Skip to content

Commit 5e12a61

Browse files
author
MarcoFalke
committed
Merge #17926: tests: Add key_io fuzzing harness. Fuzz additional functions in existing fuzzing harnesses.
52fed69 tests: Fuzz additional functions in the script fuzzing harness (practicalswift) 5fc10f3 tests: Fuzz additional functions in the transaction fuzzing harness (practicalswift) 1d324ce tests: Fuzz additional functions in the integer fuzzing harness (practicalswift) 4fe4de6 tests: Fuzz additional functions in the hex fuzzing harness (practicalswift) c7ea12d tests: Add key_io fuzzing harness (practicalswift) Pull request description: Add `key_io` fuzzing harness. Fuzz additional functions in the `hex` fuzzing harness. Fuzz additional functions in the `integer` fuzzing harness. Fuzz additional functions in the `script` fuzzing harness. Fuzz additional functions in the `transaction` fuzzing harness. **How to test this PR** ``` $ make distclean $ ./autogen.sh $ CC=clang CXX=clang++ ./configure --enable-fuzz \ --with-sanitizers=address,fuzzer,undefined $ make $ src/test/fuzz/key_io … ``` ACKs for top commit: MarcoFalke: ACK 52fed69 🛫 Tree-SHA512: a57ab66c18d260c2e39d987cab9fa576f7a5520dc1ea7fd607d64d8e005e16558312ddb4c9f4d4f3147dc6194d8ae0b0fb86ed5e58ba6aef5383ea726463df97
2 parents 3d28c88 + 52fed69 commit 5e12a61

File tree

7 files changed

+142
-2
lines changed

7 files changed

+142
-2
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ FUZZ_TARGETS = \
3636
test/fuzz/integer \
3737
test/fuzz/inv_deserialize \
3838
test/fuzz/key \
39+
test/fuzz/key_io \
3940
test/fuzz/key_origin_info_deserialize \
4041
test/fuzz/locale \
4142
test/fuzz/merkle_block_deserialize \
@@ -438,6 +439,12 @@ test_fuzz_key_LDADD = $(FUZZ_SUITE_LD_COMMON)
438439
test_fuzz_key_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
439440
test_fuzz_key_SOURCES = $(FUZZ_SUITE) test/fuzz/key.cpp
440441

442+
test_fuzz_key_io_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
443+
test_fuzz_key_io_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
444+
test_fuzz_key_io_LDADD = $(FUZZ_SUITE_LD_COMMON)
445+
test_fuzz_key_io_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
446+
test_fuzz_key_io_SOURCES = $(FUZZ_SUITE) test/fuzz/key_io.cpp
447+
441448
test_fuzz_key_origin_info_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DKEY_ORIGIN_INFO_DESERIALIZE=1
442449
test_fuzz_key_origin_info_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
443450
test_fuzz_key_origin_info_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/hex.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <core_io.h>
6+
#include <primitives/block.h>
7+
#include <rpc/util.h>
58
#include <test/fuzz/fuzz.h>
6-
9+
#include <uint256.h>
10+
#include <univalue.h>
711
#include <util/strencodings.h>
812

913
#include <cassert>
@@ -19,4 +23,14 @@ void test_one_input(const std::vector<uint8_t>& buffer)
1923
if (IsHex(random_hex_string)) {
2024
assert(ToLower(random_hex_string) == hex_data);
2125
}
26+
(void)IsHexNumber(random_hex_string);
27+
uint256 result;
28+
(void)ParseHashStr(random_hex_string, result);
29+
(void)uint256S(random_hex_string);
30+
try {
31+
(void)HexToPubKey(random_hex_string);
32+
} catch (const UniValue&) {
33+
}
34+
CBlockHeader block_header;
35+
(void)DecodeHexBlockHeader(block_header, random_hex_string);
2236
}

src/test/fuzz/integer.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <test/fuzz/FuzzedDataProvider.h>
2424
#include <test/fuzz/fuzz.h>
2525
#include <uint256.h>
26+
#include <util/moneystr.h>
2627
#include <util/strencodings.h>
2728
#include <util/system.h>
2829
#include <util/time.h>
@@ -76,11 +77,19 @@ void test_one_input(const std::vector<uint8_t>& buffer)
7677
(void)DecompressAmount(u64);
7778
(void)FormatISO8601Date(i64);
7879
(void)FormatISO8601DateTime(i64);
80+
// FormatMoney(i) not defined when i == std::numeric_limits<int64_t>::min()
81+
if (i64 != std::numeric_limits<int64_t>::min()) {
82+
int64_t parsed_money;
83+
if (ParseMoney(FormatMoney(i64), parsed_money)) {
84+
assert(parsed_money == i64);
85+
}
86+
}
7987
(void)GetSizeOfCompactSize(u64);
8088
(void)GetSpecialScriptSize(u32);
8189
// (void)GetVirtualTransactionSize(i64, i64); // function defined only for a subset of int64_t inputs
8290
// (void)GetVirtualTransactionSize(i64, i64, u32); // function defined only for a subset of int64_t/uint32_t inputs
8391
(void)HexDigit(ch);
92+
(void)MoneyRange(i64);
8493
(void)i64tostr(i64);
8594
(void)IsDigit(ch);
8695
(void)IsSpace(ch);
@@ -106,6 +115,14 @@ void test_one_input(const std::vector<uint8_t>& buffer)
106115
(void)SipHashUint256(u64, u64, u256);
107116
(void)SipHashUint256Extra(u64, u64, u256, u32);
108117
(void)ToLower(ch);
118+
(void)ToUpper(ch);
119+
// ValueFromAmount(i) not defined when i == std::numeric_limits<int64_t>::min()
120+
if (i64 != std::numeric_limits<int64_t>::min()) {
121+
int64_t parsed_money;
122+
if (ParseMoney(ValueFromAmount(i64).getValStr(), parsed_money)) {
123+
assert(parsed_money == i64);
124+
}
125+
}
109126

110127
const arith_uint256 au256 = UintToArith256(u256);
111128
assert(ArithToUint256(au256) == u256);

src/test/fuzz/key_io.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2020 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 <key_io.h>
7+
#include <rpc/util.h>
8+
#include <script/signingprovider.h>
9+
#include <script/standard.h>
10+
#include <test/fuzz/fuzz.h>
11+
12+
#include <cassert>
13+
#include <cstdint>
14+
#include <string>
15+
#include <vector>
16+
17+
void initialize()
18+
{
19+
SelectParams(CBaseChainParams::REGTEST);
20+
}
21+
22+
void test_one_input(const std::vector<uint8_t>& buffer)
23+
{
24+
const std::string random_string(buffer.begin(), buffer.end());
25+
26+
const CKey key = DecodeSecret(random_string);
27+
if (key.IsValid()) {
28+
assert(key == DecodeSecret(EncodeSecret(key)));
29+
}
30+
31+
const CExtKey ext_key = DecodeExtKey(random_string);
32+
if (ext_key.key.size() == 32) {
33+
assert(ext_key == DecodeExtKey(EncodeExtKey(ext_key)));
34+
}
35+
36+
const CExtPubKey ext_pub_key = DecodeExtPubKey(random_string);
37+
if (ext_pub_key.pubkey.size() == CPubKey::COMPRESSED_SIZE) {
38+
assert(ext_pub_key == DecodeExtPubKey(EncodeExtPubKey(ext_pub_key)));
39+
}
40+
41+
const CTxDestination tx_destination = DecodeDestination(random_string);
42+
(void)DescribeAddress(tx_destination);
43+
(void)GetKeyForDestination(/* store */ {}, tx_destination);
44+
(void)GetScriptForDestination(tx_destination);
45+
(void)IsValidDestination(tx_destination);
46+
47+
(void)IsValidDestinationString(random_string);
48+
}

src/test/fuzz/script.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,36 @@
1515
#include <script/standard.h>
1616
#include <streams.h>
1717
#include <test/fuzz/fuzz.h>
18+
#include <univalue.h>
1819
#include <util/memory.h>
1920

2021
void initialize()
2122
{
2223
// Fuzzers using pubkey must hold an ECCVerifyHandle.
2324
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
25+
26+
SelectParams(CBaseChainParams::REGTEST);
2427
}
2528

2629
void test_one_input(const std::vector<uint8_t>& buffer)
2730
{
2831
const CScript script(buffer.begin(), buffer.end());
2932

3033
std::vector<unsigned char> compressed;
31-
(void)CompressScript(script, compressed);
34+
if (CompressScript(script, compressed)) {
35+
const unsigned int size = compressed[0];
36+
assert(size >= 0 && size <= 5);
37+
CScript decompressed_script;
38+
const bool ok = DecompressScript(decompressed_script, size, compressed);
39+
assert(ok);
40+
}
41+
42+
for (unsigned int size = 0; size < 6; ++size) {
43+
std::vector<unsigned char> vch(GetSpecialScriptSize(size), 0x00);
44+
vch.insert(vch.end(), buffer.begin(), buffer.end());
45+
CScript decompressed_script;
46+
(void)DecompressScript(decompressed_script, size, vch);
47+
}
3248

3349
CTxDestination address;
3450
(void)ExtractDestination(script, address);
@@ -61,4 +77,17 @@ void test_one_input(const std::vector<uint8_t>& buffer)
6177
(void)script.IsPushOnly();
6278
(void)script.IsUnspendable();
6379
(void)script.GetSigOpCount(/* fAccurate= */ false);
80+
81+
(void)FormatScript(script);
82+
(void)ScriptToAsmStr(script, false);
83+
(void)ScriptToAsmStr(script, true);
84+
85+
UniValue o1(UniValue::VOBJ);
86+
ScriptPubKeyToUniv(script, o1, true);
87+
UniValue o2(UniValue::VOBJ);
88+
ScriptPubKeyToUniv(script, o2, false);
89+
UniValue o3(UniValue::VOBJ);
90+
ScriptToUniv(script, o3, true);
91+
UniValue o4(UniValue::VOBJ);
92+
ScriptToUniv(script, o4, false);
6493
}

src/test/fuzz/transaction.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <chainparams.h>
56
#include <coins.h>
67
#include <consensus/tx_check.h>
78
#include <consensus/tx_verify.h>
@@ -13,12 +14,18 @@
1314
#include <primitives/transaction.h>
1415
#include <streams.h>
1516
#include <test/fuzz/fuzz.h>
17+
#include <univalue.h>
1618
#include <util/rbf.h>
1719
#include <validation.h>
1820
#include <version.h>
1921

2022
#include <cassert>
2123

24+
void initialize()
25+
{
26+
SelectParams(CBaseChainParams::REGTEST);
27+
}
28+
2229
void test_one_input(const std::vector<uint8_t>& buffer)
2330
{
2431
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
@@ -85,4 +92,21 @@ void test_one_input(const std::vector<uint8_t>& buffer)
8592
(void)IsStandardTx(tx, reason);
8693
(void)RecursiveDynamicUsage(tx);
8794
(void)SignalsOptInRBF(tx);
95+
96+
CCoinsView coins_view;
97+
const CCoinsViewCache coins_view_cache(&coins_view);
98+
(void)AreInputsStandard(tx, coins_view_cache);
99+
(void)IsWitnessStandard(tx, coins_view_cache);
100+
101+
UniValue u(UniValue::VOBJ);
102+
// ValueFromAmount(i) not defined when i == std::numeric_limits<int64_t>::min()
103+
bool skip_tx_to_univ = false;
104+
for (const CTxOut& txout : tx.vout) {
105+
if (txout.nValue == std::numeric_limits<int64_t>::min()) {
106+
skip_tx_to_univ = true;
107+
}
108+
}
109+
if (!skip_tx_to_univ) {
110+
TxToUniv(tx, /* hashBlock */ {}, u);
111+
}
88112
}

test/fuzz/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"flat_file_pos_deserialize",
2828
"float",
2929
"hex",
30+
"key_io",
3031
"integer",
3132
"key",
3233
"key_origin_info_deserialize",

0 commit comments

Comments
 (0)