#include #include #include #include #include #include static const char *reason; #define SUPERVERBOSE(r) do { if (!reason) reason = (r); } while(0) #include #include /* 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); }