diff --git a/.gitignore b/.gitignore index 487e2788e..b068917d0 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,8 @@ test/test_protocol test/test_sphinx tests/.pytest.restart tests/plugins/test_libplugin +tests/fuzz/fuzz-* +!tests/fuzz/fuzz-*.c gossip_store .pytest_cache tools/headerversions diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index ea3b64a21..1cef8eebd 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -7,12 +7,7 @@ FUZZ_TARGETS_SRC := $(wildcard tests/fuzz/fuzz-*.c) FUZZ_TARGETS_OBJS := $(FUZZ_TARGETS_SRC:.c=.o) FUZZ_TARGETS_BIN := $(FUZZ_TARGETS_SRC:.c=) -FUZZ_COMMON_OBJS := \ - common/utils.o -$(FUZZ_TARGETS_OBJS): $(COMMON_HEADERS) $(WIRE_HEADERS) $(COMMON_SRC) -$(FUZZ_TARGETS_BIN): $(LIBFUZZ_OBJS) $(FUZZ_COMMON_OBJS) $(BITCOIN_OBJS) - -tests/fuzz/fuzz-addr: \ +FUZZ_COMMON_OBJS := \ common/amount.o \ common/addr.o \ common/base32.o \ @@ -22,9 +17,12 @@ tests/fuzz/fuzz-addr: \ common/json_stream.o \ common/wireaddr.o \ common/type_to_string.o \ + common/utils.o \ wire/fromwire.o \ wire/onion_wiregen.o \ wire/towire.o +$(FUZZ_TARGETS_OBJS): $(COMMON_HEADERS) $(WIRE_HEADERS) $(COMMON_SRC) +$(FUZZ_TARGETS_BIN): $(LIBFUZZ_OBJS) $(FUZZ_COMMON_OBJS) $(BITCOIN_OBJS) ALL_C_SOURCES += $(FUZZ_TARGETS_SRC) $(LIBFUZZ_SRC) ALL_FUZZ_TARGETS += $(FUZZ_TARGETS_BIN) diff --git a/tests/fuzz/fuzz-amount.c b/tests/fuzz/fuzz-amount.c new file mode 100644 index 000000000..644c9b0b7 --- /dev/null +++ b/tests/fuzz/fuzz-amount.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include +#include +#include + +void init(int *argc, char ***argv) +{ +} + +void run(const uint8_t *data, size_t size) +{ + struct amount_msat msat; + struct amount_sat sat; + char *string; + uint8_t *buf; + const char *fmt_msat, *fmt_msatbtc, *fmt_sat, *fmt_satbtc; + + + /* We should not crash when parsing any string. */ + + string = tal_arr(NULL, char, size); + for (size_t i = 0; i < size; i++) + string[i] = (char) data[i] % (CHAR_MAX + 1); + + parse_amount_msat(&msat, string, tal_count(string)); + parse_amount_sat(&sat, string, tal_count(string)); + tal_free(string); + + + /* Same with the wire primitives. */ + + buf = tal_arr(NULL, uint8_t, 8); + + msat = fromwire_amount_msat(&data, &size); + towire_amount_msat(&buf, msat); + sat = fromwire_amount_sat(&data, &size); + towire_amount_sat(&buf, sat); + + tal_free(buf); + + + /* Format should inconditionally produce valid amount strings according to our + * parser */ + + fmt_msat = fmt_amount_msat(NULL, &msat); + fmt_msatbtc = fmt_amount_msat_btc(NULL, &msat, true); + assert(parse_amount_msat(&msat, fmt_msat, tal_count(fmt_msat))); + assert(parse_amount_msat(&msat, fmt_msatbtc, tal_count(fmt_msatbtc))); + tal_free(fmt_msat); + tal_free(fmt_msatbtc); + + fmt_sat = fmt_amount_sat(NULL, &sat); + fmt_satbtc = fmt_amount_sat_btc(NULL, &sat, true); + assert(parse_amount_sat(&sat, fmt_sat, tal_count(fmt_sat))); + assert(parse_amount_sat(&sat, fmt_satbtc, tal_count(fmt_satbtc))); + tal_free(fmt_sat); + tal_free(fmt_satbtc); +}