Merge #19143: tests: Add fuzzing harnesses for CAutoFile, CBufferedFile, LoadExternalBlockFile and other FILE* consumers

ad6c34881d tests: Add fuzzing harness for CBlockPolicyEstimator::{Read,Write} (policy/fees.h) (practicalswift)
614e0807a8 tests: Add fuzzing harness for CBufferedFile::{SetPos,GetPos,GetType,GetVersion} (stream.h) (practicalswift)
7bcc71e5f8 tests: Add fuzzing harness for LoadExternalBlockFile(...) (validation.h) (practicalswift)
9823376030 tests: Add fuzzing harness for CBufferedFile (streams.h) (practicalswift)
f3aa659be6 tests: Add fuzzing harness for CAutoFile (streams.h) (practicalswift)
e507c0799d tests: Add serialization/deserialization fuzzing helpers WriteToStream(…)/ReadFromStream(…) (practicalswift)
e48094a506 tests: Add FuzzedAutoFileProvider which provides a CAutoFile interface to FuzzedDataProvider (practicalswift)
9dbcd6854c tests: Add FuzzedFileProvider which provides a FILE* interface to FuzzedDataProvider using fopencookie (practicalswift)

Pull request description:

  Add fuzzing harnesses for `CAutoFile`, `CBufferedFile`, `LoadExternalBlockFile` and other `FILE*` consumers:
  * Add `FuzzedFileProvider` which provides a `FILE*` interface to `FuzzedDataProvider` using `fopencookie`
  * Add `FuzzedAutoFileProvider` which provides a `CAutoFile` interface to `FuzzedDataProvider`
  * Add serialization/deserialization fuzzing helpers `WriteToStream(…)`/`ReadFromStream(…)`
  * Add fuzzing harness for `CAutoFile` (`streams.h`)
  * Add fuzzing harness for `CBufferedFile` (`streams.h`)
  * Add fuzzing harness for `LoadExternalBlockFile(...)` (`validation.h`)
  * Add fuzzing harness for `CBlockPolicyEstimator::Read` and `CBlockPolicyEstimator::Write` (`policy/fees.h`)

  See [`doc/fuzzing.md`](https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md) for information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the [Bitcoin Core fuzzing corpus repo](https://github.com/bitcoin-core/qa-assets).

  Happy fuzzing :)

ACKs for top commit:
  Crypt-iQ:
    Tested ACK ad6c348

Tree-SHA512: a38e142608218496796a527d7e59b74e30279a2815450408b7c27a76ed600cebc6b88491e831665a0639671e2d212453fcdca558500bbadbeb32b267751f8f72
This commit is contained in:
MarcoFalke 2020-07-18 09:00:39 +02:00
commit 090d877160
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
7 changed files with 454 additions and 0 deletions

View file

@ -10,6 +10,7 @@ FUZZ_TARGETS = \
test/fuzz/addrman_deserialize \
test/fuzz/asmap \
test/fuzz/asmap_direct \
test/fuzz/autofile \
test/fuzz/banentry_deserialize \
test/fuzz/banman \
test/fuzz/base_encode_decode \
@ -29,6 +30,7 @@ FUZZ_TARGETS = \
test/fuzz/blockundo_deserialize \
test/fuzz/bloom_filter \
test/fuzz/bloomfilter_deserialize \
test/fuzz/buffered_file \
test/fuzz/chain \
test/fuzz/checkqueue \
test/fuzz/coins_deserialize \
@ -61,6 +63,7 @@ FUZZ_TARGETS = \
test/fuzz/key_io \
test/fuzz/key_origin_info_deserialize \
test/fuzz/kitchen_sink \
test/fuzz/load_external_block_file \
test/fuzz/locale \
test/fuzz/merkle_block_deserialize \
test/fuzz/merkleblock \
@ -80,6 +83,7 @@ FUZZ_TARGETS = \
test/fuzz/partial_merkle_tree_deserialize \
test/fuzz/partially_signed_transaction_deserialize \
test/fuzz/policy_estimator \
test/fuzz/policy_estimator_io \
test/fuzz/pow \
test/fuzz/prefilled_transaction_deserialize \
test/fuzz/prevector \
@ -356,6 +360,12 @@ test_fuzz_asmap_direct_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_asmap_direct_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_asmap_direct_SOURCES = test/fuzz/asmap_direct.cpp
test_fuzz_autofile_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_autofile_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_autofile_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_autofile_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_autofile_SOURCES = test/fuzz/autofile.cpp
test_fuzz_banentry_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBANENTRY_DESERIALIZE=1
test_fuzz_banentry_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_banentry_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
@ -470,6 +480,12 @@ test_fuzz_bloomfilter_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_bloomfilter_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_bloomfilter_deserialize_SOURCES = test/fuzz/deserialize.cpp
test_fuzz_buffered_file_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_buffered_file_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_buffered_file_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_buffered_file_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_buffered_file_SOURCES = test/fuzz/buffered_file.cpp
test_fuzz_chain_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_chain_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_chain_LDADD = $(FUZZ_SUITE_LD_COMMON)
@ -662,6 +678,12 @@ test_fuzz_kitchen_sink_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_kitchen_sink_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_kitchen_sink_SOURCES = test/fuzz/kitchen_sink.cpp
test_fuzz_load_external_block_file_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_load_external_block_file_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_load_external_block_file_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_load_external_block_file_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_load_external_block_file_SOURCES = test/fuzz/load_external_block_file.cpp
test_fuzz_locale_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_locale_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_locale_LDADD = $(FUZZ_SUITE_LD_COMMON)
@ -782,6 +804,12 @@ test_fuzz_policy_estimator_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_policy_estimator_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_policy_estimator_SOURCES = test/fuzz/policy_estimator.cpp
test_fuzz_policy_estimator_io_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_policy_estimator_io_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_policy_estimator_io_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_policy_estimator_io_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_policy_estimator_io_SOURCES = test/fuzz/policy_estimator_io.cpp
test_fuzz_pow_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_pow_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_pow_LDADD = $(FUZZ_SUITE_LD_COMMON)

View file

@ -0,0 +1,72 @@
// Copyright (c) 2020 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 <optional.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <array>
#include <cstdint>
#include <iostream>
#include <optional>
#include <string>
#include <vector>
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
CAutoFile auto_file = fuzzed_auto_file_provider.open();
while (fuzzed_data_provider.ConsumeBool()) {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
case 0: {
std::array<uint8_t, 4096> arr{};
try {
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
} catch (const std::ios_base::failure&) {
}
break;
}
case 1: {
const std::array<uint8_t, 4096> arr{};
try {
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
} catch (const std::ios_base::failure&) {
}
break;
}
case 2: {
try {
auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
} catch (const std::ios_base::failure&) {
}
break;
}
case 3: {
auto_file.fclose();
break;
}
case 4: {
ReadFromStream(fuzzed_data_provider, auto_file);
break;
}
case 5: {
WriteToStream(fuzzed_data_provider, auto_file);
break;
}
}
}
(void)auto_file.Get();
(void)auto_file.GetType();
(void)auto_file.GetVersion();
(void)auto_file.IsNull();
if (fuzzed_data_provider.ConsumeBool()) {
FILE* f = auto_file.release();
if (f != nullptr) {
fclose(f);
}
}
}

View file

@ -0,0 +1,78 @@
// Copyright (c) 2020 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 <optional.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <array>
#include <cstdint>
#include <iostream>
#include <optional>
#include <string>
#include <vector>
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
std::optional<CBufferedFile> opt_buffered_file;
FILE* fuzzed_file = fuzzed_file_provider.open();
try {
opt_buffered_file.emplace(fuzzed_file, fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeIntegral<int>());
} catch (const std::ios_base::failure&) {
if (fuzzed_file != nullptr) {
fclose(fuzzed_file);
}
}
if (opt_buffered_file && fuzzed_file != nullptr) {
bool setpos_fail = false;
while (fuzzed_data_provider.ConsumeBool()) {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
case 0: {
std::array<uint8_t, 4096> arr{};
try {
opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
} catch (const std::ios_base::failure&) {
}
break;
}
case 1: {
opt_buffered_file->Seek(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
break;
}
case 2: {
opt_buffered_file->SetLimit(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
break;
}
case 3: {
if (!opt_buffered_file->SetPos(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096))) {
setpos_fail = true;
}
break;
}
case 4: {
if (setpos_fail) {
// Calling FindByte(...) after a failed SetPos(...) call may result in an infinite loop.
break;
}
try {
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>());
} catch (const std::ios_base::failure&) {
}
break;
}
case 5: {
ReadFromStream(fuzzed_data_provider, *opt_buffered_file);
break;
}
}
}
opt_buffered_file->GetPos();
opt_buffered_file->GetType();
opt_buffered_file->GetVersion();
}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2020 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 <chainparams.h>
#include <flatfile.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <validation.h>
#include <cstdint>
#include <vector>
void initialize()
{
InitializeFuzzingContext();
}
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
FILE* fuzzed_block_file = fuzzed_file_provider.open();
if (fuzzed_block_file == nullptr) {
return;
}
FlatFilePos flat_file_pos;
LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
}

View file

@ -14,6 +14,11 @@
#include <string>
#include <vector>
void initialize()
{
InitializeFuzzingContext();
}
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@ -66,4 +71,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)block_policy_estimator.estimateSmartFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr, fuzzed_data_provider.ConsumeBool());
(void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}));
}
{
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
block_policy_estimator.Write(fuzzed_auto_file);
block_policy_estimator.Read(fuzzed_auto_file);
}
}

View file

@ -0,0 +1,28 @@
// Copyright (c) 2020 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 <policy/fees.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <cstdint>
#include <vector>
void initialize()
{
InitializeFuzzingContext();
}
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
// Re-using block_policy_estimator across runs to avoid costly creation of CBlockPolicyEstimator object.
static CBlockPolicyEstimator block_policy_estimator;
if (block_policy_estimator.Read(fuzzed_auto_file)) {
block_policy_estimator.Write(fuzzed_auto_file);
}
}

View file

@ -27,6 +27,7 @@
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <optional>
#include <string>
#include <vector>
@ -264,4 +265,209 @@ void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::
static const BasicTestingSetup basic_testing_setup{chain_name, {"-nodebuglogfile"}};
}
class FuzzedFileProvider
{
FuzzedDataProvider& m_fuzzed_data_provider;
int64_t m_offset = 0;
public:
FuzzedFileProvider(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}
{
}
FILE* open()
{
if (m_fuzzed_data_provider.ConsumeBool()) {
return nullptr;
}
std::string mode;
switch (m_fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
case 0: {
mode = "r";
break;
}
case 1: {
mode = "r+";
break;
}
case 2: {
mode = "w";
break;
}
case 3: {
mode = "w+";
break;
}
case 4: {
mode = "a";
break;
}
case 5: {
mode = "a+";
break;
}
}
#ifdef _GNU_SOURCE
const cookie_io_functions_t io_hooks = {
FuzzedFileProvider::read,
FuzzedFileProvider::write,
FuzzedFileProvider::seek,
FuzzedFileProvider::close,
};
return fopencookie(this, mode.c_str(), io_hooks);
#else
(void)mode;
return nullptr;
#endif
}
static ssize_t read(void* cookie, char* buf, size_t size)
{
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider.ConsumeBool()) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
}
const std::vector<uint8_t> random_bytes = fuzzed_file->m_fuzzed_data_provider.ConsumeBytes<uint8_t>(size);
if (random_bytes.empty()) {
return 0;
}
std::memcpy(buf, random_bytes.data(), random_bytes.size());
if (AdditionOverflow((uint64_t)fuzzed_file->m_offset, random_bytes.size())) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
}
fuzzed_file->m_offset += random_bytes.size();
return random_bytes.size();
}
static ssize_t write(void* cookie, const char* buf, size_t size)
{
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
if (AdditionOverflow(fuzzed_file->m_offset, n)) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
}
fuzzed_file->m_offset += n;
return n;
}
static int seek(void* cookie, int64_t* offset, int whence)
{
assert(whence == SEEK_SET || whence == SEEK_CUR); // SEEK_END not implemented yet.
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
int64_t new_offset = 0;
if (whence == SEEK_SET) {
new_offset = *offset;
} else if (whence == SEEK_CUR) {
if (AdditionOverflow(fuzzed_file->m_offset, *offset)) {
return -1;
}
new_offset = fuzzed_file->m_offset + *offset;
}
if (new_offset < 0) {
return -1;
}
fuzzed_file->m_offset = new_offset;
*offset = new_offset;
return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
}
static int close(void* cookie)
{
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
}
};
NODISCARD inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {fuzzed_data_provider};
}
class FuzzedAutoFileProvider
{
FuzzedDataProvider& m_fuzzed_data_provider;
FuzzedFileProvider m_fuzzed_file_provider;
public:
FuzzedAutoFileProvider(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}, m_fuzzed_file_provider{fuzzed_data_provider}
{
}
CAutoFile open()
{
return {m_fuzzed_file_provider.open(), m_fuzzed_data_provider.ConsumeIntegral<int>(), m_fuzzed_data_provider.ConsumeIntegral<int>()};
}
};
NODISCARD inline FuzzedAutoFileProvider ConsumeAutoFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {fuzzed_data_provider};
}
#define WRITE_TO_STREAM_CASE(id, type, consume) \
case id: { \
type o = consume; \
stream << o; \
break; \
}
template <typename Stream>
void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noexcept
{
while (fuzzed_data_provider.ConsumeBool()) {
try {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 13)) {
WRITE_TO_STREAM_CASE(0, bool, fuzzed_data_provider.ConsumeBool())
WRITE_TO_STREAM_CASE(1, char, fuzzed_data_provider.ConsumeIntegral<char>())
WRITE_TO_STREAM_CASE(2, int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>())
WRITE_TO_STREAM_CASE(3, uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>())
WRITE_TO_STREAM_CASE(4, int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>())
WRITE_TO_STREAM_CASE(5, uint16_t, fuzzed_data_provider.ConsumeIntegral<uint16_t>())
WRITE_TO_STREAM_CASE(6, int32_t, fuzzed_data_provider.ConsumeIntegral<int32_t>())
WRITE_TO_STREAM_CASE(7, uint32_t, fuzzed_data_provider.ConsumeIntegral<uint32_t>())
WRITE_TO_STREAM_CASE(8, int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>())
WRITE_TO_STREAM_CASE(9, uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>())
WRITE_TO_STREAM_CASE(10, float, fuzzed_data_provider.ConsumeFloatingPoint<float>())
WRITE_TO_STREAM_CASE(11, double, fuzzed_data_provider.ConsumeFloatingPoint<double>())
WRITE_TO_STREAM_CASE(12, std::string, fuzzed_data_provider.ConsumeRandomLengthString(32))
WRITE_TO_STREAM_CASE(13, std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))
}
} catch (const std::ios_base::failure&) {
break;
}
}
}
#define READ_FROM_STREAM_CASE(id, type) \
case id: { \
type o; \
stream >> o; \
break; \
}
template <typename Stream>
void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noexcept
{
while (fuzzed_data_provider.ConsumeBool()) {
try {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 13)) {
READ_FROM_STREAM_CASE(0, bool)
READ_FROM_STREAM_CASE(1, char)
READ_FROM_STREAM_CASE(2, int8_t)
READ_FROM_STREAM_CASE(3, uint8_t)
READ_FROM_STREAM_CASE(4, int16_t)
READ_FROM_STREAM_CASE(5, uint16_t)
READ_FROM_STREAM_CASE(6, int32_t)
READ_FROM_STREAM_CASE(7, uint32_t)
READ_FROM_STREAM_CASE(8, int64_t)
READ_FROM_STREAM_CASE(9, uint64_t)
READ_FROM_STREAM_CASE(10, float)
READ_FROM_STREAM_CASE(11, double)
READ_FROM_STREAM_CASE(12, std::string)
READ_FROM_STREAM_CASE(13, std::vector<char>)
}
} catch (const std::ios_base::failure&) {
break;
}
}
}
#endif // BITCOIN_TEST_FUZZ_UTIL_H