Skip to content

Commit

Permalink
tests: Add fuzzing harness for serialization/deserialization of float…
Browse files Browse the repository at this point in the history
…ing-points and integrals

Summary:
```
Add simple fuzzing harness for functions with floating-point parameters
(such as ser_double_to_uint64(double), etc.).

Add serialization/deserialization fuzzing for integral types.
```

Backport of core [[bitcoin/bitcoin#17996 | PR17996]].

The first and last commit are not relevant to us.

Test Plan:
  ninja bitcoin-fuzzers
  ./test/fuzz/test_runner.py <path_to_corpus>

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D8249
  • Loading branch information
practicalswift authored and Fabcien committed Nov 3, 2020
1 parent 5a1a1b1 commit b8598eb
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/test/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ add_regular_fuzz_targets(
cashaddr
descriptor_parse
eval_script
float
hex
integer
net_permissions
Expand Down
42 changes: 42 additions & 0 deletions src/test/fuzz/float.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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 <memusage.h>
#include <serialize.h>
#include <streams.h>
#include <version.h>

#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>

#include <cassert>
#include <cstdint>

void test_one_input(const std::vector<uint8_t> &buffer) {
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

{
const double d = fuzzed_data_provider.ConsumeFloatingPoint<double>();
(void)memusage::DynamicUsage(d);
assert(ser_uint64_to_double(ser_double_to_uint64(d)) == d);

CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);
stream << d;
double d_deserialized;
stream >> d_deserialized;
assert(d == d_deserialized);
}

{
const float f = fuzzed_data_provider.ConsumeFloatingPoint<float>();
(void)memusage::DynamicUsage(f);
assert(ser_uint32_to_float(ser_float_to_uint32(f)) == f);

CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);
stream << f;
float f_deserialized;
stream >> f_deserialized;
assert(f == f_deserialized);
}
}
67 changes: 67 additions & 0 deletions src/test/fuzz/integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
#include <script/signingprovider.h>
#include <script/standard.h>
#include <serialize.h>
#include <streams.h>
#include <uint256.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/time.h>
#include <version.h>

#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
Expand Down Expand Up @@ -57,6 +59,7 @@ void test_one_input(const std::vector<uint8_t> &buffer) {
// We cannot assume a specific value of std::is_signed<char>::value:
// ConsumeIntegral<char>() instead of casting from {u,}int8_t.
const char ch = fuzzed_data_provider.ConsumeIntegral<char>();
const bool b = fuzzed_data_provider.ConsumeBool();

const Consensus::Params &consensus_params = Params().GetConsensus();
(void)CheckProofOfWork(BlockHash(u256), u32, consensus_params);
Expand Down Expand Up @@ -131,4 +134,68 @@ void test_one_input(const std::vector<uint8_t> &buffer) {
(void)GetScriptForDestination(destination);
(void)IsValidDestination(destination);
}

{
CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);

uint256 deserialized_u256;
stream << u256;
stream >> deserialized_u256;
assert(u256 == deserialized_u256 && stream.empty());

uint160 deserialized_u160;
stream << u160;
stream >> deserialized_u160;
assert(u160 == deserialized_u160 && stream.empty());

uint64_t deserialized_u64;
stream << u64;
stream >> deserialized_u64;
assert(u64 == deserialized_u64 && stream.empty());

int64_t deserialized_i64;
stream << i64;
stream >> deserialized_i64;
assert(i64 == deserialized_i64 && stream.empty());

uint32_t deserialized_u32;
stream << u32;
stream >> deserialized_u32;
assert(u32 == deserialized_u32 && stream.empty());

int32_t deserialized_i32;
stream << i32;
stream >> deserialized_i32;
assert(i32 == deserialized_i32 && stream.empty());

uint16_t deserialized_u16;
stream << u16;
stream >> deserialized_u16;
assert(u16 == deserialized_u16 && stream.empty());

int16_t deserialized_i16;
stream << i16;
stream >> deserialized_i16;
assert(i16 == deserialized_i16 && stream.empty());

uint8_t deserialized_u8;
stream << u8;
stream >> deserialized_u8;
assert(u8 == deserialized_u8 && stream.empty());

int8_t deserialized_i8;
stream << i8;
stream >> deserialized_i8;
assert(i8 == deserialized_i8 && stream.empty());

char deserialized_ch;
stream << ch;
stream >> deserialized_ch;
assert(ch == deserialized_ch && stream.empty());

bool deserialized_b;
stream << b;
stream >> deserialized_b;
assert(b == deserialized_b && stream.empty());
}
}

0 comments on commit b8598eb

Please sign in to comment.