@@ -29,6 +29,7 @@ pub struct Decoder<'input> {
2929 input : & ' input [ u8 ] ,
3030 config : DecoderOptions ,
3131 initial_len : usize ,
32+ extension_group_base : Option < Tag > ,
3233}
3334
3435impl < ' input > Decoder < ' input > {
@@ -49,6 +50,16 @@ impl<'input> Decoder<'input> {
4950 input,
5051 config,
5152 initial_len : input. len ( ) ,
53+ extension_group_base : None ,
54+ }
55+ }
56+
57+ fn translate_tag ( & self , tag : Tag ) -> Tag {
58+ match self . extension_group_base {
59+ Some ( base) if base. class == crate :: types:: Class :: Context && tag. class == base. class => {
60+ Tag :: new ( tag. class , base. value . saturating_add ( tag. value ) )
61+ }
62+ _ => tag,
5263 }
5364 }
5465
@@ -85,6 +96,9 @@ impl<'input> Decoder<'input> {
8596 {
8697 return Ok ( None ) ;
8798 }
99+
100+ let tag = self . translate_tag ( tag) ;
101+
88102 if tag != Tag :: EOC {
89103 let upcoming_tag = self . peek_tag ( ) ?;
90104 if tag != upcoming_tag {
@@ -102,13 +116,15 @@ impl<'input> Decoder<'input> {
102116 }
103117
104118 pub ( crate ) fn parse_value ( & mut self , tag : Tag ) -> Result < ( Identifier , Option < & ' input [ u8 ] > ) > {
119+ let tag = self . translate_tag ( tag) ;
105120 let ( input, ( identifier, contents) ) =
106121 self :: parser:: parse_value ( self . config , self . input , Some ( tag) ) ?;
107122 self . input = input;
108123 Ok ( ( identifier, contents) )
109124 }
110125
111126 pub ( crate ) fn parse_primitive_value ( & mut self , tag : Tag ) -> Result < ( Identifier , & ' input [ u8 ] ) > {
127+ let tag = self . translate_tag ( tag) ;
112128 let ( input, ( identifier, contents) ) =
113129 self :: parser:: parse_value ( self . config , self . input , Some ( tag) ) ?;
114130 self . input = input;
@@ -762,6 +778,37 @@ impl<'input> crate::Decoder for Decoder<'input> {
762778 default_initializer_fn : Option < DF > ,
763779 decode_fn : F ,
764780 ) -> Result < D > {
781+ if tag == Tag :: SEQUENCE {
782+ if let Some ( base) = self . extension_group_base . take ( ) {
783+ // We are decoding an extension addition group: the group tag was
784+ // already matched by `decode_extension_addition_group`, and the
785+ // group's contents are encoded "flattened" (without the SEQUENCE
786+ // wrapper). Enable tag translation for the duration of decoding
787+ // this SEQUENCE value and restore afterwards.
788+ let previous = self . extension_group_base ;
789+ self . extension_group_base = Some ( base) ;
790+
791+ let result = if D :: FIELDS . is_empty ( ) && D :: EXTENDED_FIELDS . is_none ( )
792+ || ( D :: FIELDS . len ( ) == D :: FIELDS . number_of_optional_and_default_fields ( )
793+ && self . input . is_empty ( ) )
794+ {
795+ if let Some ( default_initializer_fn) = default_initializer_fn {
796+ Ok ( ( default_initializer_fn) ( ) )
797+ } else {
798+ Err ( DecodeError :: from_kind (
799+ DecodeErrorKind :: UnexpectedEmptyInput ,
800+ self . codec ( ) ,
801+ ) )
802+ }
803+ } else {
804+ ( decode_fn) ( self )
805+ } ;
806+
807+ self . extension_group_base = previous;
808+ return result;
809+ }
810+ }
811+
765812 self . parse_constructed_contents ( tag, true , |decoder| {
766813 // If there are no fields, or the input is empty and we know that
767814 // all fields are optional or default fields, we call the default
@@ -897,9 +944,26 @@ impl<'input> crate::Decoder for Decoder<'input> {
897944 D : Decode + crate :: types:: Constructed < RL , EL > ,
898945 > (
899946 & mut self ,
900- _tag : Tag ,
947+ tag : Tag ,
901948 ) -> Result < Option < D > , Self :: Error > {
902- <Option < D > >:: decode ( self )
949+ if self . input . is_empty ( ) {
950+ return Ok ( None ) ;
951+ }
952+
953+ let ( _, identifier) = parser:: parse_identifier_octet ( self . input ) . map_err ( |e| match e {
954+ ParseNumberError :: Nom ( e) => DecodeError :: map_nom_err ( e, self . codec ( ) ) ,
955+ ParseNumberError :: Overflow => DecodeError :: integer_overflow ( 32u32 , self . codec ( ) ) ,
956+ } ) ?;
957+
958+ if identifier. tag == tag {
959+ let previous = self . extension_group_base ;
960+ self . extension_group_base = Some ( tag) ;
961+ let result = D :: decode ( self ) . map ( Some ) ;
962+ self . extension_group_base = previous;
963+ result
964+ } else {
965+ Ok ( None )
966+ }
903967 }
904968}
905969
0 commit comments