@@ -43,7 +43,20 @@ mod sealed {
43
43
// Offer encoding may be split by '+' followed by optional whitespace.
44
44
let encoded = match s. split ( '+' ) . skip ( 1 ) . next ( ) {
45
45
Some ( _) => {
46
- for chunk in s. split ( '+' ) {
46
+ let mut chunks = s. split ( '+' ) ;
47
+
48
+ // Check first chunk without trimming
49
+ if let Some ( first_chunk) = chunks. next ( ) {
50
+ if first_chunk. contains ( char:: is_whitespace) {
51
+ return Err ( Bolt12ParseError :: InvalidLeadingWhitespace ) ;
52
+ }
53
+ if first_chunk. is_empty ( ) {
54
+ return Err ( Bolt12ParseError :: InvalidContinuation ) ;
55
+ }
56
+ }
57
+
58
+ // Check remaining chunks
59
+ for chunk in chunks {
47
60
let chunk = chunk. trim_start ( ) ;
48
61
if chunk. is_empty ( ) || chunk. contains ( char:: is_whitespace) {
49
62
return Err ( Bolt12ParseError :: InvalidContinuation ) ;
@@ -123,6 +136,8 @@ pub enum Bolt12ParseError {
123
136
/// The bech32 encoding does not conform to the BOLT 12 requirements for continuing messages
124
137
/// across multiple parts (i.e., '+' followed by whitespace).
125
138
InvalidContinuation ,
139
+ /// The bech32 string starts with whitespace, which violates BOLT 12 encoding requirements.
140
+ InvalidLeadingWhitespace ,
126
141
/// The bech32 encoding's human-readable part does not match what was expected for the message
127
142
/// being parsed.
128
143
InvalidBech32Hrp ,
@@ -322,6 +337,15 @@ mod tests {
322
337
}
323
338
}
324
339
340
+ #[ test]
341
+ fn fails_parsing_bech32_encoded_offer_with_leading_whitespace ( ) {
342
+ let encoded_offer = "\u{b} lno1pqpzwyq2p32x2um5ypmx2cm5dae8x93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah+\u{b} \u{b} \u{b} \u{b} 82ru5rdpnpj" ;
343
+ match encoded_offer. parse :: < Offer > ( ) {
344
+ Ok ( _) => panic ! ( "Valid offer: {}" , encoded_offer) ,
345
+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: InvalidLeadingWhitespace ) ,
346
+ }
347
+ }
348
+
325
349
#[ test]
326
350
fn fails_parsing_bech32_encoded_offer_with_invalid_bech32_data ( ) {
327
351
let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxo" ;
0 commit comments