Skip to content

Commit b8893a1

Browse files
committed
WIP: Limit TLV stream decoding to type ranges
1 parent 062dd30 commit b8893a1

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

lightning/src/offers/invoice.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ use core::time::Duration;
1616
use io;
1717
use ln::PaymentHash;
1818
use ln::features::OfferFeatures;
19+
use ln::msgs::DecodeError;
1920
use offers::merkle::{SignatureTlvStream, self};
2021
use offers::offer::OfferTlvStream;
2122
use offers::parse::{ParseError, SemanticError};
2223
use offers::payer::PayerTlvStream;
2324
use offers::invoice_request::{InvoiceRequestContents, InvoiceRequestTlvStream};
2425
use onion_message::BlindedPath;
25-
use util::ser::{HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};
26+
use util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
2627

2728
use prelude::*;
2829

@@ -83,12 +84,19 @@ impl TryFrom<Vec<u8>> for Invoice {
8384
type Error = ParseError;
8485

8586
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();
8795
Invoice::try_from((bytes, tlv_stream))
8896
}
8997
}
9098

91-
tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, {
99+
tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
92100
(160, paths: (Vec<BlindedPath>, WithoutLength)),
93101
(162, payinfo: (Vec<BlindedPayInfo>, WithoutLength)),
94102
(164, created_at: (u64, HighZeroBytesDroppedBigSize)),
@@ -136,6 +144,18 @@ type ParsedInvoice = (Vec<u8>, FullInvoiceTlvStream);
136144
type FullInvoiceTlvStream =
137145
(PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream, SignatureTlvStream);
138146

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+
139159
type PartialInvoiceTlvStream =
140160
(PayerTlvStream, OfferTlvStream, InvoiceRequestTlvStream, InvoiceTlvStream);
141161

0 commit comments

Comments
 (0)