@@ -354,58 +354,67 @@ macro_rules! _check_missing_tlv {
354354#[ doc( hidden) ]
355355#[ macro_export]
356356macro_rules! _decode_tlv {
357- ( $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
358- $crate:: _decode_tlv!( $reader, $field, required)
357+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
358+ $crate:: _decode_tlv!( $outer_reader , $ reader, $field, required)
359359 } } ;
360- ( $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
360+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
361361 } } ;
362- ( $reader: expr, $field: ident, required) => { {
362+ ( $outer_reader : expr , $ reader: expr, $field: ident, required) => { {
363363 $field = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
364364 } } ;
365- ( $reader: expr, $field: ident, ( required: $trait: ident $( , $read_arg: expr) ?) ) => { {
365+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( required: $trait: ident $( , $read_arg: expr) ?) ) => { {
366366 $field = $trait:: read( & mut $reader $( , $read_arg) * ) ?;
367367 } } ;
368- ( $reader: expr, $field: ident, required_vec) => { {
368+ ( $outer_reader : expr , $ reader: expr, $field: ident, required_vec) => { {
369369 let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
370370 $field = f. 0 ;
371371 } } ;
372- ( $reader: expr, $field: ident, option) => { {
372+ ( $outer_reader : expr , $ reader: expr, $field: ident, option) => { {
373373 $field = Some ( $crate:: util:: ser:: Readable :: read( & mut $reader) ?) ;
374374 } } ;
375- ( $reader: expr, $field: ident, optional_vec) => { {
375+ ( $outer_reader : expr , $ reader: expr, $field: ident, optional_vec) => { {
376376 let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
377377 $field = Some ( f. 0 ) ;
378378 } } ;
379379 // `upgradable_required` indicates we're reading a required TLV that may have been upgraded
380380 // without backwards compat. We'll error if the field is missing, and return `Ok(None)` if the
381381 // field is present but we can no longer understand it.
382382 // Note that this variant can only be used within a `MaybeReadable` read.
383- ( $reader: expr, $field: ident, upgradable_required) => { {
383+ ( $outer_reader : expr , $ reader: expr, $field: ident, upgradable_required) => { {
384384 $field = match $crate:: util:: ser:: MaybeReadable :: read( & mut $reader) ? {
385385 Some ( res) => res,
386- _ => return Ok ( None )
386+ None => {
387+ // If we successfully read a value but we don't know how to parse it, we give up
388+ // and immediately return `None`. However, we need to make sure we read the correct
389+ // number of bytes for this TLV stream, which is implicitly the end of the stream.
390+ // Thus, we consume everything left in the `$outer_reader` here, ensuring that if
391+ // we're being read as a part of another TLV stream we don't spuriously fail to
392+ // deserialize the outer object due to a TLV length mismatch.
393+ $crate:: io_extras:: copy( $outer_reader, & mut $crate:: io_extras:: sink( ) ) . unwrap( ) ;
394+ return Ok ( None )
395+ } ,
387396 } ;
388397 } } ;
389398 // `upgradable_option` indicates we're reading an Option-al TLV that may have been upgraded
390399 // without backwards compat. $field will be None if the TLV is missing or if the field is present
391400 // but we can no longer understand it.
392- ( $reader: expr, $field: ident, upgradable_option) => { {
401+ ( $outer_reader : expr , $ reader: expr, $field: ident, upgradable_option) => { {
393402 $field = $crate:: util:: ser:: MaybeReadable :: read( & mut $reader) ?;
394403 } } ;
395- ( $reader: expr, $field: ident, ( option: $trait: ident $( , $read_arg: expr) ?) ) => { {
404+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( option: $trait: ident $( , $read_arg: expr) ?) ) => { {
396405 $field = Some ( $trait:: read( & mut $reader $( , $read_arg) * ) ?) ;
397406 } } ;
398- ( $reader: expr, $field: ident, ( option, encoding: ( $fieldty: ty, $encoding: ident, $encoder: ty) ) ) => { {
399- $crate:: _decode_tlv!( $reader, $field, ( option, encoding: ( $fieldty, $encoding) ) ) ;
407+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( option, encoding: ( $fieldty: ty, $encoding: ident, $encoder: ty) ) ) => { {
408+ $crate:: _decode_tlv!( $outer_reader , $ reader, $field, ( option, encoding: ( $fieldty, $encoding) ) ) ;
400409 } } ;
401- ( $reader: expr, $field: ident, ( option, encoding: ( $fieldty: ty, $encoding: ident) ) ) => { {
410+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( option, encoding: ( $fieldty: ty, $encoding: ident) ) ) => { {
402411 $field = {
403412 let field: $encoding<$fieldty> = ser:: Readable :: read( & mut $reader) ?;
404413 Some ( field. 0 )
405414 } ;
406415 } } ;
407- ( $reader: expr, $field: ident, ( option, encoding: $fieldty: ty) ) => { {
408- $crate:: _decode_tlv!( $reader, $field, option) ;
416+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( option, encoding: $fieldty: ty) ) => { {
417+ $crate:: _decode_tlv!( $outer_reader , $ reader, $field, option) ;
409418 } } ;
410419}
411420
@@ -539,7 +548,7 @@ macro_rules! _decode_tlv_stream_range {
539548 let mut s = ser:: FixedLengthReader :: new( & mut stream_ref, length. 0 ) ;
540549 match typ. 0 {
541550 $( _t if $crate:: _decode_tlv_stream_match_check!( _t, $type, $fieldty) => {
542- $crate:: _decode_tlv!( s, $field, $fieldty) ;
551+ $crate:: _decode_tlv!( $stream , s, $field, $fieldty) ;
543552 if s. bytes_remain( ) {
544553 s. eat_remaining( ) ?; // Return ShortRead if there's actually not enough bytes
545554 return Err ( DecodeError :: InvalidValue ) ;
0 commit comments