@@ -16,13 +16,14 @@ use core::time::Duration;
16
16
use crate :: io;
17
17
use crate :: ln:: PaymentHash ;
18
18
use crate :: ln:: features:: OfferFeatures ;
19
+ use crate :: ln:: msgs:: DecodeError ;
19
20
use crate :: offers:: merkle:: { SignatureTlvStream , self } ;
20
21
use crate :: offers:: offer:: OfferTlvStream ;
21
22
use crate :: offers:: parse:: { ParseError , SemanticError } ;
22
23
use crate :: offers:: payer:: PayerTlvStream ;
23
24
use crate :: offers:: invoice_request:: { InvoiceRequestContents , InvoiceRequestTlvStream } ;
24
25
use crate :: onion_message:: BlindedPath ;
25
- use crate :: util:: ser:: { HighZeroBytesDroppedBigSize , Readable , WithoutLength , Writeable , Writer } ;
26
+ use crate :: util:: ser:: { HighZeroBytesDroppedBigSize , SeekReadable , WithoutLength , Writeable , Writer } ;
26
27
27
28
use crate :: prelude:: * ;
28
29
@@ -83,12 +84,19 @@ impl TryFrom<Vec<u8>> for Invoice {
83
84
type Error = ParseError ;
84
85
85
86
fn try_from ( bytes : Vec < u8 > ) -> Result < Self , Self :: Error > {
86
- let tlv_stream: FullInvoiceTlvStream = Readable :: read ( & mut & bytes[ ..] ) ?;
87
+ let mut cursor = io:: Cursor :: new ( bytes) ;
88
+ let tlv_stream: FullInvoiceTlvStream = SeekReadable :: read ( & mut cursor) ?;
89
+
90
+ if cursor. position ( ) < cursor. get_ref ( ) . len ( ) as u64 {
91
+ return Err ( ParseError :: Decode ( DecodeError :: InvalidValue ) ) ;
92
+ }
93
+
94
+ let bytes = cursor. into_inner ( ) ;
87
95
Invoice :: try_from ( ( bytes, tlv_stream) )
88
96
}
89
97
}
90
98
91
- tlv_stream ! ( InvoiceTlvStream , InvoiceTlvStreamRef , {
99
+ tlv_stream ! ( InvoiceTlvStream , InvoiceTlvStreamRef , 160 .. 240 , {
92
100
( 160 , paths: ( Vec <BlindedPath >, WithoutLength ) ) ,
93
101
( 162 , payinfo: ( Vec <BlindedPayInfo >, WithoutLength ) ) ,
94
102
( 164 , created_at: ( u64 , HighZeroBytesDroppedBigSize ) ) ,
@@ -136,6 +144,18 @@ type ParsedInvoice = (Vec<u8>, FullInvoiceTlvStream);
136
144
type FullInvoiceTlvStream =
137
145
( PayerTlvStream , OfferTlvStream , InvoiceRequestTlvStream , InvoiceTlvStream , SignatureTlvStream ) ;
138
146
147
+ impl SeekReadable for FullInvoiceTlvStream {
148
+ fn read < R : io:: Read + io:: Seek > ( r : & mut R ) -> Result < Self , DecodeError > {
149
+ let payer = SeekReadable :: read ( r) ?;
150
+ let offer = SeekReadable :: read ( r) ?;
151
+ let invoice_request = SeekReadable :: read ( r) ?;
152
+ let invoice = SeekReadable :: read ( r) ?;
153
+ let signature = SeekReadable :: read ( r) ?;
154
+
155
+ Ok ( ( payer, offer, invoice_request, invoice, signature) )
156
+ }
157
+ }
158
+
139
159
type PartialInvoiceTlvStream =
140
160
( PayerTlvStream , OfferTlvStream , InvoiceRequestTlvStream , InvoiceTlvStream ) ;
141
161
0 commit comments