mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
tests: add test for tlvstream (from BOLT 1 test vectors).
https://github.com/lightningnetwork/lightning-rfc/pull/631 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7cf0006c78
commit
3477034657
@ -15,6 +15,10 @@
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/utils.h>
|
||||
|
||||
#ifndef SUPERVERBOSE
|
||||
#define SUPERVERBOSE(...)
|
||||
#endif
|
||||
|
||||
/* Sets *cursor to NULL and returns NULL when extraction fails. */
|
||||
const void *fromwire_fail(const u8 **cursor, size_t *max)
|
||||
{
|
||||
@ -31,6 +35,8 @@ const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n)
|
||||
/* Just make sure we don't leak uninitialized mem! */
|
||||
if (copy)
|
||||
memset(copy, 0, n);
|
||||
if (*cursor)
|
||||
SUPERVERBOSE("less than encoding length");
|
||||
return fromwire_fail(cursor, max);
|
||||
}
|
||||
*cursor += n;
|
||||
@ -103,6 +109,7 @@ static u64 fromwire_tlv_uint(const u8 **cursor, size_t *max, size_t maxlen)
|
||||
*/
|
||||
length = *max;
|
||||
if (length > maxlen) {
|
||||
SUPERVERBOSE("greater than encoding length");
|
||||
fromwire_fail(cursor, max);
|
||||
return 0;
|
||||
}
|
||||
@ -116,6 +123,7 @@ static u64 fromwire_tlv_uint(const u8 **cursor, size_t *max, size_t maxlen)
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (length > 0 && bytes[sizeof(bytes) - length] == 0) {
|
||||
SUPERVERBOSE("not minimal");
|
||||
fromwire_fail(cursor, max);
|
||||
return 0;
|
||||
}
|
||||
@ -163,18 +171,24 @@ u64 fromwire_bigsize(const u8 **cursor, size_t *max)
|
||||
switch(flag) {
|
||||
case 0xff:
|
||||
ret = fromwire_u64(cursor, max);
|
||||
if ((ret >> 32) == 0)
|
||||
if ((ret >> 32) == 0) {
|
||||
SUPERVERBOSE("not minimal encoded");
|
||||
fromwire_fail(cursor, max);
|
||||
}
|
||||
break;
|
||||
case 0xfe:
|
||||
ret = fromwire_u32(cursor, max);
|
||||
if ((ret >> 16) == 0)
|
||||
if ((ret >> 16) == 0) {
|
||||
SUPERVERBOSE("not minimal encoded");
|
||||
fromwire_fail(cursor, max);
|
||||
}
|
||||
break;
|
||||
case 0xfd:
|
||||
ret = fromwire_u16(cursor, max);
|
||||
if (ret < 0xfd)
|
||||
if (ret < 0xfd) {
|
||||
SUPERVERBOSE("not minimal encoded");
|
||||
fromwire_fail(cursor, max);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = flag;
|
||||
@ -189,8 +203,10 @@ void fromwire_pubkey(const u8 **cursor, size_t *max, struct pubkey *pubkey)
|
||||
if (!fromwire(cursor, max, der, sizeof(der)))
|
||||
return;
|
||||
|
||||
if (!pubkey_from_der(der, sizeof(der), pubkey))
|
||||
if (!pubkey_from_der(der, sizeof(der), pubkey)) {
|
||||
SUPERVERBOSE("not a valid point");
|
||||
fromwire_fail(cursor, max);
|
||||
}
|
||||
}
|
||||
|
||||
void fromwire_node_id(const u8 **cursor, size_t *max, struct node_id *id)
|
||||
|
854
wire/test/run-tlvstream.c
Normal file
854
wire/test/run-tlvstream.c
Normal file
@ -0,0 +1,854 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <common/utils.h>
|
||||
#include <wally_core.h>
|
||||
|
||||
static const char *reason;
|
||||
#define SUPERVERBOSE(r) do { reason = (r); } while(0)
|
||||
|
||||
#include <wire/tlvstream.c>
|
||||
#include <wire/fromwire.c>
|
||||
#include <wire/towire.c>
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
/* AUTOGENERATED MOCKS END */
|
||||
|
||||
/* FIXME: Autogenerate these! */
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* 1. tlvs: `n1`
|
||||
* 2. types:
|
||||
* 1. type: 1 (`tlv1`)
|
||||
* 2. data:
|
||||
* * [`tu64`:`amount_msat`]
|
||||
* 1. type: 2 (`tlv2`)
|
||||
* 2. data:
|
||||
* * [`short_channel_id`:`scid`]
|
||||
* 1. type: 3 (`tlv3`)
|
||||
* 2. data:
|
||||
* * [`point`:`node_id`]
|
||||
* * [`u64`:`amount_msat_1`]
|
||||
* * [`u64`:`amount_msat_2`]
|
||||
* 1. type: 254 (`tlv4`)
|
||||
* 2. data:
|
||||
* * [`u16`:`cltv_delta`]
|
||||
*/
|
||||
struct tlv_n1_tlv1 {
|
||||
u64 amount_msat;
|
||||
};
|
||||
|
||||
struct tlv_n1_tlv2 {
|
||||
struct short_channel_id scid;
|
||||
};
|
||||
|
||||
struct tlv_n1_tlv3 {
|
||||
struct pubkey node_id;
|
||||
u64 amount_msat_1;
|
||||
u64 amount_msat_2;
|
||||
};
|
||||
|
||||
struct tlv_n1_tlv4 {
|
||||
u16 cltv_delta;
|
||||
};
|
||||
|
||||
struct tlv_n1 {
|
||||
struct tlv_n1_tlv1 *tlv1;
|
||||
struct tlv_n1_tlv2 *tlv2;
|
||||
struct tlv_n1_tlv3 *tlv3;
|
||||
struct tlv_n1_tlv4 *tlv4;
|
||||
};
|
||||
|
||||
static struct tlv_n1 *tlv_n1_new(const tal_t *ctx)
|
||||
{
|
||||
/* Initialize everything to NULL. (Quiet, C pedants!) */
|
||||
return talz(ctx, struct tlv_n1);
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n1_tlv1(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n1 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv1)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_tu64(&ptr, r->tlv1->amount_msat);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n1_tlv2(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n1 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv2)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_short_channel_id(&ptr, &r->tlv2->scid);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n1_tlv3(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n1 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv3)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_pubkey(&ptr, &r->tlv3->node_id);
|
||||
towire_u64(&ptr, r->tlv3->amount_msat_1);
|
||||
towire_u64(&ptr, r->tlv3->amount_msat_2);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n1_tlv4(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n1 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv4)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_u16(&ptr, r->tlv4->cltv_delta);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n1_tlv1(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n1 *r = vrecord;
|
||||
|
||||
r->tlv1 = tal(r, struct tlv_n1_tlv1);
|
||||
r->tlv1->amount_msat = fromwire_tu64(cursor, max);
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n1_tlv2(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n1 *r = vrecord;
|
||||
|
||||
r->tlv2 = tal(r, struct tlv_n1_tlv2);
|
||||
fromwire_short_channel_id(cursor, max, &r->tlv2->scid);
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n1_tlv3(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n1 *r = vrecord;
|
||||
|
||||
r->tlv3 = tal(r, struct tlv_n1_tlv3);
|
||||
|
||||
fromwire_pubkey(cursor, max, &r->tlv3->node_id);
|
||||
r->tlv3->amount_msat_1 = fromwire_u64(cursor, max);
|
||||
r->tlv3->amount_msat_2 = fromwire_u64(cursor, max);
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n1_tlv4(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n1 *r = vrecord;
|
||||
|
||||
r->tlv4 = tal(r, struct tlv_n1_tlv4);
|
||||
r->tlv4->cltv_delta = fromwire_u16(cursor, max);
|
||||
}
|
||||
|
||||
static const struct tlv_record_type tlvs_n1[] = {
|
||||
{ 1, towire_tlv_n1_tlv1, fromwire_tlv_n1_tlv1 },
|
||||
{ 2, towire_tlv_n1_tlv2, fromwire_tlv_n1_tlv2 },
|
||||
{ 3, towire_tlv_n1_tlv3, fromwire_tlv_n1_tlv3 },
|
||||
{ 254, towire_tlv_n1_tlv4, fromwire_tlv_n1_tlv4 },
|
||||
};
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* 1. tlvs: `n2`
|
||||
* 2. types:
|
||||
* 1. type: 0 (`tlv1`)
|
||||
* 2. data:
|
||||
* * [`tu64`:`amount_msat`]
|
||||
* 1. type: 11 (`tlv2`)
|
||||
* 2. data:
|
||||
* * [`tu32`:`cltv_expiry`]
|
||||
*/
|
||||
struct tlv_n2_tlv1 {
|
||||
u64 amount_msat;
|
||||
};
|
||||
|
||||
struct tlv_n2_tlv2 {
|
||||
u16 cltv_expiry;
|
||||
};
|
||||
|
||||
struct tlv_n2 {
|
||||
struct tlv_n2_tlv1 *tlv1;
|
||||
struct tlv_n2_tlv2 *tlv2;
|
||||
};
|
||||
|
||||
static struct tlv_n2 *tlv_n2_new(const tal_t *ctx)
|
||||
{
|
||||
/* Initialize everything to NULL. (Quiet, C pedants!) */
|
||||
return talz(ctx, struct tlv_n2);
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n2_tlv1(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n2 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv1)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_tu64(&ptr, r->tlv1->amount_msat);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static u8 *towire_tlv_n2_tlv2(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_n2 *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->tlv2)
|
||||
return NULL;
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
towire_u16(&ptr, r->tlv2->cltv_expiry);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n2_tlv1(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n2 *r = vrecord;
|
||||
|
||||
r->tlv1 = tal(r, struct tlv_n2_tlv1);
|
||||
r->tlv1->amount_msat = fromwire_tu64(cursor, max);
|
||||
}
|
||||
|
||||
static void fromwire_tlv_n2_tlv2(const u8 **cursor, size_t *max, void *vrecord)
|
||||
{
|
||||
struct tlv_n2 *r = vrecord;
|
||||
|
||||
r->tlv2 = tal(r, struct tlv_n2_tlv2);
|
||||
r->tlv2->cltv_expiry = fromwire_u16(cursor, max);
|
||||
}
|
||||
|
||||
static const struct tlv_record_type tlvs_n2[] = {
|
||||
{ 0, towire_tlv_n2_tlv1, fromwire_tlv_n2_tlv1 },
|
||||
{ 11, towire_tlv_n2_tlv2, fromwire_tlv_n2_tlv2 },
|
||||
};
|
||||
|
||||
/* BOLT #1
|
||||
### TLV Decoding Failures
|
||||
|
||||
The following TLV streams in any namespace should trigger a decoding failure:
|
||||
|
||||
1. Invalid stream: 0xfd
|
||||
2. Reason: type truncated
|
||||
|
||||
1. Invalid stream: 0xfd01
|
||||
2. Reason: type truncated
|
||||
|
||||
1. Invalid stream: 0xfd0001 00
|
||||
2. Reason: not minimally encoded type
|
||||
|
||||
1. Invalid stream: 0xfd0101
|
||||
2. Reason: missing length
|
||||
|
||||
1. Invalid stream: 0x0f fd
|
||||
2. Reason: (length truncated)
|
||||
|
||||
1. Invalid stream: 0x0f fd26
|
||||
2. Reason: (length truncated)
|
||||
|
||||
1. Invalid stream: 0x0f fd2602
|
||||
2. Reason: missing value
|
||||
|
||||
1. Invalid stream: 0x0f fd0001 00
|
||||
2. Reason: not minimally encoded length
|
||||
|
||||
1. Invalid stream: 0x0f fd0201 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
2. Reason: value truncated
|
||||
|
||||
The following TLV streams in either namespace should trigger a
|
||||
decoding failure:
|
||||
|
||||
1. Invalid stream: 0x12 00
|
||||
2. Reason: unknown even type.
|
||||
|
||||
1. Invalid stream: 0xfd0102 00
|
||||
2. Reason: unknown even type.
|
||||
|
||||
1. Invalid stream: 0xfe01000002 00
|
||||
2. Reason: unknown even type.
|
||||
|
||||
1. Invalid stream: 0xff0100000000000002 00
|
||||
2. Reason: unknown even type.
|
||||
*/
|
||||
|
||||
struct invalid_stream {
|
||||
const char *hex;
|
||||
const char *reason;
|
||||
};
|
||||
|
||||
static struct invalid_stream invalid_streams_either[] = {
|
||||
{ "fd", "type truncated" },
|
||||
{ "fd01", "type truncated" },
|
||||
{ "fd0001 00", "not minimally encoded type" },
|
||||
{ "fd0101", "missing length" },
|
||||
{ "0f fd", "(length truncated)" },
|
||||
{ "0f fd26", "(length truncated)" },
|
||||
{ "0f fd2602", "missing value" },
|
||||
{ "0f fd0001 00", "not minimally encoded length" },
|
||||
{ "0f fd0201 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "value truncated" },
|
||||
|
||||
{ "12 00", "unknown even type." },
|
||||
{ "fd0102 00", "unknown even type." },
|
||||
{ "fe01000002 00", "unknown even type." },
|
||||
{ "ff0100000000000002 00", "unknown even type." },
|
||||
};
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
* The following TLV streams in namespace `n1` should trigger a decoding
|
||||
failure:
|
||||
|
||||
1. Invalid stream: 0x01 09 ffffffffffffffffff
|
||||
2. Reason: greater than encoding length for `n1`s `tlv1`.
|
||||
|
||||
1. Invalid stream: 0x01 01 00
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 02 0001
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 03 000100
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 04 00010000
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 05 0001000000
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 06 000100000000
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 07 00010000000000
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x01 08 0001000000000000
|
||||
2. Reason: encoding for `n1`s `tlv1`s `amount_msat` is not minimal
|
||||
|
||||
1. Invalid stream: 0x02 07 01010101010101
|
||||
2. Reason: less than encoding length for `n1`s `tlv2`.
|
||||
|
||||
1. Invalid stream: 0x02 09 010101010101010101
|
||||
2. Reason: greater than encoding length for `n1`s `tlv2`.
|
||||
|
||||
1. Invalid stream: 0x03 21 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb
|
||||
2. Reason: less than encoding length for `n1`s `tlv3`.
|
||||
|
||||
1. Invalid stream: 0x03 29 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001
|
||||
2. Reason: less than encoding length for `n1`s `tlv3`.
|
||||
|
||||
1. Invalid stream: 0x03 30 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001
|
||||
2. Reason: less than encoding length for `n1`s `tlv3`.
|
||||
|
||||
1. Invalid stream: 0x03 31 043da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002
|
||||
2. Reason: `n1`s `node_id` is not a valid point.
|
||||
|
||||
1. Invalid stream: 0x03 32 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001
|
||||
2. Reason: greater than encoding length for `n1`s `tlv3`.
|
||||
|
||||
1. Invalid stream: 0xfd00fe 00
|
||||
2. Reason: less than encoding length for `n1`s `tlv4`.
|
||||
|
||||
1. Invalid stream: 0xfd00fe 01 01
|
||||
2. Reason: less than encoding length for `n1`s `tlv4`.
|
||||
|
||||
1. Invalid stream: 0xfd00fe 03 010101
|
||||
2. Reason: greater than encoding length for `n1`s `tlv4`.
|
||||
|
||||
1. Invalid stream: 0x00 00
|
||||
2. Reason: unknown even field for `n1`s namespace.
|
||||
*/
|
||||
|
||||
static struct invalid_stream invalid_streams_n1[] = {
|
||||
{ "01 09 ffffffffffffffffff", "greater than encoding length for `n1`s `tlv1`." },
|
||||
{ "01 01 00", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 02 0001", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 03 000100", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 04 00010000", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 05 0001000000", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 06 000100000000", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 07 00010000000000", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "01 08 0001000000000000", "encoding for `n1`s `tlv1`s `amount_msat` is not minimal" },
|
||||
{ "02 07 01010101010101", "less than encoding length for `n1`s `tlv2`." },
|
||||
{ "02 09 010101010101010101", "greater than encoding length for `n1`s `tlv2`." },
|
||||
{ "03 21 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb", "less than encoding length for `n1`s `tlv3`." },
|
||||
{ "03 29 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001", "less than encoding length for `n1`s `tlv3`." },
|
||||
{ "03 30 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001", "less than encoding length for `n1`s `tlv3`." },
|
||||
{ "03 31 043da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002", "`n1`s `node_id` is not a valid point." },
|
||||
{ "03 32 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001", "greater than encoding length for `n1`s `tlv3`." },
|
||||
{ "fd00fe 00", "less than encoding length for `n1`s `tlv4`." },
|
||||
{ "fd00fe 01 01", "less than encoding length for `n1`s `tlv4`." },
|
||||
{ "fd00fe 03 010101", "greater than encoding length for `n1`s `tlv4`." },
|
||||
{ "00 00", "unknown even field for `n1`s namespace." },
|
||||
};
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
### TLV Stream Decoding Failure
|
||||
|
||||
Any appending of an invalid stream to a valid stream should trigger
|
||||
a decoding failure.
|
||||
|
||||
Any appending of a higher-numbered valid stream to a lower-numbered
|
||||
valid stream should not trigger a decoding failure.
|
||||
|
||||
In addition, the following TLV streams in namespace `n1` should
|
||||
trigger a decoding failure:
|
||||
|
||||
1. Invalid stream: 0x02 08 0000000000000226 01 01 2a
|
||||
2. Reason: valid tlv records but invalid ordering
|
||||
|
||||
1. Invalid stream: 0x02 08 0000000000000231 02 08 0000000000000451
|
||||
2. Reason: duplicate tlv type
|
||||
|
||||
1. Invalid stream: 0x1f 00 0f 01 2a
|
||||
2. Reason: valid (ignored) tlv records but invalid ordering
|
||||
|
||||
1. Invalid stream: 0x1f 00 1f 01 2a
|
||||
2. Reason: duplicate tlv type (ignored)
|
||||
*/
|
||||
static struct invalid_stream invalid_streams_n1_combo[] = {
|
||||
{ "02 08 0000000000000226 01 01 2a", "valid tlv records but invalid ordering" },
|
||||
{ "02 08 0000000000000231 02 08 0000000000000451", "duplicate tlv type" },
|
||||
{ "1f 00 0f 01 2a", "valid (ignored) tlv records but invalid ordering" },
|
||||
{ "1f 00 1f 01 2a", "duplicate tlv type (ignored)" }
|
||||
};
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
The following TLV stream in namespace `n2` should trigger a decoding
|
||||
failure:
|
||||
|
||||
1. Invalid stream: 0xffffffffffffffffff 00 00 00
|
||||
2. Reason: valid tlv records but invalid ordering
|
||||
*/
|
||||
static struct invalid_stream invalid_streams_n2_combo[] = {
|
||||
{ "ffffffffffffffffff 00 00 00", "valid tlv records but invalid ordering" },
|
||||
};
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
### TLV Decoding Successes
|
||||
|
||||
The following TLV streams in either namespace should correctly decode,
|
||||
and be ignored:
|
||||
|
||||
1. Valid stream: 0x
|
||||
2. Explanation: empty message
|
||||
|
||||
1. Valid stream: 0x21 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
1. Valid stream: 0xfd0201 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
1. Valid stream: 0xfd00fd 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
1. Valid stream: 0xfd00ff 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
1. Valid stream: 0xfe02000001 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
1. Valid stream: 0xff0200000000000001 00
|
||||
2. Explanation: Unknown odd type.
|
||||
|
||||
The following TLV streams in `n1` namespace should correctly decode,
|
||||
with the values given here:
|
||||
|
||||
1. Valid stream: 0x01 00
|
||||
2. Values: `tlv1` `amount_msat`=0
|
||||
|
||||
1. Valid stream: 0x01 01 01
|
||||
2. Values: `tlv1` `amount_msat`=1
|
||||
|
||||
1. Valid stream: 0x01 02 0100
|
||||
2. Values: `tlv1` `amount_msat`=256
|
||||
|
||||
1. Valid stream: 0x01 03 010000
|
||||
2. Values: `tlv1` `amount_msat`=65536
|
||||
|
||||
1. Valid stream: 0x01 04 01000000
|
||||
2. Values: `tlv1` `amount_msat`=16777216
|
||||
|
||||
1. Valid stream: 0x01 05 0100000000
|
||||
2. Values: `tlv1` `amount_msat`=4294967296
|
||||
|
||||
1. Valid stream: 0x01 06 010000000000
|
||||
2. Values: `tlv1` `amount_msat`=1099511627776
|
||||
|
||||
1. Valid stream: 0x01 07 01000000000000
|
||||
2. Values: `tlv1` `amount_msat`=281474976710656
|
||||
|
||||
1. Valid stream: 0x01 08 0100000000000000
|
||||
2. Values: `tlv1` `amount_msat`=72057594037927936
|
||||
|
||||
1. Valid stream: 0x02 08 0000000000000226
|
||||
2. Values: `tlv2` `scid`=0x0x550
|
||||
|
||||
1. Valid stream: 0x03 31 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002
|
||||
2. Values: `tlv3` `node_id`=023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb `amount_msat_1`=1 `amount_msat_2`=2
|
||||
|
||||
1. Valid stream: 0xfd00fe 02 0226
|
||||
2. Values: `tlv4` `cltv_delta`=550
|
||||
*/
|
||||
|
||||
struct valid_stream {
|
||||
const char *hex;
|
||||
const struct tlv_n1 expect;
|
||||
};
|
||||
|
||||
static struct tlv_n1_tlv1 tlv1_0 = { .amount_msat = 0 };
|
||||
static struct tlv_n1_tlv1 tlv1_1 = { .amount_msat = 1 };
|
||||
static struct tlv_n1_tlv1 tlv1_256 = { .amount_msat = 256 };
|
||||
static struct tlv_n1_tlv1 tlv1_65536 = { .amount_msat = 65536 };
|
||||
static struct tlv_n1_tlv1 tlv1_16777216 = { .amount_msat = 16777216 };
|
||||
static struct tlv_n1_tlv1 tlv1_4294967296 = { .amount_msat = 4294967296ULL };
|
||||
static struct tlv_n1_tlv1 tlv1_1099511627776 = { .amount_msat = 1099511627776ULL};
|
||||
static struct tlv_n1_tlv1 tlv1_281474976710656 = { .amount_msat = 281474976710656ULL };
|
||||
static struct tlv_n1_tlv1 tlv1_72057594037927936 = { .amount_msat = 72057594037927936ULL };
|
||||
static struct tlv_n1_tlv2 tlv2_0x0x550 = { .scid.u64 = 0x000000000226 };
|
||||
/* node_id filled in at runtime. */
|
||||
static struct tlv_n1_tlv3 tlv3_node_id = { { { { 0 } } }, .amount_msat_1 = 1, .amount_msat_2 = 2 };
|
||||
static struct tlv_n1_tlv4 tlv4_550 = { .cltv_delta = 550 };
|
||||
|
||||
static struct valid_stream valid_streams[] = {
|
||||
/* Valid but no (known) content. */
|
||||
{ "", {NULL, NULL, NULL, NULL} },
|
||||
{ "21 00", {NULL, NULL, NULL, NULL} },
|
||||
{ "fd0201 00", {NULL, NULL, NULL, NULL} },
|
||||
{ "fd00fd 00", {NULL, NULL, NULL, NULL} },
|
||||
{ "fd00ff 00", {NULL, NULL, NULL, NULL} },
|
||||
{ "fe02000001 00", {NULL, NULL, NULL, NULL} },
|
||||
{ "ff0200000000000001 00", {NULL, NULL, NULL, NULL} },
|
||||
|
||||
/* TLV1 */
|
||||
{ "01 00", { .tlv1 = &tlv1_0 } },
|
||||
{ "01 01 01", { .tlv1 = &tlv1_1 } },
|
||||
{ "01 02 0100", { .tlv1 = &tlv1_256 } },
|
||||
{ "01 03 010000", { .tlv1 = &tlv1_65536 } },
|
||||
{ "01 04 01000000", { .tlv1 = &tlv1_16777216 } },
|
||||
{ "01 05 0100000000", { .tlv1 = &tlv1_4294967296 } },
|
||||
{ "01 06 010000000000", { .tlv1 = &tlv1_1099511627776 } },
|
||||
{ "01 07 01000000000000", { .tlv1 = &tlv1_281474976710656 } },
|
||||
{ "01 08 0100000000000000", { .tlv1 = &tlv1_72057594037927936 } },
|
||||
{ "02 08 0000000000000226", { .tlv2 = &tlv2_0x0x550 } },
|
||||
{ "03 31 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002", { .tlv3 = &tlv3_node_id } },
|
||||
{ "fd00fe 02 0226", { .tlv4 = &tlv4_550 } },
|
||||
};
|
||||
|
||||
static bool tlv_n1_eq(const struct tlv_n1 *a, const struct tlv_n1 *b)
|
||||
{
|
||||
if (a->tlv1) {
|
||||
if (!b->tlv1)
|
||||
return false;
|
||||
if (a->tlv1->amount_msat != b->tlv1->amount_msat)
|
||||
return false;
|
||||
} else if (b->tlv1)
|
||||
return false;
|
||||
|
||||
if (a->tlv2) {
|
||||
if (!b->tlv2)
|
||||
return false;
|
||||
if (!short_channel_id_eq(&a->tlv2->scid, &b->tlv2->scid))
|
||||
return false;
|
||||
} else if (b->tlv2)
|
||||
return false;
|
||||
|
||||
if (a->tlv3) {
|
||||
if (!b->tlv3)
|
||||
return false;
|
||||
if (!pubkey_eq(&a->tlv3->node_id, &b->tlv3->node_id))
|
||||
return false;
|
||||
if (a->tlv3->amount_msat_1 != b->tlv3->amount_msat_1)
|
||||
return false;
|
||||
if (a->tlv3->amount_msat_2 != b->tlv3->amount_msat_2)
|
||||
return false;
|
||||
} else if (b->tlv3)
|
||||
return false;
|
||||
|
||||
if (a->tlv4) {
|
||||
if (!b->tlv4)
|
||||
return false;
|
||||
if (a->tlv4->cltv_delta != b->tlv4->cltv_delta)
|
||||
return false;
|
||||
} else if (b->tlv4)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* hexstr is valid, so pull out first field */
|
||||
static u64 pull_type(const char *hexstr)
|
||||
{
|
||||
u8 v;
|
||||
|
||||
hex_decode(hexstr, 2, &v, sizeof(v));
|
||||
switch (v) {
|
||||
case 0xfd: {
|
||||
u16 d;
|
||||
hex_decode(hexstr + 2, 2*sizeof(d), &d, sizeof(d));
|
||||
return be16_to_cpu(d);
|
||||
}
|
||||
case 0xfe: {
|
||||
u32 d;
|
||||
hex_decode(hexstr + 2, 2*sizeof(d), &d, sizeof(d));
|
||||
return be32_to_cpu(d);
|
||||
}
|
||||
case 0xff: {
|
||||
u64 d;
|
||||
hex_decode(hexstr + 2, 2*sizeof(d), &d, sizeof(d));
|
||||
return be64_to_cpu(d);
|
||||
}
|
||||
default:
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *stream(const tal_t *ctx, const char *hex)
|
||||
{
|
||||
size_t i, j;
|
||||
char *str = tal_arr(tmpctx, char, strlen(hex) + 1);
|
||||
|
||||
/* Remove spaces and use normal helper */
|
||||
for (i = j = 0; i <= strlen(hex); i++) {
|
||||
if (hex[i] != ' ')
|
||||
str[j++] = hex[i];
|
||||
}
|
||||
return tal_hexdata(ctx, str, strlen(str));
|
||||
}
|
||||
|
||||
static u8 *stream2(const tal_t *ctx, const char *hex1, const char *hex2)
|
||||
{
|
||||
u8 *a = stream(tmpctx, hex1), *b = stream(tmpctx, hex2), *ret;
|
||||
|
||||
ret = tal_dup_arr(ctx, u8, a, tal_count(a), tal_count(b));
|
||||
memcpy(ret + tal_count(a), b, tal_count(b));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ignored_fields(const struct tlv_n1 *tlv_n1)
|
||||
{
|
||||
return tlv_n1->tlv1 == NULL
|
||||
&& tlv_n1->tlv2 == NULL
|
||||
&& tlv_n1->tlv3 == NULL
|
||||
&& tlv_n1->tlv4 == NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setup_locale();
|
||||
wally_init(0);
|
||||
secp256k1_ctx = wally_get_secp_context();
|
||||
|
||||
setup_tmpctx();
|
||||
|
||||
if (!pubkey_from_hexstr("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb", 66, &tlv3_node_id.node_id))
|
||||
abort();
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_either); i++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
struct tlv_n2 *tlv_n2 = tlv_n2_new(tmpctx);
|
||||
const u8 *p, *orig_p;
|
||||
size_t max;
|
||||
|
||||
orig_p = stream(tmpctx, invalid_streams_either[i].hex);
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
assert(!fromwire_tlvs(&p, &max, tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
assert(strstr(invalid_streams_either[i].reason, reason));
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
assert(!fromwire_tlvs(&p, &max, tlvs_n2, ARRAY_SIZE(tlvs_n2),
|
||||
tlv_n2));
|
||||
assert(!p);
|
||||
assert(strstr(invalid_streams_either[i].reason, reason));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_n1); i++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *p;
|
||||
size_t max;
|
||||
|
||||
p = stream(tmpctx, invalid_streams_n1[i].hex);
|
||||
max = tal_count(p);
|
||||
assert(!fromwire_tlvs(&p, &max, tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
assert(strstr(invalid_streams_n1[i].reason, reason));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_n1_combo); i++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *p;
|
||||
size_t max;
|
||||
|
||||
p = stream(tmpctx, invalid_streams_n1_combo[i].hex);
|
||||
max = tal_count(p);
|
||||
assert(!fromwire_tlvs(&p, &max, tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
assert(strstr(invalid_streams_n1_combo[i].reason, reason));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_n2_combo); i++) {
|
||||
struct tlv_n2 *tlv_n2 = tlv_n2_new(tmpctx);
|
||||
const u8 *p;
|
||||
size_t max;
|
||||
|
||||
p = stream(tmpctx, invalid_streams_n2_combo[i].hex);
|
||||
max = tal_count(p);
|
||||
assert(!fromwire_tlvs(&p, &max, tlvs_n2, ARRAY_SIZE(tlvs_n2),
|
||||
tlv_n2));
|
||||
assert(!p);
|
||||
assert(strstr(invalid_streams_n2_combo[i].reason, reason));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(valid_streams); i++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *orig_p, *p;
|
||||
u8 *p2;
|
||||
size_t max;
|
||||
|
||||
orig_p = stream(tmpctx, valid_streams[i].hex);
|
||||
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
assert(fromwire_tlvs(&p, &max, tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(p);
|
||||
assert(max == 0);
|
||||
assert(tlv_n1_eq(tlv_n1, &valid_streams[i].expect));
|
||||
|
||||
/* Re-encoding should give the same results (except
|
||||
* ignored fields tests!) */
|
||||
if (ignored_fields(tlv_n1))
|
||||
continue;
|
||||
|
||||
p2 = tal_arr(tmpctx, u8, 0);
|
||||
towire_tlvs(&p2, tlvs_n1, ARRAY_SIZE(tlvs_n1), tlv_n1);
|
||||
assert(memeq(p2, tal_count(p2), orig_p, tal_count(orig_p)));
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
* Any appending of an invalid stream to a valid stream should trigger
|
||||
* a decoding failure.
|
||||
*/
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_either); i++) {
|
||||
for (size_t j = 0; j < ARRAY_SIZE(valid_streams); j++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
struct tlv_n2 *tlv_n2 = tlv_n2_new(tmpctx);
|
||||
const u8 *orig_p, *p;
|
||||
size_t max;
|
||||
|
||||
/* Append */
|
||||
orig_p = stream2(tmpctx, valid_streams[j].hex,
|
||||
invalid_streams_either[i].hex);
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
assert(!fromwire_tlvs(&p, &max,
|
||||
tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
assert(!fromwire_tlvs(&p, &max,
|
||||
tlvs_n2, ARRAY_SIZE(tlvs_n2),
|
||||
tlv_n2));
|
||||
assert(!p);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_n1); i++) {
|
||||
for (size_t j = 0; j < ARRAY_SIZE(valid_streams); j++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *p;
|
||||
size_t max;
|
||||
|
||||
p = stream2(tmpctx, valid_streams[j].hex,
|
||||
invalid_streams_n1[i].hex);
|
||||
max = tal_count(p);
|
||||
assert(!fromwire_tlvs(&p, &max,
|
||||
tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(invalid_streams_n1_combo); i++) {
|
||||
for (size_t j = 0; j < ARRAY_SIZE(valid_streams); j++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *p;
|
||||
size_t max;
|
||||
|
||||
p = stream2(tmpctx, valid_streams[j].hex,
|
||||
invalid_streams_n1_combo[i].hex);
|
||||
max = tal_count(p);
|
||||
assert(!fromwire_tlvs(&p, &max,
|
||||
tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1));
|
||||
assert(!p);
|
||||
}
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
* Any appending of a higher-numbered valid stream to a lower-numbered
|
||||
* valid stream should not trigger a decoding failure.
|
||||
*/
|
||||
for (size_t i = 0; i < ARRAY_SIZE(valid_streams); i++) {
|
||||
for (size_t j = i+1; j < ARRAY_SIZE(valid_streams); j++) {
|
||||
struct tlv_n1 *tlv_n1 = tlv_n1_new(tmpctx);
|
||||
const u8 *orig_p, *p;
|
||||
size_t max;
|
||||
bool expect_success;
|
||||
|
||||
if (strlen(valid_streams[i].hex) == 0
|
||||
|| strlen(valid_streams[j].hex) == 0)
|
||||
continue;
|
||||
|
||||
orig_p = stream2(tmpctx, valid_streams[i].hex,
|
||||
valid_streams[j].hex);
|
||||
max = tal_count(orig_p);
|
||||
p = orig_p;
|
||||
|
||||
/* This comparison works for our simple cases. */
|
||||
expect_success = pull_type(valid_streams[i].hex)
|
||||
< pull_type(valid_streams[j].hex);
|
||||
|
||||
assert(fromwire_tlvs(&p, &max,
|
||||
tlvs_n1, ARRAY_SIZE(tlvs_n1),
|
||||
tlv_n1) == expect_success);
|
||||
|
||||
if (!expect_success)
|
||||
continue;
|
||||
|
||||
/* Re-encoding should give the same results (except
|
||||
* ignored fields tests!) */
|
||||
if (ignored_fields(&valid_streams[i].expect)
|
||||
|| ignored_fields(&valid_streams[j].expect))
|
||||
continue;
|
||||
|
||||
u8 *p2 = tal_arr(tmpctx, u8, 0);
|
||||
towire_tlvs(&p2, tlvs_n1, ARRAY_SIZE(tlvs_n1), tlv_n1);
|
||||
assert(memeq(orig_p, tal_count(orig_p),
|
||||
p2, tal_count(p2)));
|
||||
}
|
||||
}
|
||||
tal_free(tmpctx);
|
||||
wally_cleanup(0);
|
||||
}
|
@ -2,6 +2,10 @@
|
||||
#include <assert.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
#ifndef SUPERVERBOSE
|
||||
#define SUPERVERBOSE(...)
|
||||
#endif
|
||||
|
||||
static const struct tlv_record_type *
|
||||
find_record_type(u64 type,
|
||||
const struct tlv_record_type types[],
|
||||
@ -40,29 +44,47 @@ bool fromwire_tlvs(const u8 **cursor, size_t *max,
|
||||
* format
|
||||
*/
|
||||
type = fromwire_bigsize(cursor, max);
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* - if a `type` or `length` is not minimally encoded:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (!*cursor) {
|
||||
SUPERVERBOSE("type");
|
||||
goto fail;
|
||||
}
|
||||
length = fromwire_bigsize(cursor, max);
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* - if a `type` or `length` is not minimally encoded:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (!*cursor)
|
||||
if (!*cursor) {
|
||||
SUPERVERBOSE("length");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* - if `length` exceeds the number of bytes remaining in the
|
||||
* message:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (length > *max)
|
||||
if (length > *max) {
|
||||
SUPERVERBOSE("value");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* - if decoded `type`s are not monotonically-increasing:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (!first && type <= prev_type)
|
||||
if (!first && type <= prev_type) {
|
||||
if (type == prev_type)
|
||||
SUPERVERBOSE("duplicate tlv type");
|
||||
else
|
||||
SUPERVERBOSE("invalid ordering");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
* - if `type` is known:
|
||||
@ -83,8 +105,10 @@ bool fromwire_tlvs(const u8 **cursor, size_t *max,
|
||||
* for the known encoding for `type`:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
*/
|
||||
if (tlvlen != 0)
|
||||
if (tlvlen != 0) {
|
||||
SUPERVERBOSE("greater than encoding length");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* We've read bytes in ->fromwire, so update max */
|
||||
*max -= length;
|
||||
@ -98,8 +122,10 @@ bool fromwire_tlvs(const u8 **cursor, size_t *max,
|
||||
*/
|
||||
if (type & 1)
|
||||
fromwire(cursor, max, NULL, length);
|
||||
else
|
||||
else {
|
||||
SUPERVERBOSE("unknown even");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
prev_type = type;
|
||||
|
Loading…
Reference in New Issue
Block a user