aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/bech32.cpp43
-rw-r--r--src/test/fuzz/deserialize.cpp318
-rw-r--r--src/test/fuzz/eval_script.cpp9
-rw-r--r--src/test/fuzz/parse_iso8601.cpp32
-rw-r--r--src/test/fuzz/psbt.cpp79
-rw-r--r--src/test/fuzz/script_flags.cpp7
-rw-r--r--src/test/fuzz/transaction.cpp24
7 files changed, 403 insertions, 109 deletions
diff --git a/src/test/fuzz/bech32.cpp b/src/test/fuzz/bech32.cpp
new file mode 100644
index 0000000000..8b91f9bc96
--- /dev/null
+++ b/src/test/fuzz/bech32.cpp
@@ -0,0 +1,43 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <bech32.h>
+#include <test/fuzz/fuzz.h>
+#include <test/util/str.h>
+#include <util/strencodings.h>
+
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ const std::string random_string(buffer.begin(), buffer.end());
+ const std::pair<std::string, std::vector<uint8_t>> r1 = bech32::Decode(random_string);
+ if (r1.first.empty()) {
+ assert(r1.second.empty());
+ } else {
+ const std::string& hrp = r1.first;
+ const std::vector<uint8_t>& data = r1.second;
+ const std::string reencoded = bech32::Encode(hrp, data);
+ assert(CaseInsensitiveEqual(random_string, reencoded));
+ }
+
+ std::vector<unsigned char> input;
+ ConvertBits<8, 5, true>([&](unsigned char c) { input.push_back(c); }, buffer.begin(), buffer.end());
+ const std::string encoded = bech32::Encode("bc", input);
+ assert(!encoded.empty());
+
+ const std::pair<std::string, std::vector<uint8_t>> r2 = bech32::Decode(encoded);
+ if (r2.first.empty()) {
+ assert(r2.second.empty());
+ } else {
+ const std::string& hrp = r2.first;
+ const std::vector<uint8_t>& data = r2.second;
+ assert(hrp == "bc");
+ assert(data == input);
+ }
+}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index bcd8691359..46bc38fdab 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -5,18 +5,24 @@
#include <addrdb.h>
#include <addrman.h>
#include <blockencodings.h>
+#include <blockfilter.h>
#include <chain.h>
#include <coins.h>
#include <compressor.h>
#include <consensus/merkle.h>
+#include <key.h>
+#include <merkleblock.h>
#include <net.h>
#include <primitives/block.h>
#include <protocol.h>
+#include <psbt.h>
#include <pubkey.h>
+#include <script/keyorigin.h>
#include <streams.h>
#include <undo.h>
#include <version.h>
+#include <stdexcept>
#include <stdint.h>
#include <unistd.h>
@@ -37,129 +43,237 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
-#if BLOCK_DESERIALIZE
- try
- {
- CBlock block;
- ds >> block;
- } catch (const std::ios_base::failure& e) {return;}
+#if BLOCK_FILTER_DESERIALIZE
+ try {
+ BlockFilter block_filter;
+ ds >> block_filter;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif ADDR_INFO_DESERIALIZE
+ try {
+ CAddrInfo addr_info;
+ ds >> addr_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_FILE_INFO_DESERIALIZE
+ try {
+ CBlockFileInfo block_file_info;
+ ds >> block_file_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE
+ try {
+ CBlockHeaderAndShortTxIDs block_header_and_short_txids;
+ ds >> block_header_and_short_txids;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FEE_RATE_DESERIALIZE
+ try {
+ CFeeRate fee_rate;
+ ds >> fee_rate;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif MERKLE_BLOCK_DESERIALIZE
+ try {
+ CMerkleBlock merkle_block;
+ ds >> merkle_block;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif OUT_POINT_DESERIALIZE
+ try {
+ COutPoint out_point;
+ ds >> out_point;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIAL_MERKLE_TREE_DESERIALIZE
+ try {
+ CPartialMerkleTree partial_merkle_tree;
+ ds >> partial_merkle_tree;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PUB_KEY_DESERIALIZE
+ try {
+ CPubKey pub_key;
+ ds >> pub_key;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SCRIPT_DESERIALIZE
+ try {
+ CScript script;
+ ds >> script;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SUB_NET_DESERIALIZE
+ try {
+ CSubNet sub_net;
+ ds >> sub_net;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif TX_IN_DESERIALIZE
+ try {
+ CTxIn tx_in;
+ ds >> tx_in;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FLAT_FILE_POS_DESERIALIZE
+ try {
+ FlatFilePos flat_file_pos;
+ ds >> flat_file_pos;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif KEY_ORIGIN_INFO_DESERIALIZE
+ try {
+ KeyOriginInfo key_origin_info;
+ ds >> key_origin_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE
+ try {
+ PartiallySignedTransaction partially_signed_transaction;
+ ds >> partially_signed_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PREFILLED_TRANSACTION_DESERIALIZE
+ try {
+ PrefilledTransaction prefilled_transaction;
+ ds >> prefilled_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_INPUT_DESERIALIZE
+ try {
+ PSBTInput psbt_input;
+ ds >> psbt_input;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_OUTPUT_DESERIALIZE
+ try {
+ PSBTOutput psbt_output;
+ ds >> psbt_output;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_DESERIALIZE
+ try {
+ CBlock block;
+ ds >> block;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKLOCATOR_DESERIALIZE
- try
- {
- CBlockLocator bl;
- ds >> bl;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockLocator bl;
+ ds >> bl;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKMERKLEROOT
- try
- {
- CBlock block;
- ds >> block;
- bool mutated;
- BlockMerkleRoot(block, &mutated);
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlock block;
+ ds >> block;
+ bool mutated;
+ BlockMerkleRoot(block, &mutated);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRMAN_DESERIALIZE
- try
- {
- CAddrMan am;
- ds >> am;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddrMan am;
+ ds >> am;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKHEADER_DESERIALIZE
- try
- {
- CBlockHeader bh;
- ds >> bh;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockHeader bh;
+ ds >> bh;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BANENTRY_DESERIALIZE
- try
- {
- CBanEntry be;
- ds >> be;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBanEntry be;
+ ds >> be;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXUNDO_DESERIALIZE
- try
- {
- CTxUndo tu;
- ds >> tu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CTxUndo tu;
+ ds >> tu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKUNDO_DESERIALIZE
- try
- {
- CBlockUndo bu;
- ds >> bu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockUndo bu;
+ ds >> bu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif COINS_DESERIALIZE
- try
- {
- Coin coin;
- ds >> coin;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ Coin coin;
+ ds >> coin;
+ } catch (const std::ios_base::failure&) {
+ }
#elif NETADDR_DESERIALIZE
- try
- {
- CNetAddr na;
- ds >> na;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CNetAddr na;
+ ds >> na;
+ } catch (const std::ios_base::failure&) {
+ }
#elif SERVICE_DESERIALIZE
- try
- {
- CService s;
- ds >> s;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CService s;
+ ds >> s;
+ } catch (const std::ios_base::failure&) {
+ }
#elif MESSAGEHEADER_DESERIALIZE
- CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
- try
- {
- CMessageHeader mh(pchMessageStart);
- ds >> mh;
- if (!mh.IsValid(pchMessageStart)) {return;}
- } catch (const std::ios_base::failure& e) {return;}
+ CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
+ try {
+ CMessageHeader mh(pchMessageStart);
+ ds >> mh;
+ (void)mh.IsValid(pchMessageStart);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRESS_DESERIALIZE
- try
- {
- CAddress a;
- ds >> a;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddress a;
+ ds >> a;
+ } catch (const std::ios_base::failure&) {
+ }
#elif INV_DESERIALIZE
- try
- {
- CInv i;
- ds >> i;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CInv i;
+ ds >> i;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOOMFILTER_DESERIALIZE
- try
- {
- CBloomFilter bf;
- ds >> bf;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBloomFilter bf;
+ ds >> bf;
+ } catch (const std::ios_base::failure&) {
+ }
#elif DISKBLOCKINDEX_DESERIALIZE
- try
- {
- CDiskBlockIndex dbi;
- ds >> dbi;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CDiskBlockIndex dbi;
+ ds >> dbi;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXOUTCOMPRESSOR_DESERIALIZE
- CTxOut to;
- CTxOutCompressor toc(to);
- try
- {
- ds >> toc;
- } catch (const std::ios_base::failure& e) {return;}
+ CTxOut to;
+ CTxOutCompressor toc(to);
+ try {
+ ds >> toc;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONS_DESERIALIZE
- try
- {
- BlockTransactions bt;
- ds >> bt;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactions bt;
+ ds >> bt;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
- try
- {
- BlockTransactionsRequest btr;
- ds >> btr;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactionsRequest btr;
+ ds >> btr;
+ } catch (const std::ios_base::failure&) {
+ }
#else
#error Need at least one fuzz target to compile
#endif
diff --git a/src/test/fuzz/eval_script.cpp b/src/test/fuzz/eval_script.cpp
index 9444cd489e..7acdd76857 100644
--- a/src/test/fuzz/eval_script.cpp
+++ b/src/test/fuzz/eval_script.cpp
@@ -2,12 +2,19 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <pubkey.h>
#include <script/interpreter.h>
-#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <util/memory.h>
#include <limits>
+void initialize()
+{
+ static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
+}
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/parse_iso8601.cpp b/src/test/fuzz/parse_iso8601.cpp
new file mode 100644
index 0000000000..c86f8a853e
--- /dev/null
+++ b/src/test/fuzz/parse_iso8601.cpp
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <util/time.h>
+
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ const int64_t random_time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const std::string random_string = fuzzed_data_provider.ConsumeRemainingBytesAsString();
+
+ const std::string iso8601_datetime = FormatISO8601DateTime(random_time);
+ const int64_t parsed_time_1 = ParseISO8601DateTime(iso8601_datetime);
+ if (random_time >= 0) {
+ assert(parsed_time_1 >= 0);
+ if (iso8601_datetime.length() == 20) {
+ assert(parsed_time_1 == random_time);
+ }
+ }
+
+ const int64_t parsed_time_2 = ParseISO8601DateTime(random_string);
+ assert(parsed_time_2 >= 0);
+}
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
new file mode 100644
index 0000000000..1ce28f9a6d
--- /dev/null
+++ b/src/test/fuzz/psbt.cpp
@@ -0,0 +1,79 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <test/fuzz/fuzz.h>
+
+#include <node/psbt.h>
+#include <optional.h>
+#include <psbt.h>
+#include <pubkey.h>
+#include <script/script.h>
+#include <streams.h>
+#include <util/memory.h>
+#include <version.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ PartiallySignedTransaction psbt_mut;
+ const std::string raw_psbt{buffer.begin(), buffer.end()};
+ std::string error;
+ if (!DecodeRawPSBT(psbt_mut, raw_psbt, error)) {
+ return;
+ }
+ const PartiallySignedTransaction psbt = psbt_mut;
+
+ const PSBTAnalysis analysis = AnalyzePSBT(psbt);
+ (void)PSBTRoleName(analysis.next);
+ for (const PSBTInputAnalysis& input_analysis : analysis.inputs) {
+ (void)PSBTRoleName(input_analysis.next);
+ }
+
+ (void)psbt.IsNull();
+ (void)psbt.IsSane();
+
+ Optional<CMutableTransaction> tx = psbt.tx;
+ if (tx) {
+ const CMutableTransaction& mtx = *tx;
+ const PartiallySignedTransaction psbt_from_tx{mtx};
+ }
+
+ for (const PSBTInput& input : psbt.inputs) {
+ (void)PSBTInputSigned(input);
+ (void)input.IsNull();
+ (void)input.IsSane();
+ }
+
+ for (const PSBTOutput& output : psbt.outputs) {
+ (void)output.IsNull();
+ }
+
+ for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
+ CTxOut tx_out;
+ if (psbt.GetInputUTXO(tx_out, i)) {
+ (void)tx_out.IsNull();
+ (void)tx_out.ToString();
+ }
+ }
+
+ psbt_mut = psbt;
+ (void)FinalizePSBT(psbt_mut);
+
+ psbt_mut = psbt;
+ CMutableTransaction result;
+ if (FinalizeAndExtractPSBT(psbt_mut, result)) {
+ const PartiallySignedTransaction psbt_from_tx{result};
+ }
+
+ psbt_mut = psbt;
+ (void)psbt_mut.Merge(psbt);
+}
diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp
index 0bf5cd5c72..08622d0979 100644
--- a/src/test/fuzz/script_flags.cpp
+++ b/src/test/fuzz/script_flags.cpp
@@ -2,8 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <pubkey.h>
#include <script/interpreter.h>
#include <streams.h>
+#include <util/memory.h>
#include <version.h>
#include <test/fuzz/fuzz.h>
@@ -11,6 +13,11 @@
/** Flags that are not forbidden by an assert */
static bool IsValidFlagCombination(unsigned flags);
+void initialize()
+{
+ static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
+}
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 383d879040..fefafda36b 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -26,23 +26,35 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
- bool valid = true;
+ bool valid_tx = true;
const CTransaction tx = [&] {
try {
return CTransaction(deserialize, ds);
- } catch (const std::ios_base::failure& e) {
- valid = false;
+ } catch (const std::ios_base::failure&) {
+ valid_tx = false;
return CTransaction();
}
}();
- if (!valid) {
+ bool valid_mutable_tx = true;
+ CDataStream ds_mtx(buffer, SER_NETWORK, INIT_PROTO_VERSION);
+ CMutableTransaction mutable_tx;
+ try {
+ int nVersion;
+ ds_mtx >> nVersion;
+ ds_mtx.SetVersion(nVersion);
+ ds_mtx >> mutable_tx;
+ } catch (const std::ios_base::failure&) {
+ valid_mutable_tx = false;
+ }
+ assert(valid_tx == valid_mutable_tx);
+ if (!valid_tx) {
return;
}
- CValidationState state_with_dupe_check;
+ TxValidationState state_with_dupe_check;
(void)CheckTransaction(tx, state_with_dupe_check);
const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE};