@@ -383,6 +383,35 @@ 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 which is backwards-compatible but treats 0xffff as "read eight more bytes".
390
+ struct U16Or64 ( pub u64 ) ;
391
+ impl Writeable for U16Or64 {
392
+ #[ inline]
393
+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
394
+ if self . 0 < 0xffff {
395
+ ( self . 0 as u16 ) . write ( writer)
396
+ } else {
397
+ 0xffffu16 . write ( writer) ?;
398
+ ( self . 0 - 0xfffe ) . write ( writer)
399
+ }
400
+ }
401
+ }
402
+
403
+ impl Readable for U16Or64 {
404
+ #[ inline]
405
+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
406
+ let mut val: u64 = <u16 as Readable >:: read ( r) ? as u64 ;
407
+ if val == 0xffff {
408
+ val = <u64 as Readable >:: read ( r) ?
409
+ . checked_add ( 0xfffe ) . ok_or ( DecodeError :: InvalidValue ) ?;
410
+ }
411
+ Ok ( U16Or64 ( val) )
412
+ }
413
+ }
414
+
386
415
/// In TLV we occasionally send fields which only consist of, or potentially end with, a
387
416
/// variable-length integer which is simply truncated by skipping high zero bytes. This type
388
417
/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
@@ -597,7 +626,7 @@ macro_rules! impl_for_map {
597
626
{
598
627
#[ inline]
599
628
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
600
- ( self . len( ) as u16 ) . write( w) ?;
629
+ U16Or64 ( self . len( ) as u64 ) . write( w) ?;
601
630
for ( key, value) in self . iter( ) {
602
631
key. write( w) ?;
603
632
value. write( w) ?;
@@ -611,9 +640,9 @@ macro_rules! impl_for_map {
611
640
{
612
641
#[ inline]
613
642
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 {
643
+ let len: U16Or64 = Readable :: read( r) ?;
644
+ let mut ret = $constr( len. 0 as usize ) ;
645
+ for _ in 0 ..len. 0 {
617
646
let k = K :: read( r) ?;
618
647
let v_opt = V :: read( r) ?;
619
648
if let Some ( v) = v_opt {
@@ -637,7 +666,7 @@ where T: Writeable + Eq + Hash
637
666
{
638
667
#[ inline]
639
668
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
640
- ( self . len ( ) as u16 ) . write ( w) ?;
669
+ U16Or64 ( self . len ( ) as u64 ) . write ( w) ?;
641
670
for item in self . iter ( ) {
642
671
item. write ( w) ?;
643
672
}
@@ -650,9 +679,9 @@ where T: Readable + Eq + Hash
650
679
{
651
680
#[ inline]
652
681
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 {
682
+ let len: U16Or64 = Readable :: read ( r) ?;
683
+ let mut ret = HashSet :: with_capacity ( cmp :: min ( len. 0 as usize , MAX_BUF_SIZE / core :: mem :: size_of :: < T > ( ) ) ) ;
684
+ for _ in 0 ..len. 0 {
656
685
if !ret. insert ( T :: read ( r) ?) {
657
686
return Err ( DecodeError :: InvalidValue )
658
687
}
@@ -667,7 +696,7 @@ macro_rules! impl_for_vec {
667
696
impl <$( $name : Writeable ) ,* > Writeable for Vec <$ty> {
668
697
#[ inline]
669
698
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
670
- ( self . len( ) as u16 ) . write( w) ?;
699
+ U16Or64 ( self . len( ) as u64 ) . write( w) ?;
671
700
for elem in self . iter( ) {
672
701
elem. write( w) ?;
673
702
}
@@ -678,9 +707,9 @@ macro_rules! impl_for_vec {
678
707
impl <$( $name : Readable ) ,* > Readable for Vec <$ty> {
679
708
#[ inline]
680
709
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 {
710
+ let len: U16Or64 = Readable :: read( r) ?;
711
+ let mut ret = Vec :: with_capacity( cmp:: min( len. 0 as usize , MAX_BUF_SIZE / core:: mem:: size_of:: <$ty>( ) ) ) ;
712
+ for _ in 0 ..len. 0 {
684
713
if let Some ( val) = MaybeReadable :: read( r) ? {
685
714
ret. push( val) ;
686
715
}
@@ -694,18 +723,23 @@ macro_rules! impl_for_vec {
694
723
impl Writeable for Vec < u8 > {
695
724
#[ inline]
696
725
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
697
- ( self . len ( ) as u16 ) . write ( w) ?;
726
+ U16Or64 ( self . len ( ) as u64 ) . write ( w) ?;
698
727
w. write_all ( & self )
699
728
}
700
729
}
701
730
702
731
impl Readable for Vec < u8 > {
703
732
#[ inline]
704
733
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) ?;
734
+ let mut len: U16Or64 = Readable :: read ( r) ?;
735
+ let mut ret = Vec :: new ( ) ;
736
+ while len. 0 > 0 {
737
+ let readamt = cmp:: min ( len. 0 as usize , MAX_BUF_SIZE ) ;
738
+ let readstart = ret. len ( ) ;
739
+ ret. resize ( readstart + readamt, 0 ) ;
740
+ r. read_exact ( & mut ret[ readstart..] ) ?;
741
+ len. 0 -= readamt as u64 ;
742
+ }
709
743
Ok ( ret)
710
744
}
711
745
}
@@ -1040,7 +1074,7 @@ impl Readable for () {
1040
1074
impl Writeable for String {
1041
1075
#[ inline]
1042
1076
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
1043
- ( self . len ( ) as u16 ) . write ( w) ?;
1077
+ U16Or64 ( self . len ( ) as u64 ) . write ( w) ?;
1044
1078
w. write_all ( self . as_bytes ( ) )
1045
1079
}
1046
1080
}
0 commit comments