Skip to content

der: auto read_nested in trait: DecodeValue::decode_value_nested #1916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion der/src/asn1/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ mod allocating {

fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self, Error> {
let header = Header::decode(reader)?;
read_value(reader, header, Self::decode_value)
read_value(reader, header, Self::decode_value_nested)
}
}

Expand Down
18 changes: 13 additions & 5 deletions der/src/asn1/internal_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ macro_rules! impl_custom_class {
Ok(Some(Self::decode(reader)?))
}

/// Decode inner tag-length-value of `EXPLICIT` field.
fn decode_explicit_inner<'a, R: Reader<'a>>(
reader: &mut R,
header: Header
) -> Result<T, T::Error>
where
T: Decode<'a>
{
reader.read_nested(header.length, |r| T::decode(r))
}

#[doc = concat!("Attempt to decode an `IMPLICIT` ASN.1 `", $asn1_class_name, "` field with the")]
/// provided [`TagNumber`].
///
Expand Down Expand Up @@ -152,7 +163,7 @@ macro_rules! impl_custom_class {
}

// read_value checks if header matches decoded length
let value = crate::reader::read_value(reader, header, T::decode_value)?;
let value = crate::reader::read_value(reader, header, T::decode_value_nested)?;

Ok(Some(Self {
tag_number,
Expand Down Expand Up @@ -189,10 +200,7 @@ macro_rules! impl_custom_class {
Tag::$class_enum_name { number, .. } => Ok(Self {
tag_number: number,
tag_mode: TagMode::default(),
value: crate::reader::read_value(reader, header, |reader, _| {
// Decode inner tag-length-value of EXPLICIT
T::decode(reader)
})?,
value: crate::reader::read_value(reader, header, Self::decode_explicit_inner)?,
}),
tag => Err(reader.error(tag.unexpected_error(None)).into())
}
Expand Down
12 changes: 11 additions & 1 deletion der/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ where
fn decode<R: Reader<'a>>(reader: &mut R) -> Result<T, <T as DecodeValue<'a>>::Error> {
let header = Header::decode(reader)?;
header.tag.assert_eq(T::TAG)?;
read_value(reader, header, T::decode_value)
read_value(reader, header, T::decode_value_nested)
}
}

Expand Down Expand Up @@ -130,6 +130,16 @@ pub trait DecodeValue<'a>: Sized {

/// Attempt to decode this message using the provided [`Reader`].
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error>;

/// Attempt to decode this message using the nested [`Reader`], using [`Reader::read_nested`] wrapper.
///
/// For primitive types, this function can be overridden to [`DecodeValue::decode_value`] directly.
fn decode_value_nested<R: Reader<'a>>(
reader: &mut R,
header: Header,
) -> Result<Self, Self::Error> {
reader.read_nested(header.length, |r| Self::decode_value(r, header))
}
}

#[cfg(feature = "alloc")]
Expand Down
4 changes: 2 additions & 2 deletions der/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub trait Reader<'r>: Clone {
{
let header = Header::decode(self)?;
header.tag.assert_eq(Tag::Sequence)?;
read_value(self, header, |r, _| f(r))
read_value(self, header, |r, h| r.read_nested(h.length, |r| f(r)))
}

/// Obtain a slice of bytes containing a complete TLV production suitable for parsing later.
Expand All @@ -214,7 +214,7 @@ where
F: FnOnce(&mut R, Header) -> Result<T, E>,
{
header.length = header.length.sans_eoc();
let ret = reader.read_nested(header.length, |r| f(r, header))?;
let ret = f(reader, header)?;

// Consume EOC marker if the length is indefinite.
if header.length.is_indefinite() {
Expand Down