aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz/deserialize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz/deserialize.cpp')
-rw-r--r--src/test/fuzz/deserialize.cpp270
1 files changed, 163 insertions, 107 deletions
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index bcd8691359..bd05283b78 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -5,18 +5,25 @@
#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 <exception>
+#include <stdexcept>
#include <stdint.h>
#include <unistd.h>
@@ -30,137 +37,186 @@ void initialize()
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+namespace {
+
+struct invalid_fuzzing_input_exception : public std::exception {
+};
+
+template <typename T>
+CDataStream Serialize(const T& obj)
+{
+ CDataStream ds(SER_NETWORK, INIT_PROTO_VERSION);
+ ds << obj;
+ return ds;
+}
+
+template <typename T>
+T Deserialize(CDataStream ds)
+{
+ T obj;
+ ds >> obj;
+ return obj;
+}
+
+template <typename T>
+void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
try {
- int nVersion;
- ds >> nVersion;
- ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
- return;
+ int version;
+ ds >> version;
+ ds.SetVersion(version);
+ } catch (const std::ios_base::failure&) {
+ throw invalid_fuzzing_input_exception();
+ }
+ try {
+ ds >> obj;
+ } catch (const std::ios_base::failure&) {
+ throw invalid_fuzzing_input_exception();
}
+ assert(buffer.empty() || !Serialize(obj).empty());
+}
+
+template <typename T>
+void AssertEqualAfterSerializeDeserialize(const T& obj)
+{
+ assert(Deserialize<T>(Serialize(obj)) == obj);
+}
-#if BLOCK_DESERIALIZE
- try
- {
- CBlock block;
- ds >> block;
- } catch (const std::ios_base::failure& e) {return;}
+} // namespace
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ try {
+#if BLOCK_FILTER_DESERIALIZE
+ BlockFilter block_filter;
+ DeserializeFromFuzzingInput(buffer, block_filter);
+#elif ADDR_INFO_DESERIALIZE
+ CAddrInfo addr_info;
+ DeserializeFromFuzzingInput(buffer, addr_info);
+#elif BLOCK_FILE_INFO_DESERIALIZE
+ CBlockFileInfo block_file_info;
+ DeserializeFromFuzzingInput(buffer, block_file_info);
+#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE
+ CBlockHeaderAndShortTxIDs block_header_and_short_txids;
+ DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
+#elif FEE_RATE_DESERIALIZE
+ CFeeRate fee_rate;
+ DeserializeFromFuzzingInput(buffer, fee_rate);
+ AssertEqualAfterSerializeDeserialize(fee_rate);
+#elif MERKLE_BLOCK_DESERIALIZE
+ CMerkleBlock merkle_block;
+ DeserializeFromFuzzingInput(buffer, merkle_block);
+#elif OUT_POINT_DESERIALIZE
+ COutPoint out_point;
+ DeserializeFromFuzzingInput(buffer, out_point);
+ AssertEqualAfterSerializeDeserialize(out_point);
+#elif PARTIAL_MERKLE_TREE_DESERIALIZE
+ CPartialMerkleTree partial_merkle_tree;
+ DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
+#elif PUB_KEY_DESERIALIZE
+ CPubKey pub_key;
+ DeserializeFromFuzzingInput(buffer, pub_key);
+ // TODO: The following equivalence should hold for CPubKey? Fix.
+ // AssertEqualAfterSerializeDeserialize(pub_key);
+#elif SCRIPT_DESERIALIZE
+ CScript script;
+ DeserializeFromFuzzingInput(buffer, script);
+#elif SUB_NET_DESERIALIZE
+ CSubNet sub_net;
+ DeserializeFromFuzzingInput(buffer, sub_net);
+ AssertEqualAfterSerializeDeserialize(sub_net);
+#elif TX_IN_DESERIALIZE
+ CTxIn tx_in;
+ DeserializeFromFuzzingInput(buffer, tx_in);
+ AssertEqualAfterSerializeDeserialize(tx_in);
+#elif FLAT_FILE_POS_DESERIALIZE
+ FlatFilePos flat_file_pos;
+ DeserializeFromFuzzingInput(buffer, flat_file_pos);
+ AssertEqualAfterSerializeDeserialize(flat_file_pos);
+#elif KEY_ORIGIN_INFO_DESERIALIZE
+ KeyOriginInfo key_origin_info;
+ DeserializeFromFuzzingInput(buffer, key_origin_info);
+ AssertEqualAfterSerializeDeserialize(key_origin_info);
+#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE
+ PartiallySignedTransaction partially_signed_transaction;
+ DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
+#elif PREFILLED_TRANSACTION_DESERIALIZE
+ PrefilledTransaction prefilled_transaction;
+ DeserializeFromFuzzingInput(buffer, prefilled_transaction);
+#elif PSBT_INPUT_DESERIALIZE
+ PSBTInput psbt_input;
+ DeserializeFromFuzzingInput(buffer, psbt_input);
+#elif PSBT_OUTPUT_DESERIALIZE
+ PSBTOutput psbt_output;
+ DeserializeFromFuzzingInput(buffer, psbt_output);
+#elif BLOCK_DESERIALIZE
+ CBlock block;
+ DeserializeFromFuzzingInput(buffer, block);
#elif BLOCKLOCATOR_DESERIALIZE
- try
- {
- CBlockLocator bl;
- ds >> bl;
- } catch (const std::ios_base::failure& e) {return;}
+ CBlockLocator bl;
+ DeserializeFromFuzzingInput(buffer, bl);
#elif BLOCKMERKLEROOT
- try
- {
- CBlock block;
- ds >> block;
- bool mutated;
- BlockMerkleRoot(block, &mutated);
- } catch (const std::ios_base::failure& e) {return;}
+ CBlock block;
+ DeserializeFromFuzzingInput(buffer, block);
+ bool mutated;
+ BlockMerkleRoot(block, &mutated);
#elif ADDRMAN_DESERIALIZE
- try
- {
- CAddrMan am;
- ds >> am;
- } catch (const std::ios_base::failure& e) {return;}
+ CAddrMan am;
+ DeserializeFromFuzzingInput(buffer, am);
#elif BLOCKHEADER_DESERIALIZE
- try
- {
- CBlockHeader bh;
- ds >> bh;
- } catch (const std::ios_base::failure& e) {return;}
+ CBlockHeader bh;
+ DeserializeFromFuzzingInput(buffer, bh);
#elif BANENTRY_DESERIALIZE
- try
- {
- CBanEntry be;
- ds >> be;
- } catch (const std::ios_base::failure& e) {return;}
+ CBanEntry be;
+ DeserializeFromFuzzingInput(buffer, be);
#elif TXUNDO_DESERIALIZE
- try
- {
- CTxUndo tu;
- ds >> tu;
- } catch (const std::ios_base::failure& e) {return;}
+ CTxUndo tu;
+ DeserializeFromFuzzingInput(buffer, tu);
#elif BLOCKUNDO_DESERIALIZE
- try
- {
- CBlockUndo bu;
- ds >> bu;
- } catch (const std::ios_base::failure& e) {return;}
+ CBlockUndo bu;
+ DeserializeFromFuzzingInput(buffer, bu);
#elif COINS_DESERIALIZE
- try
- {
- Coin coin;
- ds >> coin;
- } catch (const std::ios_base::failure& e) {return;}
+ Coin coin;
+ DeserializeFromFuzzingInput(buffer, coin);
#elif NETADDR_DESERIALIZE
- try
- {
- CNetAddr na;
- ds >> na;
- } catch (const std::ios_base::failure& e) {return;}
+ CNetAddr na;
+ DeserializeFromFuzzingInput(buffer, na);
+ AssertEqualAfterSerializeDeserialize(na);
#elif SERVICE_DESERIALIZE
- try
- {
- CService s;
- ds >> s;
- } catch (const std::ios_base::failure& e) {return;}
+ CService s;
+ DeserializeFromFuzzingInput(buffer, s);
+ AssertEqualAfterSerializeDeserialize(s);
#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;}
+ const CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
+ CMessageHeader mh(pchMessageStart);
+ DeserializeFromFuzzingInput(buffer, mh);
+ (void)mh.IsValid(pchMessageStart);
#elif ADDRESS_DESERIALIZE
- try
- {
- CAddress a;
- ds >> a;
- } catch (const std::ios_base::failure& e) {return;}
+ CAddress a;
+ DeserializeFromFuzzingInput(buffer, a);
#elif INV_DESERIALIZE
- try
- {
- CInv i;
- ds >> i;
- } catch (const std::ios_base::failure& e) {return;}
+ CInv i;
+ DeserializeFromFuzzingInput(buffer, i);
#elif BLOOMFILTER_DESERIALIZE
- try
- {
- CBloomFilter bf;
- ds >> bf;
- } catch (const std::ios_base::failure& e) {return;}
+ CBloomFilter bf;
+ DeserializeFromFuzzingInput(buffer, bf);
#elif DISKBLOCKINDEX_DESERIALIZE
- try
- {
- CDiskBlockIndex dbi;
- ds >> dbi;
- } catch (const std::ios_base::failure& e) {return;}
+ CDiskBlockIndex dbi;
+ DeserializeFromFuzzingInput(buffer, dbi);
#elif TXOUTCOMPRESSOR_DESERIALIZE
- CTxOut to;
- CTxOutCompressor toc(to);
- try
- {
- ds >> toc;
- } catch (const std::ios_base::failure& e) {return;}
+ CTxOut to;
+ CTxOutCompressor toc(to);
+ DeserializeFromFuzzingInput(buffer, toc);
#elif BLOCKTRANSACTIONS_DESERIALIZE
- try
- {
- BlockTransactions bt;
- ds >> bt;
- } catch (const std::ios_base::failure& e) {return;}
+ BlockTransactions bt;
+ DeserializeFromFuzzingInput(buffer, bt);
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
- try
- {
- BlockTransactionsRequest btr;
- ds >> btr;
- } catch (const std::ios_base::failure& e) {return;}
+ BlockTransactionsRequest btr;
+ DeserializeFromFuzzingInput(buffer, btr);
#else
#error Need at least one fuzz target to compile
#endif
+ } catch (const invalid_fuzzing_input_exception&) {
+ }
}