Skip to content

Commit 3644522

Browse files
committed
der: simplify Header::peek and Tag::peek
We can rely on the ability to clone the `Reader` to use the `Decode` implementation to implement peeking, so we don't need a separate bespoke implementation. This also avoids losing the `Reader` context while peeking.
1 parent 65b5d4c commit 3644522

File tree

2 files changed

+8
-39
lines changed

2 files changed

+8
-39
lines changed

der/src/header.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ pub struct Header {
1414
}
1515

1616
impl Header {
17-
/// Maximum number of DER octets a header can be in this crate.
18-
pub(crate) const MAX_SIZE: usize = Tag::MAX_SIZE + Length::MAX_SIZE;
19-
2017
/// Create a new [`Header`] from a [`Tag`] and a specified length.
2118
///
2219
/// Returns an error if the length exceeds the limits of [`Length`].
@@ -29,17 +26,7 @@ impl Header {
2926
///
3027
/// Does not modify the reader's state.
3128
pub fn peek<'a>(reader: &impl Reader<'a>) -> Result<Self> {
32-
let mut buf = [0u8; Self::MAX_SIZE];
33-
34-
for i in 2..Self::MAX_SIZE {
35-
let slice = &mut buf[0..i];
36-
reader.peek_into(slice)?;
37-
if let Ok(header) = Self::from_der(slice) {
38-
return Ok(header);
39-
}
40-
}
41-
reader.peek_into(&mut buf[..])?;
42-
Self::from_der(&buf[..])
29+
Header::decode(&mut reader.clone())
4330
}
4431
}
4532

der/src/tag.rs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -166,29 +166,15 @@ impl Tag {
166166
///
167167
/// Does not modify the reader's state.
168168
pub fn peek<'a>(reader: &impl Reader<'a>) -> Result<Self> {
169-
Self::peek_optional(reader)?.ok_or_else(|| Error::incomplete(reader.input_len()))
169+
Self::decode(&mut reader.clone())
170170
}
171171

172172
pub(crate) fn peek_optional<'a>(reader: &impl Reader<'a>) -> Result<Option<Self>> {
173-
let mut buf = [0u8; Self::MAX_SIZE];
174-
if reader.peek_into(&mut buf[0..1]).is_err() {
175-
// Ignore empty buffer
173+
if reader.is_finished() {
176174
return Ok(None);
177175
}
178176

179-
if let Ok(tag) = Self::from_der(&buf[0..1]) {
180-
return Ok(Some(tag));
181-
}
182-
183-
for i in 2..=Self::MAX_SIZE {
184-
let slice = &mut buf[0..i];
185-
reader.peek_into(slice)?;
186-
187-
if let Ok(tag) = Self::from_der(slice) {
188-
return Ok(Some(tag));
189-
}
190-
}
191-
Err(ErrorKind::TagNumberInvalid.into())
177+
Self::peek(reader).map(Some)
192178
}
193179

194180
/// Returns true if given context-specific (or any given class) tag number matches the peeked tag.
@@ -197,16 +183,12 @@ impl Tag {
197183
expected_class: Class,
198184
expected_tag_number: TagNumber,
199185
) -> Result<bool> {
200-
// Peek tag or ignore end of stream
201-
let Some(tag) = Tag::peek_optional(reader)? else {
202-
return Ok(false);
203-
};
204-
// Ignore tags with different numbers
205-
if tag.class() != expected_class || tag.number() != expected_tag_number {
186+
if reader.is_finished() {
206187
return Ok(false);
207188
}
208-
// Tag matches
209-
Ok(true)
189+
190+
let tag = Self::peek(reader)?;
191+
Ok(tag.class() == expected_class && tag.number() == expected_tag_number)
210192
}
211193

212194
/// Assert that this [`Tag`] matches the provided expected tag.

0 commit comments

Comments
 (0)