wire: add bigsize parsing tests.
Based on: https://github.com/lightningnetwork/lightning-rfc/pull/640 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3477034657
commit
e737fe72d6
|
@ -0,0 +1,282 @@
|
|||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json.c>
|
||||
#include <common/utils.h>
|
||||
|
||||
static const char *reason;
|
||||
#define SUPERVERBOSE(r) do { if (!reason) reason = (r); } while(0)
|
||||
|
||||
#include <wire/fromwire.c>
|
||||
#include <wire/towire.c>
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
/* AUTOGENERATED MOCKS END */
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
* A correct implementation should pass against these test vectors:
|
||||
* ```json
|
||||
* [
|
||||
* {
|
||||
* "name": "zero",
|
||||
* "value": 0,
|
||||
* "bytes": "00"
|
||||
* },
|
||||
* {
|
||||
* "name": "one byte high",
|
||||
* "value": 252,
|
||||
* "bytes": "fc"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte low",
|
||||
* "value": 253,
|
||||
* "bytes": "fd00fd"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte high",
|
||||
* "value": 65535,
|
||||
* "bytes": "fdffff"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte low",
|
||||
* "value": 65536,
|
||||
* "bytes": "fe00010000"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte high",
|
||||
* "value": 4294967295,
|
||||
* "bytes": "feffffffff"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte low",
|
||||
* "value": 4294967296,
|
||||
* "bytes": "ff0000000100000000"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte high",
|
||||
* "value": 18446744073709551615,
|
||||
* "bytes": "ffffffffffffffffff"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte not canonical",
|
||||
* "value": 0,
|
||||
* "bytes": "fd00fc",
|
||||
* "exp_error": "decoded varint is not canonical"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte not canonical",
|
||||
* "value": 0,
|
||||
* "bytes": "fe0000ffff",
|
||||
* "exp_error": "decoded varint is not canonical"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte not canonical",
|
||||
* "value": 0,
|
||||
* "bytes": "ff00000000ffffffff",
|
||||
* "exp_error": "decoded varint is not canonical"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte short read",
|
||||
* "value": 0,
|
||||
* "bytes": "fd00",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte short read",
|
||||
* "value": 0,
|
||||
* "bytes": "feffff",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte short read",
|
||||
* "value": 0,
|
||||
* "bytes": "ffffffffff",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "one byte no read",
|
||||
* "value": 0,
|
||||
* "bytes": "",
|
||||
* "exp_error": "EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte no read",
|
||||
* "value": 0,
|
||||
* "bytes": "fd",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte no read",
|
||||
* "value": 0,
|
||||
* "bytes": "fe",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte no read",
|
||||
* "value": 0,
|
||||
* "bytes": "ff",
|
||||
* "exp_error": "unexpected EOF"
|
||||
* }
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
static void test_decode(const char *json, const jsmntok_t toks[])
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
|
||||
json_for_each_arr(i, t, toks) {
|
||||
const jsmntok_t *err = json_get_member(json, t, "exp_error");
|
||||
const jsmntok_t *bytes = json_get_member(json, t, "bytes");
|
||||
u64 num, expect;
|
||||
const u8 *b;
|
||||
size_t max;
|
||||
|
||||
if (!json_to_u64(json, json_get_member(json, t, "value"),
|
||||
&expect))
|
||||
abort();
|
||||
b = tal_hexdata(tmpctx, json + bytes->start,
|
||||
bytes->end - bytes->start);
|
||||
|
||||
max = tal_bytelen(b);
|
||||
reason = NULL;
|
||||
num = fromwire_bigsize(&b, &max);
|
||||
if (err) {
|
||||
assert(b == NULL);
|
||||
assert(max == 0);
|
||||
/* Map our errors to the test strings. */
|
||||
if (json_tok_streq(json, err,
|
||||
"decoded varint is not canonical"))
|
||||
assert(streq(reason, "not minimal encoded"));
|
||||
else if (json_tok_streq(json, err, "unexpected EOF")
|
||||
|| json_tok_streq(json, err, "EOF"))
|
||||
assert(streq(reason, "less than encoding length"));
|
||||
else
|
||||
abort();
|
||||
} else {
|
||||
assert(b != NULL);
|
||||
assert(num == expect);
|
||||
assert(max == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* BOLT-EXPERIMENTAL #1:
|
||||
*
|
||||
* A correct implementation should pass against the following test vectors:
|
||||
* ```json
|
||||
* [
|
||||
* {
|
||||
* "name": "zero",
|
||||
* "value": 0,
|
||||
* "bytes": "00"
|
||||
* },
|
||||
* {
|
||||
* "name": "one byte high",
|
||||
* "value": 252,
|
||||
* "bytes": "fc"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte low",
|
||||
* "value": 253,
|
||||
* "bytes": "fd00fd"
|
||||
* },
|
||||
* {
|
||||
* "name": "two byte high",
|
||||
* "value": 65535,
|
||||
* "bytes": "fdffff"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte low",
|
||||
* "value": 65536,
|
||||
* "bytes": "fe00010000"
|
||||
* },
|
||||
* {
|
||||
* "name": "four byte high",
|
||||
* "value": 4294967295,
|
||||
* "bytes": "feffffffff"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte low",
|
||||
* "value": 4294967296,
|
||||
* "bytes": "ff0000000100000000"
|
||||
* },
|
||||
* {
|
||||
* "name": "eight byte high",
|
||||
* "value": 18446744073709551615,
|
||||
* "bytes": "ffffffffffffffffff"
|
||||
* }
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
static void test_encode(const char *json, const jsmntok_t toks[])
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
|
||||
json_for_each_arr(i, t, toks) {
|
||||
const jsmntok_t *bytes = json_get_member(json, t, "bytes");
|
||||
u64 num;
|
||||
const u8 *expect;
|
||||
u8 *b;
|
||||
|
||||
if (!json_to_u64(json, json_get_member(json, t, "value"),
|
||||
&num))
|
||||
abort();
|
||||
expect = tal_hexdata(tmpctx, json + bytes->start,
|
||||
bytes->end - bytes->start);
|
||||
|
||||
b = tal_arr(tmpctx, u8, 0);
|
||||
towire_bigsize(&b, num);
|
||||
assert(memeq(b, tal_bytelen(b), expect, tal_bytelen(expect)));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char **lines, *json = NULL;
|
||||
int test_count = 0;
|
||||
|
||||
setup_locale();
|
||||
setup_tmpctx();
|
||||
|
||||
lines = tal_strsplit(tmpctx, grab_file(tmpctx, tal_fmt(tmpctx, "%s.c",
|
||||
argv[0])),
|
||||
"\n", STR_NO_EMPTY);
|
||||
|
||||
for (size_t i = 0; lines[i]; i++) {
|
||||
const char *l = lines[i];
|
||||
if (!strstarts(l, " * "))
|
||||
continue;
|
||||
l += 3;
|
||||
if (streq(l, "```json"))
|
||||
json = tal_strdup(tmpctx, "");
|
||||
else if (streq(l, "```")) {
|
||||
jsmn_parser parser;
|
||||
jsmntok_t toks[500];
|
||||
|
||||
jsmn_init(&parser);
|
||||
if (jsmn_parse(&parser, json, strlen(json),
|
||||
toks, ARRAY_SIZE(toks)) < 0)
|
||||
abort();
|
||||
|
||||
switch (test_count) {
|
||||
case 0:
|
||||
test_decode(json, toks);
|
||||
break;
|
||||
case 1:
|
||||
test_encode(json, toks);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
test_count++;
|
||||
json = NULL;
|
||||
} else if (json)
|
||||
tal_append_fmt(&json, "%s", l);
|
||||
}
|
||||
assert(test_count == 2);
|
||||
tal_free(tmpctx);
|
||||
}
|
Loading…
Reference in New Issue