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