@@ -383,6 +383,40 @@ impl Readable for BigSize {
383
383
}
384
384
}
385
385
386
+ /// The lightning protocol uses u16s for lengths in most cases. As our serialization framework
387
+ /// primarily targets that, we must as well. However, because we may serialize objects that have
388
+ /// more than 65K entries, we need to be able to store larger values. Thus, we define a variable
389
+ /// length integer here that is backwards-compatible for values < 0xffff. We treat 0xffff as
390
+ /// "read eight more bytes".
391
+ ///
392
+ /// To ensure we only have one valid encoding per value, we add 0xffff to values written as eight
393
+ /// bytes. Thus, 0xfffe is serialized as 0xfffe, whereas 0xffff is serialized as
394
+ /// 0xffff0000000000000000 (i.e. read-eight-bytes then zero).
395
+ struct CollectionLength ( pub u64 ) ;
396
+ impl Writeable for CollectionLength {
397
+ #[ inline]
398
+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
399
+ if self . 0 < 0xffff {
400
+ ( self . 0 as u16 ) . write ( writer)
401
+ } else {
402
+ 0xffffu16 . write ( writer) ?;
403
+ ( self . 0 - 0xffff ) . write ( writer)
404
+ }
405
+ }
406
+ }
407
+
408
+ impl Readable for CollectionLength {
409
+ #[ inline]
410
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
411
+ let mut val: u64 = <u16 as Readable >:: read ( r) ? as u64 ;
412
+ if val == 0xffff {
413
+ val = <u64 as Readable >:: read ( r) ?
414
+ . checked_add ( 0xffff ) . ok_or ( DecodeError :: InvalidValue ) ?;
415
+ }
416
+ Ok ( CollectionLength ( val) )
417
+ }
418
+ }
419
+
386
420
/// In TLV we occasionally send fields which only consist of, or potentially end with, a
387
421
/// variable-length integer which is simply truncated by skipping high zero bytes. This type
388
422
/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
@@ -597,7 +631,7 @@ macro_rules! impl_for_map {
597
631
{
598
632
#[ inline]
599
633
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
600
- ( self . len( ) as u16 ) . write( w) ?;
634
+ CollectionLength ( self . len( ) as u64 ) . write( w) ?;
601
635
for ( key, value) in self . iter( ) {
602
636
key. write( w) ?;
603
637
value. write( w) ?;
@@ -611,9 +645,9 @@ macro_rules! impl_for_map {
611
645
{
612
646
#[ inline]
613
647
fn read<R : Read >( r: & mut R ) -> Result <Self , DecodeError > {
614
- let len: u16 = Readable :: read( r) ?;
615
- let mut ret = $constr( len as usize ) ;
616
- for _ in 0 ..len {
648
+ let len: CollectionLength = Readable :: read( r) ?;
649
+ let mut ret = $constr( len. 0 as usize ) ;
650
+ for _ in 0 ..len. 0 {
617
651
let k = K :: read( r) ?;
618
652
let v_opt = V :: read( r) ?;
619
653
if let Some ( v) = v_opt {
@@ -637,7 +671,7 @@ where T: Writeable + Eq + Hash
637
671
{
638
672
#[ inline]
639
673
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
640
- ( self . len ( ) as u16 ) . write ( w) ?;
674
+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
641
675
for item in self . iter ( ) {
642
676
item. write ( w) ?;
643
677
}
@@ -650,9 +684,9 @@ where T: Readable + Eq + Hash
650
684
{
651
685
#[ inline]
652
686
fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
653
- let len: u16 = Readable :: read ( r) ?;
654
- let mut ret = HashSet :: with_capacity ( len as usize ) ;
655
- for _ in 0 ..len {
687
+ let len: CollectionLength = Readable :: read ( r) ?;
688
+ let mut ret = HashSet :: with_capacity ( cmp :: min ( len. 0 as usize , MAX_BUF_SIZE / core :: mem :: size_of :: < T > ( ) ) ) ;
689
+ for _ in 0 ..len. 0 {
656
690
if !ret. insert ( T :: read ( r) ?) {
657
691
return Err ( DecodeError :: InvalidValue )
658
692
}
@@ -667,7 +701,7 @@ macro_rules! impl_for_vec {
667
701
impl <$( $name : Writeable ) ,* > Writeable for Vec <$ty> {
668
702
#[ inline]
669
703
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
670
- ( self . len( ) as u16 ) . write( w) ?;
704
+ CollectionLength ( self . len( ) as u64 ) . write( w) ?;
671
705
for elem in self . iter( ) {
672
706
elem. write( w) ?;
673
707
}
@@ -678,9 +712,9 @@ macro_rules! impl_for_vec {
678
712
impl <$( $name : Readable ) ,* > Readable for Vec <$ty> {
679
713
#[ inline]
680
714
fn read<R : Read >( r: & mut R ) -> Result <Self , DecodeError > {
681
- let len: u16 = Readable :: read( r) ?;
682
- let mut ret = Vec :: with_capacity( cmp:: min( len as usize , MAX_BUF_SIZE / core:: mem:: size_of:: <$ty>( ) ) ) ;
683
- for _ in 0 ..len {
715
+ let len: CollectionLength = Readable :: read( r) ?;
716
+ let mut ret = Vec :: with_capacity( cmp:: min( len. 0 as usize , MAX_BUF_SIZE / core:: mem:: size_of:: <$ty>( ) ) ) ;
717
+ for _ in 0 ..len. 0 {
684
718
if let Some ( val) = MaybeReadable :: read( r) ? {
685
719
ret. push( val) ;
686
720
}
@@ -694,18 +728,23 @@ macro_rules! impl_for_vec {
694
728
impl Writeable for Vec < u8 > {
695
729
#[ inline]
696
730
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
697
- ( self . len ( ) as u16 ) . write ( w) ?;
731
+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
698
732
w. write_all ( & self )
699
733
}
700
734
}
701
735
702
736
impl Readable for Vec < u8 > {
703
737
#[ inline]
704
738
fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
705
- let len: u16 = Readable :: read ( r) ?;
706
- let mut ret = Vec :: with_capacity ( len as usize ) ;
707
- ret. resize ( len as usize , 0 ) ;
708
- r. read_exact ( & mut ret) ?;
739
+ let mut len: CollectionLength = Readable :: read ( r) ?;
740
+ let mut ret = Vec :: new ( ) ;
741
+ while len. 0 > 0 {
742
+ let readamt = cmp:: min ( len. 0 as usize , MAX_BUF_SIZE ) ;
743
+ let readstart = ret. len ( ) ;
744
+ ret. resize ( readstart + readamt, 0 ) ;
745
+ r. read_exact ( & mut ret[ readstart..] ) ?;
746
+ len. 0 -= readamt as u64 ;
747
+ }
709
748
Ok ( ret)
710
749
}
711
750
}
@@ -1040,7 +1079,7 @@ impl Readable for () {
1040
1079
impl Writeable for String {
1041
1080
#[ inline]
1042
1081
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
1043
- ( self . len ( ) as u16 ) . write ( w) ?;
1082
+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
1044
1083
w. write_all ( self . as_bytes ( ) )
1045
1084
}
1046
1085
}
0 commit comments