Skip to content

Commit

Permalink
fix: cargo test -p der now pass
Browse files Browse the repository at this point in the history
  • Loading branch information
dishmaker committed Oct 6, 2024
1 parent dc2e67f commit 05e0133
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
4 changes: 2 additions & 2 deletions der/src/asn1/context_specific.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn decode_implicit<'a, R: Reader<'a>, T: Tagged + DecodeValue<'a>>(
number: TagNumber,
reader: &mut R,
) -> Result<Option<T>, T::Error> {
match AnyCustomClassImplicit::decode_implicit(Class::ContextSpecific, number, reader) {
match AnyCustomClassImplicit::decode_skipping(Class::ContextSpecific, number, reader) {
Ok(Some(custom)) => Ok(Some(custom.value)),
Ok(None) => Ok(None),
Err(err) => Err(err),
Expand All @@ -33,7 +33,7 @@ pub fn decode_explicit<'a, R: Reader<'a>, T: Decode<'a>>(
number: TagNumber,
reader: &mut R,
) -> Result<Option<T>, T::Error> {
match AnyCustomClassExplicit::decode_explicit(Class::ContextSpecific, number, reader) {
match AnyCustomClassExplicit::decode_skipping(Class::ContextSpecific, number, reader) {
Ok(Some(custom)) => Ok(Some(custom.value)),
Ok(None) => Ok(None),
Err(err) => Err(err),
Expand Down
55 changes: 33 additions & 22 deletions der/src/asn1/custom_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<T, const TAG: u16, const CLASS: u8> CustomClass<T, TAG, CLASS> {
where
T: Decode<'a>,
{
match AnyCustomClassExplicit::decode_explicit(Class::from(CLASS), TagNumber(TAG), reader) {
match AnyCustomClassExplicit::decode_skipping(Class::from(CLASS), TagNumber(TAG), reader) {
Ok(Some(custom)) => Ok(Some(Self {
value: custom.value,
})),
Expand All @@ -70,21 +70,21 @@ fn is_unskippable_tag(tag: Tag, expected_class: Class, expected_number: TagNumbe

/// Attempt to decode a custom class-tagged field with the given
/// helper callback.
fn decode_with<'a, F, R: Reader<'a>, E, T>(
fn decode_peeking<'a, F, R: Reader<'a>, E, T>(
reader: &mut R,
expected_class: Class,
expected_number: TagNumber,
f: F,
) -> Result<Option<T>, E>
where
F: FnOnce(Tag, &mut R) -> Result<T, E>,
F: FnOnce(&mut R) -> Result<T, E>,
E: From<Error>,
{
while let Some(tag) = Tag::peek_optional(reader)? {
if is_unskippable_tag(tag, expected_class, expected_number) {
break;
} else if tag.number() == expected_number {
return Some(f(tag, reader)).transpose();
return Some(f(reader)).transpose();
} else {
AnyRef::decode(reader)?;
}
Expand All @@ -104,7 +104,7 @@ impl<T, const TAG: u16, const CLASS: u8> CustomClassImplicit<T, TAG, CLASS> {
where
T: DecodeValue<'a> + Tagged,
{
match AnyCustomClassImplicit::decode_implicit(Class::from(CLASS), TagNumber(TAG), reader) {
match AnyCustomClassImplicit::decode_skipping(Class::from(CLASS), TagNumber(TAG), reader) {
Ok(Some(custom)) => Ok(Some(Self {
value: custom.value,
})),
Expand All @@ -130,31 +130,46 @@ impl<'a, T> AnyCustomClassExplicit<T>
where
T: Decode<'a>,
{
pub fn decode_explicit<R: Reader<'a>>(
pub fn decode_skipping<R: Reader<'a>>(
class: Class,
number: TagNumber,
reader: &mut R,
) -> Result<Option<Self>, T::Error> {
decode_with(reader, class, number, |tag, reader| {
decode_peeking(reader, class, number, |reader| {
Self::decode(class, number, reader)
})
}

pub fn decode<R: Reader<'a>>(
class: Class,
number: TagNumber,
reader: &mut R,
) -> Result<Self, T::Error> {
let header = Header::decode(reader)?;

if header.tag.class() == class {
Ok(Self {
value: T::decode(reader)?,
tag_number: tag.number(),
constructed: tag.is_constructed(),
value: reader.read_nested(header.length, |reader| T::decode(reader))?,
tag_number: header.tag.number(),
constructed: header.tag.is_constructed(),
})
})
} else {
let expected = expected_tag_constructed(class, number, true);
Err(header.tag.unexpected_error(Some(expected)).into())
}
}
}

impl<'a, T> AnyCustomClassImplicit<T>
where
T: Tagged + DecodeValue<'a>,
{
pub fn decode_implicit<R: Reader<'a>>(
pub fn decode_skipping<R: Reader<'a>>(
class: Class,
number: TagNumber,
reader: &mut R,
) -> Result<Option<Self>, T::Error> {
decode_with::<_, _, T::Error, _>(reader, class, number, |_tag, reader| {
decode_peeking::<_, _, T::Error, _>(reader, class, number, |reader| {
let header = Header::decode(reader)?;
let value = T::decode_value(reader, header)?;

Expand Down Expand Up @@ -198,15 +213,11 @@ where
type Error = T::Error;

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

if header.tag.class() == Class::from(CLASS) {
Ok(Self {
value: reader.read_nested(header.length, |reader| T::decode(reader))?,
})
} else {
let expected = expected_tag_constructed(Class::from(CLASS), TagNumber(TAG), true);
Err(header.tag.unexpected_error(Some(expected)).into())
match AnyCustomClassExplicit::<T>::decode(Class::from(CLASS), TagNumber(TAG), reader) {
Ok(custom) => Ok(Self {
value: custom.value,
}),
Err(err) => Err(err),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions der/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ pub trait Reader<'r>: Sized {
T: DecodeValue<'r> + FixedTag + 'r,
{
Ok(match tag_mode {
TagMode::Explicit => AnyCustomClassExplicit::<T>::decode_explicit(
TagMode::Explicit => AnyCustomClassExplicit::<T>::decode_skipping(
Class::ContextSpecific,
tag_number,
self,
)?
.map(|field| field.value),
TagMode::Implicit => AnyCustomClassImplicit::<T>::decode_implicit(
TagMode::Implicit => AnyCustomClassImplicit::<T>::decode_skipping(
Class::ContextSpecific,
tag_number,
self,
Expand Down

0 comments on commit 05e0133

Please sign in to comment.