Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ BITCOIN_CORE_H = \
util/check.h \
util/error.h \
util/fees.h \
util/golombrice.h \
util/irange.h \
util/spanparsing.h \
util/system.h \
Expand Down
255 changes: 253 additions & 2 deletions src/Makefile.test.include

Large diffs are not rendered by default.

32 changes: 1 addition & 31 deletions src/blockfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <primitives/transaction.h>
#include <script/script.h>
#include <streams.h>
#include <util/golombrice.h>

/// SerType used to serialize parameters in GCS filter encoding.
static constexpr int GCS_SER_TYPE = SER_NETWORK;
Expand All @@ -23,37 +24,6 @@ static const std::map<BlockFilterType, std::string> g_filter_types = {
{BlockFilterType::BASIC_FILTER, "basic"},
};

template <typename OStream>
static void GolombRiceEncode(BitStreamWriter<OStream>& bitwriter, uint8_t P, uint64_t x)
{
// Write quotient as unary-encoded: q 1's followed by one 0.
uint64_t q = x >> P;
while (q > 0) {
int nbits = q <= 64 ? static_cast<int>(q) : 64;
bitwriter.Write(~0ULL, nbits);
q -= nbits;
}
bitwriter.Write(0, 1);

// Write the remainder in P bits. Since the remainder is just the bottom
// P bits of x, there is no need to mask first.
bitwriter.Write(x, P);
}

template <typename IStream>
static uint64_t GolombRiceDecode(BitStreamReader<IStream>& bitreader, uint8_t P)
{
// Read unary-encoded quotient: q 1's followed by one 0.
uint64_t q = 0;
while (bitreader.Read(1) == 1) {
++q;
}

uint64_t r = bitreader.Read(P);

return (q << P) + r;
}

// Map a value x that is uniformly distributed in the range [0, 2^64) to a
// value uniformly distributed in [0, n) by returning the upper 64 bits of
// x * n.
Expand Down
6 changes: 3 additions & 3 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ static bool InitHTTPAllowList()
}

/** HTTP request method as string - use for logging only */
static std::string RequestMethodString(HTTPRequest::RequestMethod m)
std::string RequestMethodString(HTTPRequest::RequestMethod m)
{
switch (m) {
case HTTPRequest::GET:
Expand Down Expand Up @@ -513,10 +513,10 @@ void HTTPEvent::trigger(struct timeval* tv)
else
evtimer_add(ev, tv); // trigger after timeval passed
}
HTTPRequest::HTTPRequest(struct evhttp_request* _req) : req(_req),
replySent(false)
HTTPRequest::HTTPRequest(struct evhttp_request* _req, bool _replySent) : req(_req), replySent(_replySent)
{
}

HTTPRequest::~HTTPRequest()
{
if (!replySent) {
Expand Down
2 changes: 1 addition & 1 deletion src/httpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class HTTPRequest
bool replySent;

public:
explicit HTTPRequest(struct evhttp_request* req);
explicit HTTPRequest(struct evhttp_request* req, bool replySent = false);
~HTTPRequest();

enum RequestMethod {
Expand Down
72 changes: 72 additions & 0 deletions src/test/fuzz/autofile.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
88 changes: 88 additions & 0 deletions src/test/fuzz/banman.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 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 <banman.h>
#include <fs.h>
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <util/system.h>

#include <cstdint>
#include <limits>
#include <string>
#include <vector>

namespace {
int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
// Avoid signed integer overflow by capping to int32_t max:
// banman.cpp:137:73: runtime error: signed integer overflow: 1591700817 + 9223372036854775807 cannot be represented in type 'long'
return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());
}
} // namespace

void initialize()
{
InitializeFuzzingContext();
}

void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat";
fs::remove(banlist_file);
{
BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)};
while (fuzzed_data_provider.ConsumeBool()) {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
case 0: {
ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
break;
}
case 1: {
ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
break;
}
case 2: {
ban_man.ClearBanned();
break;
}
case 4: {
ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
break;
}
case 5: {
ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
break;
}
case 6: {
ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
break;
}
case 7: {
ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
break;
}
case 8: {
banmap_t banmap;
ban_man.GetBanned(banmap);
break;
}
case 9: {
ban_man.DumpBanlist();
break;
}
case 11: {
ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
break;
}
}
}
}
fs::remove(banlist_file);
}
6 changes: 6 additions & 0 deletions src/test/fuzz/base_encode_decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <test/fuzz/fuzz.h>

#include <base58.h>
#include <core_io.h>
#include <psbt.h>
#include <util/string.h>
#include <util/strencodings.h>

Expand Down Expand Up @@ -44,4 +46,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(encoded_string == TrimString(encoded_string));
assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
}

PartiallySignedTransaction psbt;
std::string error;
(void)DecodeBase64PSBT(psbt, random_encoded_string, error);
}
6 changes: 4 additions & 2 deletions src/test/fuzz/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

void initialize()
{
const static auto verify_handle = MakeUnique<ECCVerifyHandle>();
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}

Expand Down Expand Up @@ -52,5 +52,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)block.GetHash();
(void)block.ToString();
(void)BlockMerkleRoot(block);
(void)RecursiveDynamicUsage(block);
const size_t raw_memory_size = RecursiveDynamicUsage(block);
const size_t raw_memory_size_as_shared_ptr = RecursiveDynamicUsage(std::make_shared<CBlock>(block));
assert(raw_memory_size_as_shared_ptr > raw_memory_size);
}
78 changes: 78 additions & 0 deletions src/test/fuzz/buffered_file.cpp
Original file line number Diff line number Diff line change
@@ -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();
}
}
Loading