aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/asmap.cpp45
-rw-r--r--src/test/fuzz/asmap_direct.cpp46
-rw-r--r--src/test/fuzz/bloom_filter.cpp5
-rw-r--r--src/test/fuzz/fees.cpp3
-rw-r--r--src/test/fuzz/integer.cpp17
-rw-r--r--src/test/fuzz/kitchen_sink.cpp25
-rw-r--r--src/test/fuzz/message.cpp48
-rw-r--r--src/test/fuzz/parse_hd_keypath.cpp10
-rw-r--r--src/test/fuzz/policy_estimator.cpp69
-rw-r--r--src/test/fuzz/rbf.cpp47
-rw-r--r--src/test/fuzz/scriptnum_ops.cpp6
-rw-r--r--src/test/fuzz/string.cpp4
-rw-r--r--src/test/fuzz/system.cpp123
-rw-r--r--src/test/fuzz/util.h18
14 files changed, 437 insertions, 29 deletions
diff --git a/src/test/fuzz/asmap.cpp b/src/test/fuzz/asmap.cpp
index 7f3eef79a1..ea56277eac 100644
--- a/src/test/fuzz/asmap.cpp
+++ b/src/test/fuzz/asmap.cpp
@@ -3,26 +3,47 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <netaddress.h>
-#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <cstdint>
#include <vector>
+//! asmap code that consumes nothing
+static const std::vector<bool> IPV6_PREFIX_ASMAP = {};
+
+//! asmap code that consumes the 96 prefix bits of ::ffff:0/96 (IPv4-in-IPv6 map)
+static const std::vector<bool> IPV4_PREFIX_ASMAP = {
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, // Match 0x00
+ true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, // Match 0xFF
+ true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true // Match 0xFF
+};
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
- FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
- const Network network = fuzzed_data_provider.PickValueInArray({NET_IPV4, NET_IPV6});
- if (fuzzed_data_provider.remaining_bytes() < 16) {
- return;
- }
- CNetAddr net_addr;
- net_addr.SetRaw(network, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data());
- std::vector<bool> asmap;
- for (const char cur_byte : fuzzed_data_provider.ConsumeRemainingBytes<char>()) {
- for (int bit = 0; bit < 8; ++bit) {
- asmap.push_back((cur_byte >> bit) & 1);
+ // Encoding: [7 bits: asmap size] [1 bit: ipv6?] [3-130 bytes: asmap] [4 or 16 bytes: addr]
+ if (buffer.size() < 1 + 3 + 4) return;
+ int asmap_size = 3 + (buffer[0] & 127);
+ bool ipv6 = buffer[0] & 128;
+ int addr_size = ipv6 ? 16 : 4;
+ if (buffer.size() < size_t(1 + asmap_size + addr_size)) return;
+ std::vector<bool> asmap = ipv6 ? IPV6_PREFIX_ASMAP : IPV4_PREFIX_ASMAP;
+ asmap.reserve(asmap.size() + 8 * asmap_size);
+ for (int i = 0; i < asmap_size; ++i) {
+ for (int j = 0; j < 8; ++j) {
+ asmap.push_back((buffer[1 + i] >> j) & 1);
}
}
+ if (!SanityCheckASMap(asmap)) return;
+ CNetAddr net_addr;
+ net_addr.SetRaw(ipv6 ? NET_IPV6 : NET_IPV4, buffer.data() + 1 + asmap_size);
(void)net_addr.GetMappedAS(asmap);
}
diff --git a/src/test/fuzz/asmap_direct.cpp b/src/test/fuzz/asmap_direct.cpp
new file mode 100644
index 0000000000..6d8a65f5ab
--- /dev/null
+++ b/src/test/fuzz/asmap_direct.cpp
@@ -0,0 +1,46 @@
+// 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 <util/asmap.h>
+#include <test/fuzz/fuzz.h>
+
+#include <cstdint>
+#include <optional>
+#include <vector>
+
+#include <assert.h>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ // Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
+ std::optional<size_t> sep_pos_opt;
+ for (size_t pos = 0; pos < buffer.size(); ++pos) {
+ uint8_t x = buffer[pos];
+ if ((x & 0xFE) == 0) continue;
+ if (x == 0xFF) {
+ if (sep_pos_opt) return;
+ sep_pos_opt = pos;
+ } else {
+ return;
+ }
+ }
+ if (!sep_pos_opt) return; // Needs exactly 1 separator
+ const size_t sep_pos{sep_pos_opt.value()};
+ if (buffer.size() - sep_pos - 1 > 128) return; // At most 128 bits in IP address
+
+ // Checks on asmap
+ std::vector<bool> asmap(buffer.begin(), buffer.begin() + sep_pos);
+ if (SanityCheckASMap(asmap, buffer.size() - 1 - sep_pos)) {
+ // Verify that for valid asmaps, no prefix (except up to 7 zero padding bits) is valid.
+ std::vector<bool> asmap_prefix = asmap;
+ while (!asmap_prefix.empty() && asmap_prefix.size() + 7 > asmap.size() && asmap_prefix.back() == false) asmap_prefix.pop_back();
+ while (!asmap_prefix.empty()) {
+ asmap_prefix.pop_back();
+ assert(!SanityCheckASMap(asmap_prefix, buffer.size() - 1 - sep_pos));
+ }
+ // No address input should trigger assertions in interpreter
+ std::vector<bool> addr(buffer.begin() + sep_pos + 1, buffer.end());
+ (void)Interpret(asmap, addr);
+ }
+}
diff --git a/src/test/fuzz/bloom_filter.cpp b/src/test/fuzz/bloom_filter.cpp
index 50036ce5bd..7039bf16c1 100644
--- a/src/test/fuzz/bloom_filter.cpp
+++ b/src/test/fuzz/bloom_filter.cpp
@@ -25,7 +25,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
fuzzed_data_provider.ConsumeIntegral<unsigned int>(),
static_cast<unsigned char>(fuzzed_data_provider.PickValueInArray({BLOOM_UPDATE_NONE, BLOOM_UPDATE_ALL, BLOOM_UPDATE_P2PUBKEY_ONLY, BLOOM_UPDATE_MASK}))};
while (fuzzed_data_provider.remaining_bytes() > 0) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 4)) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 3)) {
case 0: {
const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
(void)bloom_filter.contains(b);
@@ -65,9 +65,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)bloom_filter.IsRelevantAndUpdate(tx);
break;
}
- case 4:
- bloom_filter.UpdateEmptyFull();
- break;
}
(void)bloom_filter.IsWithinSizeConstraints();
}
diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp
index 090994263e..f29acace23 100644
--- a/src/test/fuzz/fees.cpp
+++ b/src/test/fuzz/fees.cpp
@@ -8,6 +8,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <util/fees.h>
#include <cstdint>
#include <string>
@@ -23,4 +24,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
assert(MoneyRange(rounded_fee));
}
+ const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});
+ (void)StringForFeeReason(fee_reason);
}
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index 9dbf0fcc90..35d6804d4f 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -24,8 +24,8 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
-#include <time.h>
#include <uint256.h>
+#include <util/check.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
@@ -35,6 +35,7 @@
#include <cassert>
#include <chrono>
+#include <ctime>
#include <limits>
#include <set>
#include <vector>
@@ -147,11 +148,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const CScriptNum script_num{i64};
(void)script_num.getint();
- // Avoid negation failure:
- // script/script.h:332:35: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long'); cast to an unsigned type to negate this value to itself
- if (script_num != CScriptNum{std::numeric_limits<int64_t>::min()}) {
- (void)script_num.getvch();
- }
+ (void)script_num.getvch();
const arith_uint256 au256 = UintToArith256(u256);
assert(ArithToUint256(au256) == u256);
@@ -287,8 +284,12 @@ void test_one_input(const std::vector<uint8_t>& buffer)
try {
const uint64_t deserialized_u64 = ReadCompactSize(stream);
assert(u64 == deserialized_u64 && stream.empty());
+ } catch (const std::ios_base::failure&) {
}
- catch (const std::ios_base::failure&) {
- }
+ }
+
+ try {
+ CHECK_NONFATAL(b);
+ } catch (const NonFatalCheckError&) {
}
}
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
new file mode 100644
index 0000000000..af6dc71322
--- /dev/null
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -0,0 +1,25 @@
+// 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 <rpc/util.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/error.h>
+
+#include <cstdint>
+#include <vector>
+
+// The fuzzing kitchen sink: Fuzzing harness for functions that need to be
+// fuzzed but a.) don't belong in any existing fuzzing harness file, and
+// b.) are not important enough to warrant their own fuzzing harness file.
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ const TransactionError transaction_error = fuzzed_data_provider.PickValueInArray<TransactionError>({TransactionError::OK, TransactionError::MISSING_INPUTS, TransactionError::ALREADY_IN_CHAIN, TransactionError::P2P_DISABLED, TransactionError::MEMPOOL_REJECTED, TransactionError::MEMPOOL_ERROR, TransactionError::INVALID_PSBT, TransactionError::PSBT_MISMATCH, TransactionError::SIGHASH_MISMATCH, TransactionError::MAX_FEE_EXCEEDED});
+ (void)JSONRPCTransactionError(transaction_error);
+ (void)RPCErrorFromTransactionError(transaction_error);
+ (void)TransactionErrorString(transaction_error);
+}
diff --git a/src/test/fuzz/message.cpp b/src/test/fuzz/message.cpp
new file mode 100644
index 0000000000..dfa98a812b
--- /dev/null
+++ b/src/test/fuzz/message.cpp
@@ -0,0 +1,48 @@
+// 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 <key_io.h>
+#include <optional.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/message.h>
+#include <util/strencodings.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ static const ECCVerifyHandle ecc_verify_handle;
+ ECC_Start();
+ SelectParams(CBaseChainParams::REGTEST);
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ const std::string random_message = fuzzed_data_provider.ConsumeRandomLengthString(1024);
+ {
+ const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ CKey private_key;
+ private_key.Set(random_bytes.begin(), random_bytes.end(), fuzzed_data_provider.ConsumeBool());
+ std::string signature;
+ const bool message_signed = MessageSign(private_key, random_message, signature);
+ if (private_key.IsValid()) {
+ assert(message_signed);
+ const MessageVerificationResult verification_result = MessageVerify(EncodeDestination(PKHash(private_key.GetPubKey().GetID())), signature, random_message);
+ assert(verification_result == MessageVerificationResult::OK);
+ }
+ }
+ {
+ (void)MessageHash(random_message);
+ (void)MessageVerify(fuzzed_data_provider.ConsumeRandomLengthString(1024), fuzzed_data_provider.ConsumeRandomLengthString(1024), random_message);
+ (void)SigningResultString(fuzzed_data_provider.PickValueInArray({SigningResult::OK, SigningResult::PRIVATE_KEY_NOT_AVAILABLE, SigningResult::SIGNING_FAILED}));
+ }
+}
diff --git a/src/test/fuzz/parse_hd_keypath.cpp b/src/test/fuzz/parse_hd_keypath.cpp
index 9a23f4b2d4..f668ca8c48 100644
--- a/src/test/fuzz/parse_hd_keypath.cpp
+++ b/src/test/fuzz/parse_hd_keypath.cpp
@@ -2,12 +2,22 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <util/bip32.h>
+#include <cstdint>
+#include <vector>
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
const std::string keypath_str(buffer.begin(), buffer.end());
std::vector<uint32_t> keypath;
(void)ParseHDKeypath(keypath_str, keypath);
+
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ const std::vector<uint32_t> random_keypath = ConsumeRandomLengthIntegralVector<uint32_t>(fuzzed_data_provider);
+ (void)FormatHDKeypath(random_keypath);
+ (void)WriteHDKeypath(random_keypath);
}
diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp
new file mode 100644
index 0000000000..201f49c87b
--- /dev/null
+++ b/src/test/fuzz/policy_estimator.cpp
@@ -0,0 +1,69 @@
+// 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 <policy/fees.h>
+#include <primitives/transaction.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <txmempool.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ CBlockPolicyEstimator block_policy_estimator;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 3)) {
+ case 0: {
+ const Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ break;
+ }
+ const CTransaction tx{*mtx};
+ block_policy_estimator.processTransaction(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx), fuzzed_data_provider.ConsumeBool());
+ if (fuzzed_data_provider.ConsumeBool()) {
+ (void)block_policy_estimator.removeTx(tx.GetHash(), /* inBlock */ fuzzed_data_provider.ConsumeBool());
+ }
+ break;
+ }
+ case 1: {
+ std::vector<CTxMemPoolEntry> mempool_entries;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ break;
+ }
+ const CTransaction tx{*mtx};
+ mempool_entries.push_back(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx));
+ }
+ std::vector<const CTxMemPoolEntry*> ptrs;
+ ptrs.reserve(mempool_entries.size());
+ for (const CTxMemPoolEntry& mempool_entry : mempool_entries) {
+ ptrs.push_back(&mempool_entry);
+ }
+ block_policy_estimator.processBlock(fuzzed_data_provider.ConsumeIntegral<unsigned int>(), ptrs);
+ break;
+ }
+ case 2: {
+ (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider), /* inBlock */ fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 3: {
+ block_policy_estimator.FlushUnconfirmed();
+ break;
+ }
+ }
+ (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>());
+ EstimationResult result;
+ (void)block_policy_estimator.estimateRawFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeFloatingPoint<double>(), fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}), fuzzed_data_provider.ConsumeBool() ? &result : nullptr);
+ FeeCalculation fee_calculation;
+ (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}));
+ }
+}
diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp
new file mode 100644
index 0000000000..eb54b05df9
--- /dev/null
+++ b/src/test/fuzz/rbf.cpp
@@ -0,0 +1,47 @@
+// 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 <policy/rbf.h>
+#include <primitives/transaction.h>
+#include <sync.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <txmempool.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ return;
+ }
+ CTxMemPool pool;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const Optional<CMutableTransaction> another_mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!another_mtx) {
+ break;
+ }
+ const CTransaction another_tx{*another_mtx};
+ if (fuzzed_data_provider.ConsumeBool() && !mtx->vin.empty()) {
+ mtx->vin[0].prevout = COutPoint{another_tx.GetHash(), 0};
+ }
+ LOCK2(cs_main, pool.cs);
+ pool.addUnchecked(ConsumeTxMemPoolEntry(fuzzed_data_provider, another_tx));
+ }
+ const CTransaction tx{*mtx};
+ if (fuzzed_data_provider.ConsumeBool()) {
+ LOCK2(cs_main, pool.cs);
+ pool.addUnchecked(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx));
+ }
+ {
+ LOCK(pool.cs);
+ (void)IsRBFOptIn(tx, pool);
+ }
+}
diff --git a/src/test/fuzz/scriptnum_ops.cpp b/src/test/fuzz/scriptnum_ops.cpp
index 42b1432f13..f4e079fb89 100644
--- a/src/test/fuzz/scriptnum_ops.cpp
+++ b/src/test/fuzz/scriptnum_ops.cpp
@@ -129,10 +129,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
break;
}
(void)script_num.getint();
- // Avoid negation failure:
- // script/script.h:332:35: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long'); cast to an unsigned type to negate this value to itself
- if (script_num != CScriptNum{std::numeric_limits<int64_t>::min()}) {
- (void)script_num.getvch();
- }
+ (void)script_num.getvch();
}
}
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 3de0cf8db7..49bee0e81f 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -115,4 +115,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(data_stream.empty());
assert(deserialized_string == random_string_1);
}
+ {
+ int64_t amount_out;
+ (void)ParseFixedPoint(random_string_1, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1024), &amount_out);
+ }
}
diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp
new file mode 100644
index 0000000000..01b523cee4
--- /dev/null
+++ b/src/test/fuzz/system.cpp
@@ -0,0 +1,123 @@
+// 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 <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/system.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace {
+std::string GetArgumentName(const std::string& name)
+{
+ size_t idx = name.find('=');
+ if (idx == std::string::npos) {
+ idx = name.size();
+ }
+ return name.substr(0, idx);
+}
+} // namespace
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ ArgsManager args_manager{};
+
+ if (fuzzed_data_provider.ConsumeBool()) {
+ SetupHelpOptions(args_manager);
+ }
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 7)) {
+ case 0: {
+ args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 1: {
+ args_manager.SoftSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 2: {
+ args_manager.ForceSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 3: {
+ args_manager.SoftSetBoolArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 4: {
+ const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::HIDDEN});
+ // Avoid hitting:
+ // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
+ const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16));
+ if (args_manager.GetArgFlags(argument_name) != nullopt) {
+ break;
+ }
+ args_manager.AddArg(argument_name, fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeIntegral<unsigned int>(), options_category);
+ break;
+ }
+ case 5: {
+ // Avoid hitting:
+ // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
+ const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider);
+ std::vector<std::string> hidden_arguments;
+ for (const std::string& name : names) {
+ const std::string hidden_argument = GetArgumentName(name);
+ if (args_manager.GetArgFlags(hidden_argument) != nullopt) {
+ continue;
+ }
+ if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) {
+ continue;
+ }
+ hidden_arguments.push_back(hidden_argument);
+ }
+ args_manager.AddHiddenArgs(hidden_arguments);
+ break;
+ }
+ case 6: {
+ args_manager.ClearArgs();
+ break;
+ }
+ case 7: {
+ const std::vector<std::string> random_arguments = ConsumeRandomLengthStringVector(fuzzed_data_provider);
+ std::vector<const char*> argv;
+ argv.reserve(random_arguments.size());
+ for (const std::string& random_argument : random_arguments) {
+ argv.push_back(random_argument.c_str());
+ }
+ try {
+ std::string error;
+ (void)args_manager.ParseParameters(argv.size(), argv.data(), error);
+ } catch (const std::logic_error&) {
+ }
+ break;
+ }
+ }
+ }
+
+ const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16);
+ const std::string s2 = fuzzed_data_provider.ConsumeRandomLengthString(16);
+ const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const bool b = fuzzed_data_provider.ConsumeBool();
+
+ (void)args_manager.GetArg(s1, i64);
+ (void)args_manager.GetArg(s1, s2);
+ (void)args_manager.GetArgFlags(s1);
+ (void)args_manager.GetArgs(s1);
+ (void)args_manager.GetBoolArg(s1, b);
+ try {
+ (void)args_manager.GetChainName();
+ } catch (const std::runtime_error&) {
+ }
+ (void)args_manager.GetHelpMessage();
+ (void)args_manager.GetUnrecognizedSections();
+ (void)args_manager.GetUnsuitableSectionOnlyArgs();
+ (void)args_manager.IsArgNegated(s1);
+ (void)args_manager.IsArgSet(s1);
+
+ (void)HelpRequested(args_manager);
+}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 9c7b0d47a2..501bb1de5a 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -8,12 +8,15 @@
#include <amount.h>
#include <arith_uint256.h>
#include <attributes.h>
+#include <consensus/consensus.h>
#include <optional.h>
+#include <primitives/transaction.h>
#include <script/script.h>
#include <serialize.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <txmempool.h>
#include <uint256.h>
#include <version.h>
@@ -97,6 +100,21 @@ NODISCARD inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_da
return UintToArith256(ConsumeUInt256(fuzzed_data_provider));
}
+NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
+{
+ // Avoid:
+ // policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
+ //
+ // Reproduce using CFeeRate(348732081484775, 10).GetFeePerK()
+ const CAmount fee = std::min<CAmount>(ConsumeMoney(fuzzed_data_provider), std::numeric_limits<CAmount>::max() / static_cast<CAmount>(100000));
+ assert(MoneyRange(fee));
+ const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
+ const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
+ return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
+}
+
template <typename T>
NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
{