@@ -64,15 +64,21 @@ static const char *pull_bits(struct hash_u5 *hu5,
6464
6565/* Helper for pulling a variable-length big-endian int. */
6666static const char * pull_uint (struct hash_u5 * hu5 ,
67- const u5 * * data , size_t * data_len ,
68- u64 * val , size_t databits )
67+ const u5 * * data , size_t * data_len ,
68+ u64 * val , size_t databits ,
69+ bool must_be_minimal )
6970{
7071 be64 be_val ;
7172 const char * err ;
7273
7374 /* Too big. */
7475 if (databits > sizeof (be_val ) * CHAR_BIT )
7576 return "integer too large" ;
77+ if (must_be_minimal
78+ && databits >= 5
79+ && * data_len > 1
80+ && (* data )[0 ] == 0 )
81+ return "not a minimal value" ;
7682 err = pull_bits (hu5 , data , data_len , & be_val , databits , true);
7783 if (err )
7884 return err ;
@@ -262,8 +268,12 @@ static const char *decode_x(struct bolt11 *b11,
262268
263269 assert (!* have_x );
264270
265- /* FIXME: Put upper limit in bolt 11 */
266- err = pull_uint (hu5 , data , field_len , & b11 -> expiry , * field_len * 5 );
271+ /* BOLT #11:
272+ * - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
273+ * (i.e. begins with 0 field elements):
274+ * - SHOULD treat the invoice as invalid.
275+ */
276+ err = pull_uint (hu5 , data , field_len , & b11 -> expiry , * field_len * 5 , true);
267277 if (err )
268278 return tal_fmt (b11 , "x: %s" , err );
269279
@@ -287,8 +297,12 @@ static const char *decode_c(struct bolt11 *b11,
287297
288298 assert (!* have_c );
289299
290- /* FIXME: Put upper limit in bolt 11 */
291- err = pull_uint (hu5 , data , field_len , & c , * field_len * 5 );
300+ /* BOLT #11:
301+ * - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
302+ * (i.e. begins with 0 field elements):
303+ * - SHOULD treat the invoice as invalid.
304+ */
305+ err = pull_uint (hu5 , data , field_len , & c , * field_len * 5 , true);
292306 if (err )
293307 return tal_fmt (b11 , "c: %s" , err );
294308 b11 -> min_final_cltv_expiry = c ;
@@ -375,7 +389,7 @@ static const char *decode_f(struct bolt11 *b11,
375389 size_t orig_len = * field_len ;
376390 const char * err ;
377391
378- err = pull_uint (hu5 , data , field_len , & version , 5 );
392+ err = pull_uint (hu5 , data , field_len , & version , 5 , false );
379393 if (err )
380394 return tal_fmt (b11 , "f: %s" , err );
381395
@@ -550,6 +564,14 @@ static const char *decode_9(struct bolt11 *b11,
550564 if (!b11 -> features )
551565 return err ;
552566
567+ /* BOLT #11:
568+ * - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
569+ * (i.e. begins with 0 field elements):
570+ * - SHOULD treat the invoice as invalid.
571+ */
572+ if (tal_count (b11 -> features ) > 0 && b11 -> features [0 ] == 0 )
573+ return tal_fmt (b11 , "9: non-minimal length (begins with 0)" );
574+
553575 /* pull_bits pads with zero bits: we need to remove them. */
554576 shift_bitmap_down (b11 -> features ,
555577 flen * 8 - databits );
@@ -847,7 +869,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
847869 * 1. zero or more tagged parts
848870 * 1. `signature`: Bitcoin-style signature of above (520 bits)
849871 */
850- err = pull_uint (& hu5 , & data , & data_len , & b11 -> timestamp , 35 );
872+ err = pull_uint (& hu5 , & data , & data_len , & b11 -> timestamp , 35 , false );
851873 if (err )
852874 return decode_fail (b11 , fail ,
853875 "Can't get 35-bit timestamp: %s" , err );
@@ -866,11 +888,11 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
866888 * 1. `data_length` (10 bits, big-endian)
867889 * 1. `data` (`data_length` x 5 bits)
868890 */
869- err = pull_uint (& hu5 , & data , & data_len , & type , 5 );
891+ err = pull_uint (& hu5 , & data , & data_len , & type , 5 , false );
870892 if (err )
871893 return decode_fail (b11 , fail ,
872894 "Can't get tag: %s" , err );
873- err = pull_uint (& hu5 , & data , & data_len , & field_len64 , 10 );
895+ err = pull_uint (& hu5 , & data , & data_len , & field_len64 , 10 , false );
874896 if (err )
875897 return decode_fail (b11 , fail ,
876898 "Can't get length: %s" , err );
@@ -1053,10 +1075,11 @@ static void push_field(u5 **data, char type, const void *src, size_t nbits)
10531075/* BOLT #11:
10541076 *
10551077 * - if `x` is included:
1056- * - SHOULD use the minimum `data_length` possible.
1078+ * - MUST use the minimum `data_length` possible, i.e. no leading 0 field-elements .
10571079 * - SHOULD include one `c` field (`min_final_cltv_expiry_delta`).
1058- *...
1059- * - SHOULD use the minimum `data_length` possible.
1080+ * - MUST set `c` to the minimum `cltv_expiry` it will accept for the last
1081+ * HTLC in the route.
1082+ * - MUST use the minimum `data_length` possible, i.e. no leading 0 field-elements.
10601083 */
10611084static void push_varlen_field (u5 * * data , char type , u64 val )
10621085{
@@ -1197,7 +1220,8 @@ static void maybe_encode_9(u5 **data, const u8 *features,
11971220 /* BOLT #11:
11981221 *
11991222 * - if `9` contains non-zero bits:
1200- * - SHOULD use the minimum `data_length` possible.
1223+ * - MUST use the minimum `data_length` possible to encode the non-zero bits
1224+ * with no 0 field-elements at the start.
12011225 * - otherwise:
12021226 * - MUST omit the `9` field altogether.
12031227 */
0 commit comments