Changeset View
Changeset View
Standalone View
Standalone View
src/test/fuzz/util.h
// Copyright (c) 2009-2019 The Bitcoin Core developers | // Copyright (c) 2009-2019 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_TEST_FUZZ_UTIL_H | #ifndef BITCOIN_TEST_FUZZ_UTIL_H | ||||
#define BITCOIN_TEST_FUZZ_UTIL_H | #define BITCOIN_TEST_FUZZ_UTIL_H | ||||
#include <amount.h> | #include <amount.h> | ||||
#include <arith_uint256.h> | #include <arith_uint256.h> | ||||
#include <attributes.h> | #include <attributes.h> | ||||
#include <coins.h> | #include <coins.h> | ||||
#include <script/script.h> | #include <script/script.h> | ||||
#include <script/standard.h> | |||||
#include <serialize.h> | #include <serialize.h> | ||||
#include <streams.h> | #include <streams.h> | ||||
#include <uint256.h> | #include <uint256.h> | ||||
#include <version.h> | #include <version.h> | ||||
#include <test/fuzz/FuzzedDataProvider.h> | #include <test/fuzz/FuzzedDataProvider.h> | ||||
#include <test/fuzz/fuzz.h> | #include <test/fuzz/fuzz.h> | ||||
#include <algorithm> | |||||
#include <cstdint> | #include <cstdint> | ||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
namespace fuzzer { | |||||
// FIXME find a better way to avoid duplicating the MAX_MONEY definition | |||||
constexpr int64_t MAX_MONEY_AS_INT = int64_t(21000000) * int64_t(100000000); | |||||
} // end namespace fuzzer | |||||
using namespace fuzzer; | |||||
NODISCARD inline std::vector<uint8_t> | NODISCARD inline std::vector<uint8_t> | ||||
ConsumeRandomLengthByteVector(FuzzedDataProvider &fuzzed_data_provider, | ConsumeRandomLengthByteVector(FuzzedDataProvider &fuzzed_data_provider, | ||||
const size_t max_length = 4096) noexcept { | const size_t max_length = 4096) noexcept { | ||||
const std::string s = | const std::string s = | ||||
fuzzed_data_provider.ConsumeRandomLengthString(max_length); | fuzzed_data_provider.ConsumeRandomLengthString(max_length); | ||||
return {s.begin(), s.end()}; | return {s.begin(), s.end()}; | ||||
} | } | ||||
NODISCARD inline CDataStream | |||||
ConsumeDataStream(FuzzedDataProvider &fuzzed_data_provider, | |||||
const size_t max_length = 4096) noexcept { | |||||
return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), | |||||
SER_NETWORK, INIT_PROTO_VERSION}; | |||||
} | |||||
NODISCARD inline std::vector<std::string> | NODISCARD inline std::vector<std::string> | ||||
ConsumeRandomLengthStringVector(FuzzedDataProvider &fuzzed_data_provider, | ConsumeRandomLengthStringVector(FuzzedDataProvider &fuzzed_data_provider, | ||||
const size_t max_vector_size = 16, | const size_t max_vector_size = 16, | ||||
const size_t max_string_length = 16) noexcept { | const size_t max_string_length = 16) noexcept { | ||||
const size_t n_elements = | const size_t n_elements = | ||||
fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size); | fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size); | ||||
std::vector<std::string> r; | std::vector<std::string> r; | ||||
for (size_t i = 0; i < n_elements; ++i) { | for (size_t i = 0; i < n_elements; ++i) { | ||||
Show All 35 Lines | |||||
NODISCARD inline opcodetype | NODISCARD inline opcodetype | ||||
ConsumeOpcodeType(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeOpcodeType(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
return static_cast<opcodetype>( | return static_cast<opcodetype>( | ||||
fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE)); | fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE)); | ||||
} | } | ||||
NODISCARD inline Amount | NODISCARD inline Amount | ||||
ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
// FIXME find a better way to avoid duplicating the MAX_MONEY definition | return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>( | ||||
int64_t maxMoneyAsInt = int64_t(21000000) * int64_t(100000000); | 0, MAX_MONEY_AS_INT) * | ||||
return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, | |||||
maxMoneyAsInt) * | |||||
SATOSHI; | SATOSHI; | ||||
} | } | ||||
NODISCARD inline CScript | NODISCARD inline CScript | ||||
ConsumeScript(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeScript(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
const std::vector<uint8_t> b = | const std::vector<uint8_t> b = | ||||
ConsumeRandomLengthByteVector(fuzzed_data_provider); | ConsumeRandomLengthByteVector(fuzzed_data_provider); | ||||
return {b.begin(), b.end()}; | return {b.begin(), b.end()}; | ||||
} | } | ||||
NODISCARD inline CScriptNum | NODISCARD inline CScriptNum | ||||
ConsumeScriptNum(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeScriptNum(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; | return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; | ||||
} | } | ||||
NODISCARD inline uint160 | |||||
ConsumeUInt160(FuzzedDataProvider &fuzzed_data_provider) noexcept { | |||||
const std::vector<uint8_t> v160 = | |||||
fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8); | |||||
if (v160.size() != 160 / 8) { | |||||
return {}; | |||||
} | |||||
return uint160{v160}; | |||||
} | |||||
NODISCARD inline uint256 | NODISCARD inline uint256 | ||||
ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
const std::vector<uint8_t> v256 = | const std::vector<uint8_t> v256 = | ||||
fuzzed_data_provider.ConsumeBytes<uint8_t>(sizeof(uint256)); | fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8); | ||||
if (v256.size() != sizeof(uint256)) { | if (v256.size() != 256 / 8) { | ||||
return {}; | return {}; | ||||
} | } | ||||
return uint256{v256}; | return uint256{v256}; | ||||
} | } | ||||
NODISCARD inline arith_uint256 | NODISCARD inline arith_uint256 | ||||
ConsumeArithUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ConsumeArithUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept { | ||||
return UintToArith256(ConsumeUInt256(fuzzed_data_provider)); | return UintToArith256(ConsumeUInt256(fuzzed_data_provider)); | ||||
} | } | ||||
NODISCARD inline CTxDestination | |||||
ConsumeTxDestination(FuzzedDataProvider &fuzzed_data_provider) noexcept { | |||||
CTxDestination tx_destination; | |||||
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 3)) { | |||||
case 0: { | |||||
tx_destination = CNoDestination{}; | |||||
break; | |||||
} | |||||
case 1: { | |||||
tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)}; | |||||
break; | |||||
} | |||||
case 2: { | |||||
tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)}; | |||||
break; | |||||
} | |||||
} | |||||
return tx_destination; | |||||
} | |||||
template <typename T> | template <typename T> | ||||
NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept { | NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept { | ||||
static_assert(std::is_integral<T>::value, "Integral required."); | static_assert(std::is_integral<T>::value, "Integral required."); | ||||
if (std::numeric_limits<T>::is_signed) { | if (std::numeric_limits<T>::is_signed) { | ||||
if (i > 0) { | if (i > 0) { | ||||
if (j > 0) { | if (j > 0) { | ||||
return i > (std::numeric_limits<T>::max() / j); | return i > (std::numeric_limits<T>::max() / j); | ||||
} else { | } else { | ||||
Show All 37 Lines |