<commit_before>// Copyright (c) 2009-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 <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>

#include <vector>

#include <test/fuzz/fuzz.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    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);
    try {
        int nVersion;
        ds >> nVersion;
        ds.SetVersion(nVersion);
    } catch (const std::ios_base::failure&) {
        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&) {
    }
#elif BLOCKMERKLEROOT
    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&) {
    }
#elif BLOCKHEADER_DESERIALIZE
    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&) {
    }
#elif TXUNDO_DESERIALIZE
    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&) {
    }
#elif COINS_DESERIALIZE
    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&) {
    }
#elif SERVICE_DESERIALIZE
    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;
        (void)mh.IsValid(pchMessageStart);
    } catch (const std::ios_base::failure&) {
    }
#elif ADDRESS_DESERIALIZE
    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&) {
    }
#elif BLOOMFILTER_DESERIALIZE
    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&) {
    }
#elif TXOUTCOMPRESSOR_DESERIALIZE
    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&) {
    }
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
    try {
        BlockTransactionsRequest btr;
        ds >> btr;
    } catch (const std::ios_base::failure&) {
    }
#else
#error Need at least one fuzz target to compile
#endif
}<commit_msg>tests: Test serialisation as part of deserialisation fuzzing. Test round-trip equality where possible. Avoid code repetition.<commit_after>// Copyright (c) 2009-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 <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>

#include <vector>

#include <test/fuzz/fuzz.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
}

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 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);
}

} // 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
        CBlockLocator bl;
        DeserializeFromFuzzingInput(buffer, bl);
#elif BLOCKMERKLEROOT
        CBlock block;
        DeserializeFromFuzzingInput(buffer, block);
        bool mutated;
        BlockMerkleRoot(block, &mutated);
#elif ADDRMAN_DESERIALIZE
        CAddrMan am;
        DeserializeFromFuzzingInput(buffer, am);
#elif BLOCKHEADER_DESERIALIZE
        CBlockHeader bh;
        DeserializeFromFuzzingInput(buffer, bh);
#elif BANENTRY_DESERIALIZE
        CBanEntry be;
        DeserializeFromFuzzingInput(buffer, be);
#elif TXUNDO_DESERIALIZE
        CTxUndo tu;
        DeserializeFromFuzzingInput(buffer, tu);
#elif BLOCKUNDO_DESERIALIZE
        CBlockUndo bu;
        DeserializeFromFuzzingInput(buffer, bu);
#elif COINS_DESERIALIZE
        Coin coin;
        DeserializeFromFuzzingInput(buffer, coin);
#elif NETADDR_DESERIALIZE
        CNetAddr na;
        DeserializeFromFuzzingInput(buffer, na);
        AssertEqualAfterSerializeDeserialize(na);
#elif SERVICE_DESERIALIZE
        CService s;
        DeserializeFromFuzzingInput(buffer, s);
        AssertEqualAfterSerializeDeserialize(s);
#elif MESSAGEHEADER_DESERIALIZE
        const CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
        CMessageHeader mh(pchMessageStart);
        DeserializeFromFuzzingInput(buffer, mh);
        (void)mh.IsValid(pchMessageStart);
#elif ADDRESS_DESERIALIZE
        CAddress a;
        DeserializeFromFuzzingInput(buffer, a);
#elif INV_DESERIALIZE
        CInv i;
        DeserializeFromFuzzingInput(buffer, i);
#elif BLOOMFILTER_DESERIALIZE
        CBloomFilter bf;
        DeserializeFromFuzzingInput(buffer, bf);
#elif DISKBLOCKINDEX_DESERIALIZE
        CDiskBlockIndex dbi;
        DeserializeFromFuzzingInput(buffer, dbi);
#elif TXOUTCOMPRESSOR_DESERIALIZE
        CTxOut to;
        CTxOutCompressor toc(to);
        DeserializeFromFuzzingInput(buffer, toc);
#elif BLOCKTRANSACTIONS_DESERIALIZE
        BlockTransactions bt;
        DeserializeFromFuzzingInput(buffer, bt);
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
        BlockTransactionsRequest btr;
        DeserializeFromFuzzingInput(buffer, btr);
#else
#error Need at least one fuzz target to compile
#endif
    } catch (const invalid_fuzzing_input_exception&) {
    }
}
{'fraction_non_alphanumeric': 0.09587301587301587, 'fraction_numerical': 0.0030335097001763667, 'mean_word_length': 3.331194622670333, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 0, '>': 144, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5154609', 'n_tokens_mistral': 4915, 'n_tokens_neox': 4725, 'n_words': 943}