@@ -354,58 +354,67 @@ macro_rules! _check_missing_tlv {
354
354
#[ doc( hidden) ]
355
355
#[ macro_export]
356
356
macro_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)
359
359
} } ;
360
- ( $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
360
+ ( $outer_reader : expr , $ reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
361
361
} } ;
362
- ( $reader: expr, $field: ident, required) => { {
362
+ ( $outer_reader : expr , $ reader: expr, $field: ident, required) => { {
363
363
$field = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
364
364
} } ;
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) ?) ) => { {
366
366
$field = $trait:: read( & mut $reader $( , $read_arg) * ) ?;
367
367
} } ;
368
- ( $reader: expr, $field: ident, required_vec) => { {
368
+ ( $outer_reader : expr , $ reader: expr, $field: ident, required_vec) => { {
369
369
let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
370
370
$field = f. 0 ;
371
371
} } ;
372
- ( $reader: expr, $field: ident, option) => { {
372
+ ( $outer_reader : expr , $ reader: expr, $field: ident, option) => { {
373
373
$field = Some ( $crate:: util:: ser:: Readable :: read( & mut $reader) ?) ;
374
374
} } ;
375
- ( $reader: expr, $field: ident, optional_vec) => { {
375
+ ( $outer_reader : expr , $ reader: expr, $field: ident, optional_vec) => { {
376
376
let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
377
377
$field = Some ( f. 0 ) ;
378
378
} } ;
379
379
// `upgradable_required` indicates we're reading a required TLV that may have been upgraded
380
380
// without backwards compat. We'll error if the field is missing, and return `Ok(None)` if the
381
381
// field is present but we can no longer understand it.
382
382
// 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) => { {
384
384
$field = match $crate:: util:: ser:: MaybeReadable :: read( & mut $reader) ? {
385
385
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
+ } ,
387
396
} ;
388
397
} } ;
389
398
// `upgradable_option` indicates we're reading an Option-al TLV that may have been upgraded
390
399
// without backwards compat. $field will be None if the TLV is missing or if the field is present
391
400
// but we can no longer understand it.
392
- ( $reader: expr, $field: ident, upgradable_option) => { {
401
+ ( $outer_reader : expr , $ reader: expr, $field: ident, upgradable_option) => { {
393
402
$field = $crate:: util:: ser:: MaybeReadable :: read( & mut $reader) ?;
394
403
} } ;
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) ?) ) => { {
396
405
$field = Some ( $trait:: read( & mut $reader $( , $read_arg) * ) ?) ;
397
406
} } ;
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) ) ) ;
400
409
} } ;
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) ) ) => { {
402
411
$field = {
403
412
let field: $encoding<$fieldty> = ser:: Readable :: read( & mut $reader) ?;
404
413
Some ( field. 0 )
405
414
} ;
406
415
} } ;
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) ;
409
418
} } ;
410
419
}
411
420
@@ -539,7 +548,7 @@ macro_rules! _decode_tlv_stream_range {
539
548
let mut s = ser:: FixedLengthReader :: new( & mut stream_ref, length. 0 ) ;
540
549
match typ. 0 {
541
550
$( _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) ;
543
552
if s. bytes_remain( ) {
544
553
s. eat_remaining( ) ?; // Return ShortRead if there's actually not enough bytes
545
554
return Err ( DecodeError :: InvalidValue ) ;
0 commit comments