Skip to content

Commit a1308b7

Browse files
tests: Add fuzzing harnesses for various JSON/univalue parsing functions
1 parent e3d2bcf commit a1308b7

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/Makefile.test.include

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ FUZZ_TARGETS = \
4040
test/fuzz/prefilled_transaction_deserialize \
4141
test/fuzz/parse_numbers \
4242
test/fuzz/parse_script \
43+
test/fuzz/parse_univalue \
4344
test/fuzz/psbt \
4445
test/fuzz/psbt_input_deserialize \
4546
test/fuzz/psbt_output_deserialize \
@@ -97,6 +98,7 @@ FUZZ_SUITE_LD_COMMON = \
9798
$(LIBTEST_UTIL) \
9899
$(LIBBITCOIN_CONSENSUS) \
99100
$(LIBBITCOIN_CRYPTO) \
101+
$(LIBBITCOIN_CLI) \
100102
$(LIBUNIVALUE) \
101103
$(LIBLEVELDB) \
102104
$(LIBLEVELDB_SSE42) \
@@ -539,6 +541,12 @@ test_fuzz_parse_numbers_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
539541
test_fuzz_parse_numbers_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
540542
test_fuzz_parse_numbers_LDADD = $(FUZZ_SUITE_LD_COMMON)
541543

544+
test_fuzz_parse_univalue_SOURCES = $(FUZZ_SUITE) test/fuzz/parse_univalue.cpp
545+
test_fuzz_parse_univalue_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
546+
test_fuzz_parse_univalue_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
547+
test_fuzz_parse_univalue_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
548+
test_fuzz_parse_univalue_LDADD = $(FUZZ_SUITE_LD_COMMON)
549+
542550
endif # ENABLE_FUZZ
543551

544552
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)

src/test/fuzz/parse_univalue.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (c) 2009-2019 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <chainparams.h>
6+
#include <core_io.h>
7+
#include <rpc/client.h>
8+
#include <rpc/util.h>
9+
#include <test/fuzz/fuzz.h>
10+
#include <util/memory.h>
11+
12+
#include <limits>
13+
#include <string>
14+
15+
void initialize()
16+
{
17+
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
18+
SelectParams(CBaseChainParams::REGTEST);
19+
}
20+
21+
void test_one_input(const std::vector<uint8_t>& buffer)
22+
{
23+
const std::string random_string(buffer.begin(), buffer.end());
24+
bool valid = true;
25+
const UniValue univalue = [&] {
26+
try {
27+
return ParseNonRFCJSONValue(random_string);
28+
} catch (const std::runtime_error&) {
29+
valid = false;
30+
return NullUniValue;
31+
}
32+
}();
33+
if (!valid) {
34+
return;
35+
}
36+
try {
37+
(void)ParseHashO(univalue, "A");
38+
(void)ParseHashO(univalue, random_string);
39+
} catch (const UniValue&) {
40+
} catch (const std::runtime_error&) {
41+
}
42+
try {
43+
(void)ParseHashV(univalue, "A");
44+
(void)ParseHashV(univalue, random_string);
45+
} catch (const UniValue&) {
46+
} catch (const std::runtime_error&) {
47+
}
48+
try {
49+
(void)ParseHexO(univalue, "A");
50+
(void)ParseHexO(univalue, random_string);
51+
} catch (const UniValue&) {
52+
} catch (const std::runtime_error&) {
53+
}
54+
try {
55+
(void)ParseHexUV(univalue, "A");
56+
(void)ParseHexUV(univalue, random_string);
57+
} catch (const UniValue&) {
58+
} catch (const std::runtime_error&) {
59+
}
60+
try {
61+
(void)ParseHexV(univalue, "A");
62+
(void)ParseHexV(univalue, random_string);
63+
} catch (const UniValue&) {
64+
} catch (const std::runtime_error&) {
65+
}
66+
try {
67+
(void)ParseSighashString(univalue);
68+
} catch (const std::runtime_error&) {
69+
}
70+
try {
71+
(void)AmountFromValue(univalue);
72+
} catch (const UniValue&) {
73+
} catch (const std::runtime_error&) {
74+
}
75+
try {
76+
FlatSigningProvider provider;
77+
(void)EvalDescriptorStringOrObject(univalue, provider);
78+
} catch (const UniValue&) {
79+
} catch (const std::runtime_error&) {
80+
}
81+
try {
82+
(void)ParseConfirmTarget(univalue, std::numeric_limits<unsigned int>::max());
83+
} catch (const UniValue&) {
84+
} catch (const std::runtime_error&) {
85+
}
86+
try {
87+
(void)ParseDescriptorRange(univalue);
88+
} catch (const UniValue&) {
89+
} catch (const std::runtime_error&) {
90+
}
91+
}

0 commit comments

Comments
 (0)