diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/addrman_tests.cpp | 51 | ||||
-rw-r--r-- | src/test/blockchain_tests.cpp | 5 | ||||
-rw-r--r-- | src/test/denialofservice_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/addrdb.cpp | 43 | ||||
-rw-r--r-- | src/test/fuzz/blockfilter.cpp | 44 | ||||
-rw-r--r-- | src/test/fuzz/chain.cpp | 65 | ||||
-rw-r--r-- | src/test/fuzz/integer.cpp | 40 | ||||
-rw-r--r-- | src/test/fuzz/net_permissions.cpp | 51 | ||||
-rw-r--r-- | src/test/fuzz/protocol.cpp | 32 | ||||
-rw-r--r-- | src/test/fuzz/timedata.cpp | 29 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 10 | ||||
-rw-r--r-- | src/test/key_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/net_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/settings_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/timedata_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/transaction_tests.cpp | 34 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 1 | ||||
-rw-r--r-- | src/test/util/setup_common.h | 1 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 22 | ||||
-rw-r--r-- | src/test/util_threadnames_tests.cpp | 5 |
20 files changed, 413 insertions, 35 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 07cebeb35a..dfa8a6df21 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -6,6 +6,7 @@ #include <string> #include <boost/test/unit_test.hpp> #include <util/asmap.h> +#include <util/string.h> #include <test/data/asmap.raw.h> #include <hash.h> @@ -266,7 +267,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) BOOST_CHECK_EQUAL(addrman.size(), 0U); for (unsigned int i = 1; i < 18; i++) { - CService addr = ResolveService("250.1.1." + std::to_string(i)); + CService addr = ResolveService("250.1.1." + ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); //Test: No collision in new table yet. @@ -292,7 +293,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) BOOST_CHECK_EQUAL(addrman.size(), 0U); for (unsigned int i = 1; i < 80; i++) { - CService addr = ResolveService("250.1.1." + std::to_string(i)); + CService addr = ResolveService("250.1.1." + ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); addrman.Good(CAddress(addr, NODE_NONE)); @@ -425,7 +426,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) for (unsigned int i = 1; i < (8 * 256); i++) { int octet1 = i % 256; int octet2 = i >> 8 % 256; - std::string strAddr = std::to_string(octet1) + "." + std::to_string(octet2) + ".1.23"; + std::string strAddr = ToString(octet1) + "." + ToString(octet2) + ".1.23"; CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE); // Ensure that for all addrs in addrman, isTerrible == false. @@ -477,8 +478,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket_legacy) std::set<int> buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(ResolveService("250.1.1." + std::to_string(i)), NODE_NONE), - ResolveIP("250.1.1." + std::to_string(i))); + CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE), + ResolveIP("250.1.1." + ToString(i))); int bucket = infoi.GetTriedBucket(nKey1, asmap); buckets.insert(bucket); } @@ -489,8 +490,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket_legacy) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(ResolveService("250." + std::to_string(j) + ".1.1"), NODE_NONE), - ResolveIP("250." + std::to_string(j) + ".1.1")); + CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE), + ResolveIP("250." + ToString(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1, asmap); buckets.insert(bucket); } @@ -531,8 +532,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy) std::set<int> buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(ResolveService("250.1.1." + std::to_string(i)), NODE_NONE), - ResolveIP("250.1.1." + std::to_string(i))); + CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE), + ResolveIP("250.1.1." + ToString(i))); int bucket = infoi.GetNewBucket(nKey1, asmap); buckets.insert(bucket); } @@ -544,7 +545,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( ResolveService( - std::to_string(250 + (j / 255)) + "." + std::to_string(j % 256) + ".1.1"), NODE_NONE), + ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE), ResolveIP("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1, asmap); buckets.insert(bucket); @@ -557,7 +558,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket_legacy) for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( CAddress(ResolveService("250.1.1.1"), NODE_NONE), - ResolveIP("250." + std::to_string(p) + ".1.1")); + ResolveIP("250." + ToString(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1, asmap); buckets.insert(bucket); } @@ -610,8 +611,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) std::set<int> buckets; for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(ResolveService("101." + std::to_string(j) + ".1.1"), NODE_NONE), - ResolveIP("101." + std::to_string(j) + ".1.1")); + CAddress(ResolveService("101." + ToString(j) + ".1.1"), NODE_NONE), + ResolveIP("101." + ToString(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1, asmap); buckets.insert(bucket); } @@ -622,8 +623,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) buckets.clear(); for (int j = 0; j < 255; j++) { CAddrInfo infoj = CAddrInfo( - CAddress(ResolveService("250." + std::to_string(j) + ".1.1"), NODE_NONE), - ResolveIP("250." + std::to_string(j) + ".1.1")); + CAddress(ResolveService("250." + ToString(j) + ".1.1"), NODE_NONE), + ResolveIP("250." + ToString(j) + ".1.1")); int bucket = infoj.GetTriedBucket(nKey1, asmap); buckets.insert(bucket); } @@ -664,8 +665,8 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) std::set<int> buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( - CAddress(ResolveService("250.1.1." + std::to_string(i)), NODE_NONE), - ResolveIP("250.1.1." + std::to_string(i))); + CAddress(ResolveService("250.1.1." + ToString(i)), NODE_NONE), + ResolveIP("250.1.1." + ToString(i))); int bucket = infoi.GetNewBucket(nKey1, asmap); buckets.insert(bucket); } @@ -677,7 +678,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int j = 0; j < 4 * 255; j++) { CAddrInfo infoj = CAddrInfo(CAddress( ResolveService( - std::to_string(250 + (j / 255)) + "." + std::to_string(j % 256) + ".1.1"), NODE_NONE), + ToString(250 + (j / 255)) + "." + ToString(j % 256) + ".1.1"), NODE_NONE), ResolveIP("251.4.1.1")); int bucket = infoj.GetNewBucket(nKey1, asmap); buckets.insert(bucket); @@ -690,7 +691,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( CAddress(ResolveService("250.1.1.1"), NODE_NONE), - ResolveIP("101." + std::to_string(p) + ".1.1")); + ResolveIP("101." + ToString(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1, asmap); buckets.insert(bucket); } @@ -702,7 +703,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) for (int p = 0; p < 255; p++) { CAddrInfo infoj = CAddrInfo( CAddress(ResolveService("250.1.1.1"), NODE_NONE), - ResolveIP("250." + std::to_string(p) + ".1.1")); + ResolveIP("250." + ToString(p) + ".1.1")); int bucket = infoj.GetNewBucket(nKey1, asmap); buckets.insert(bucket); } @@ -791,7 +792,7 @@ BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision) // Add twenty two addresses. CNetAddr source = ResolveIP("252.2.2.2"); for (unsigned int i = 1; i < 23; i++) { - CService addr = ResolveService("250.1.1."+std::to_string(i)); + CService addr = ResolveService("250.1.1."+ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); addrman.Good(addr); @@ -802,7 +803,7 @@ BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision) // Ensure Good handles duplicates well. for (unsigned int i = 1; i < 23; i++) { - CService addr = ResolveService("250.1.1."+std::to_string(i)); + CService addr = ResolveService("250.1.1."+ToString(i)); addrman.Good(addr); BOOST_CHECK(addrman.size() == 22); @@ -818,7 +819,7 @@ BOOST_AUTO_TEST_CASE(addrman_noevict) // Add twenty two addresses. CNetAddr source = ResolveIP("252.2.2.2"); for (unsigned int i = 1; i < 23; i++) { - CService addr = ResolveService("250.1.1."+std::to_string(i)); + CService addr = ResolveService("250.1.1."+ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); addrman.Good(addr); @@ -841,7 +842,7 @@ BOOST_AUTO_TEST_CASE(addrman_noevict) // Lets create two collisions. for (unsigned int i = 24; i < 33; i++) { - CService addr = ResolveService("250.1.1."+std::to_string(i)); + CService addr = ResolveService("250.1.1."+ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); addrman.Good(addr); @@ -879,7 +880,7 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks) // Add twenty two addresses. CNetAddr source = ResolveIP("252.2.2.2"); for (unsigned int i = 1; i < 23; i++) { - CService addr = ResolveService("250.1.1."+std::to_string(i)); + CService addr = ResolveService("250.1.1."+ToString(i)); BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source)); addrman.Good(addr); diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp index 3b4c480f72..aa704642bf 100644 --- a/src/test/blockchain_tests.cpp +++ b/src/test/blockchain_tests.cpp @@ -8,6 +8,7 @@ #include <chain.h> #include <rpc/blockchain.h> +#include <util/string.h> #include <test/util/setup_common.h> /* Equality between doubles is imprecise. Comparison should be done @@ -30,8 +31,8 @@ static CBlockIndex* CreateBlockIndexWithNbits(uint32_t nbits) static void RejectDifficultyMismatch(double difficulty, double expected_difficulty) { BOOST_CHECK_MESSAGE( DoubleEquals(difficulty, expected_difficulty, 0.00001), - "Difficulty was " + std::to_string(difficulty) - + " but was expected to be " + std::to_string(expected_difficulty)); + "Difficulty was " + ToString(difficulty) + + " but was expected to be " + ToString(expected_difficulty)); } /* Given a BlockIndex with the provided nbits, diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 73bce6f789..7310498eb6 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -13,6 +13,7 @@ #include <script/standard.h> #include <serialize.h> #include <util/memory.h> +#include <util/string.h> #include <util/system.h> #include <util/time.h> #include <validation.h> @@ -313,7 +314,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); } BOOST_CHECK(banman->IsBanned(addr1)); - gArgs.ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD)); + gArgs.ForceSetArg("-banscore", ToString(DEFAULT_BANSCORE_THRESHOLD)); bool dummy; peerLogic->FinalizeNode(dummyNode1.GetId(), dummy); diff --git a/src/test/fuzz/addrdb.cpp b/src/test/fuzz/addrdb.cpp new file mode 100644 index 0000000000..f21ff3fac3 --- /dev/null +++ b/src/test/fuzz/addrdb.cpp @@ -0,0 +1,43 @@ +// 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 <addrdb.h> +#include <optional.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cassert> +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + const CBanEntry ban_entry = [&] { + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 3)) { + case 0: + return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; + break; + case 1: + return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>(), fuzzed_data_provider.PickValueInArray<BanReason>({ + BanReason::BanReasonUnknown, + BanReason::BanReasonNodeMisbehaving, + BanReason::BanReasonManuallyAdded, + })}; + break; + case 2: { + const Optional<CBanEntry> ban_entry = ConsumeDeserializable<CBanEntry>(fuzzed_data_provider); + if (ban_entry) { + return *ban_entry; + } + break; + } + } + return CBanEntry{}; + }(); + assert(!ban_entry.banReasonToString().empty()); +} diff --git a/src/test/fuzz/blockfilter.cpp b/src/test/fuzz/blockfilter.cpp new file mode 100644 index 0000000000..be9320dcbf --- /dev/null +++ b/src/test/fuzz/blockfilter.cpp @@ -0,0 +1,44 @@ +// 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 <blockfilter.h> +#include <optional.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.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()); + const Optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider); + if (!block_filter) { + return; + } + { + (void)block_filter->ComputeHeader(ConsumeUInt256(fuzzed_data_provider)); + (void)block_filter->GetBlockHash(); + (void)block_filter->GetEncodedFilter(); + (void)block_filter->GetHash(); + } + { + const BlockFilterType block_filter_type = block_filter->GetFilterType(); + (void)BlockFilterTypeName(block_filter_type); + } + { + const GCSFilter gcs_filter = block_filter->GetFilter(); + (void)gcs_filter.GetN(); + (void)gcs_filter.GetParams(); + (void)gcs_filter.GetEncoded(); + (void)gcs_filter.Match(ConsumeRandomLengthByteVector(fuzzed_data_provider)); + GCSFilter::ElementSet element_set; + while (fuzzed_data_provider.ConsumeBool()) { + element_set.insert(ConsumeRandomLengthByteVector(fuzzed_data_provider)); + gcs_filter.MatchAny(element_set); + } + } +} diff --git a/src/test/fuzz/chain.cpp b/src/test/fuzz/chain.cpp new file mode 100644 index 0000000000..b322516cc7 --- /dev/null +++ b/src/test/fuzz/chain.cpp @@ -0,0 +1,65 @@ +// 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 <chain.h> +#include <optional.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + Optional<CDiskBlockIndex> disk_block_index = ConsumeDeserializable<CDiskBlockIndex>(fuzzed_data_provider); + if (!disk_block_index) { + return; + } + + const uint256 zero{}; + disk_block_index->phashBlock = &zero; + (void)disk_block_index->GetBlockHash(); + (void)disk_block_index->GetBlockPos(); + (void)disk_block_index->GetBlockTime(); + (void)disk_block_index->GetBlockTimeMax(); + (void)disk_block_index->GetMedianTimePast(); + (void)disk_block_index->GetUndoPos(); + (void)disk_block_index->HaveTxsDownloaded(); + (void)disk_block_index->IsValid(); + (void)disk_block_index->ToString(); + + const CBlockHeader block_header = disk_block_index->GetBlockHeader(); + (void)CDiskBlockIndex{*disk_block_index}; + (void)disk_block_index->BuildSkip(); + + while (fuzzed_data_provider.ConsumeBool()) { + const BlockStatus block_status = fuzzed_data_provider.PickValueInArray({ + BlockStatus::BLOCK_VALID_UNKNOWN, + BlockStatus::BLOCK_VALID_RESERVED, + BlockStatus::BLOCK_VALID_TREE, + BlockStatus::BLOCK_VALID_TRANSACTIONS, + BlockStatus::BLOCK_VALID_CHAIN, + BlockStatus::BLOCK_VALID_SCRIPTS, + BlockStatus::BLOCK_VALID_MASK, + BlockStatus::BLOCK_HAVE_DATA, + BlockStatus::BLOCK_HAVE_UNDO, + BlockStatus::BLOCK_HAVE_MASK, + BlockStatus::BLOCK_FAILED_VALID, + BlockStatus::BLOCK_FAILED_CHILD, + BlockStatus::BLOCK_FAILED_MASK, + BlockStatus::BLOCK_OPT_WITNESS, + }); + if (block_status & ~BLOCK_VALID_MASK) { + continue; + } + (void)disk_block_index->RaiseValidity(block_status); + } + + CBlockIndex block_index{block_header}; + block_index.phashBlock = &zero; + (void)block_index.GetBlockHash(); + (void)block_index.ToString(); +} diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 24459c21be..63b9296574 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -227,4 +227,44 @@ void test_one_input(const std::vector<uint8_t>& buffer) (void)HasAllDesirableServiceFlags(service_flags); (void)MayHaveUsefulAddressDB(service_flags); } + + { + CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); + + ser_writedata64(stream, u64); + const uint64_t deserialized_u64 = ser_readdata64(stream); + assert(u64 == deserialized_u64 && stream.empty()); + + ser_writedata32(stream, u32); + const uint32_t deserialized_u32 = ser_readdata32(stream); + assert(u32 == deserialized_u32 && stream.empty()); + + ser_writedata32be(stream, u32); + const uint32_t deserialized_u32be = ser_readdata32be(stream); + assert(u32 == deserialized_u32be && stream.empty()); + + ser_writedata16(stream, u16); + const uint16_t deserialized_u16 = ser_readdata16(stream); + assert(u16 == deserialized_u16 && stream.empty()); + + ser_writedata16be(stream, u16); + const uint16_t deserialized_u16be = ser_readdata16be(stream); + assert(u16 == deserialized_u16be && stream.empty()); + + ser_writedata8(stream, u8); + const uint8_t deserialized_u8 = ser_readdata8(stream); + assert(u8 == deserialized_u8 && stream.empty()); + } + + { + CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); + + WriteCompactSize(stream, u64); + try { + const uint64_t deserialized_u64 = ReadCompactSize(stream); + assert(u64 == deserialized_u64 && stream.empty()); + } + catch (const std::ios_base::failure&) { + } + } } diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp new file mode 100644 index 0000000000..bfc5d21427 --- /dev/null +++ b/src/test/fuzz/net_permissions.cpp @@ -0,0 +1,51 @@ +// 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 <net_permissions.h> +#include <optional.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cassert> +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(32); + const NetPermissionFlags net_permission_flags = fuzzed_data_provider.ConsumeBool() ? fuzzed_data_provider.PickValueInArray<NetPermissionFlags>({ + NetPermissionFlags::PF_NONE, + NetPermissionFlags::PF_BLOOMFILTER, + NetPermissionFlags::PF_RELAY, + NetPermissionFlags::PF_FORCERELAY, + NetPermissionFlags::PF_NOBAN, + NetPermissionFlags::PF_MEMPOOL, + NetPermissionFlags::PF_ISIMPLICIT, + NetPermissionFlags::PF_ALL, + }) : + static_cast<NetPermissionFlags>(fuzzed_data_provider.ConsumeIntegral<uint32_t>()); + + NetWhitebindPermissions net_whitebind_permissions; + std::string error_net_whitebind_permissions; + if (NetWhitebindPermissions::TryParse(s, net_whitebind_permissions, error_net_whitebind_permissions)) { + (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); + (void)NetPermissions::AddFlag(net_whitebind_permissions.m_flags, net_permission_flags); + assert(NetPermissions::HasFlag(net_whitebind_permissions.m_flags, net_permission_flags)); + (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); + } + + NetWhitelistPermissions net_whitelist_permissions; + std::string error_net_whitelist_permissions; + if (NetWhitelistPermissions::TryParse(s, net_whitelist_permissions, error_net_whitelist_permissions)) { + (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); + (void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags); + assert(NetPermissions::HasFlag(net_whitelist_permissions.m_flags, net_permission_flags)); + (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); + } +} diff --git a/src/test/fuzz/protocol.cpp b/src/test/fuzz/protocol.cpp new file mode 100644 index 0000000000..954471de6c --- /dev/null +++ b/src/test/fuzz/protocol.cpp @@ -0,0 +1,32 @@ +// 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 <protocol.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <stdexcept> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const Optional<CInv> inv = ConsumeDeserializable<CInv>(fuzzed_data_provider); + if (!inv) { + return; + } + try { + (void)inv->GetCommand(); + } catch (const std::out_of_range&) { + } + (void)inv->ToString(); + const Optional<CInv> another_inv = ConsumeDeserializable<CInv>(fuzzed_data_provider); + if (!another_inv) { + return; + } + (void)(*inv < *another_inv); +} diff --git a/src/test/fuzz/timedata.cpp b/src/test/fuzz/timedata.cpp new file mode 100644 index 0000000000..a0e579a88f --- /dev/null +++ b/src/test/fuzz/timedata.cpp @@ -0,0 +1,29 @@ +// 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 <timedata.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()); + const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000); + // Divide by 2 to avoid signed integer overflow in .median() + const int64_t initial_value = fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2; + CMedianFilter<int64_t> median_filter{max_size, initial_value}; + while (fuzzed_data_provider.remaining_bytes() > 0) { + (void)median_filter.median(); + assert(median_filter.size() > 0); + assert(static_cast<size_t>(median_filter.size()) == median_filter.sorted().size()); + assert(static_cast<unsigned int>(median_filter.size()) <= max_size || max_size == 0); + // Divide by 2 to avoid signed integer overflow in .median() + median_filter.input(fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2); + } +} diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 47f8d3fb27..10be2ebaf7 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -13,6 +13,7 @@ #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> +#include <uint256.h> #include <version.h> #include <cstdint> @@ -70,6 +71,15 @@ NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_pro return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; } +NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + const std::vector<unsigned char> v256 = fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)); + if (v256.size() != sizeof(uint256)) { + return {}; + } + return uint256{v256}; +} + template <typename T> bool MultiplicationOverflow(T i, T j) { diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 85dc961bea..034b7938f9 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -8,6 +8,7 @@ #include <uint256.h> #include <util/system.h> #include <util/strencodings.h> +#include <util/string.h> #include <test/util/setup_common.h> #include <string> @@ -176,7 +177,7 @@ BOOST_AUTO_TEST_CASE(key_signature_tests) bool found_small = false; for (int i = 0; i < 256; ++i) { sig.clear(); - std::string msg = "A message to be signed" + std::to_string(i); + std::string msg = "A message to be signed" + ToString(i); msg_hash = Hash(msg.begin(), msg.end()); BOOST_CHECK(key.Sign(msg_hash, sig)); found = sig[3] == 0x20; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index cb1ef5dcf3..9b5a86fef2 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -15,6 +15,7 @@ #include <chainparams.h> #include <util/memory.h> #include <util/system.h> +#include <util/string.h> #include <memory> @@ -85,7 +86,7 @@ BOOST_AUTO_TEST_CASE(cnode_listen_port) BOOST_CHECK(port == Params().GetDefaultPort()); // test set port unsigned short altPort = 12345; - BOOST_CHECK(gArgs.SoftSetArg("-port", std::to_string(altPort))); + BOOST_CHECK(gArgs.SoftSetArg("-port", ToString(altPort))); port = GetListenPort(); BOOST_CHECK(port == altPort); } diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index 45644834a5..10b161aa80 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -11,6 +11,7 @@ #include <boost/test/unit_test.hpp> #include <univalue.h> #include <util/strencodings.h> +#include <util/string.h> #include <vector> BOOST_FIXTURE_TEST_SUITE(settings_tests, BasicTestingSetup) @@ -114,7 +115,7 @@ BOOST_FIXTURE_TEST_CASE(Merge, MergeTestingSetup) std::vector<util::SettingsValue>& dest) { if (action == SET || action == SECTION_SET) { for (int i = 0; i < 2; ++i) { - dest.push_back(value_prefix + std::to_string(++value_suffix)); + dest.push_back(value_prefix + ToString(++value_suffix)); desc += " " + name_prefix + name + "=" + dest.back().get_str(); } } else if (action == NEGATE || action == SECTION_NEGATE) { diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 19bd0d142f..29b43e9bec 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -5,6 +5,7 @@ #include <netaddress.h> #include <noui.h> +#include <util/string.h> #include <test/util/logging.h> #include <test/util/setup_common.h> #include <timedata.h> @@ -46,7 +47,7 @@ static void MultiAddTimeData(int n, int64_t offset) static int cnt = 0; for (int i = 0; i < n; ++i) { CNetAddr addr; - addr.SetInternal(std::to_string(++cnt)); + addr.SetInternal(ToString(++cnt)); AddTimeData(addr, offset); } } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 44d4e0890a..96520079d7 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -784,6 +784,40 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); BOOST_CHECK_EQUAL(reason, "scriptsig-size"); + // Check scriptSig format (non-standard if there are any other ops than just PUSHs) + t.vin[0].scriptSig = CScript() + << OP_TRUE << OP_0 << OP_1NEGATE << OP_16 // OP_n (single byte pushes: n = 1, 0, -1, 16) + << std::vector<unsigned char>(75, 0) // OP_PUSHx [...x bytes...] + << std::vector<unsigned char>(235, 0) // OP_PUSHDATA1 x [...x bytes...] + << std::vector<unsigned char>(1234, 0) // OP_PUSHDATA2 x [...x bytes...] + << OP_9; + BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); + + const std::vector<unsigned char> non_push_ops = { // arbitrary set of non-push operations + OP_NOP, OP_VERIFY, OP_IF, OP_ROT, OP_3DUP, OP_SIZE, OP_EQUAL, OP_ADD, OP_SUB, + OP_HASH256, OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKLOCKTIMEVERIFY }; + + CScript::const_iterator pc = t.vin[0].scriptSig.begin(); + while (pc < t.vin[0].scriptSig.end()) { + opcodetype opcode; + CScript::const_iterator prev_pc = pc; + t.vin[0].scriptSig.GetOp(pc, opcode); // advance to next op + // for the sake of simplicity, we only replace single-byte push operations + if (opcode >= 1 && opcode <= OP_PUSHDATA4) + continue; + + int index = prev_pc - t.vin[0].scriptSig.begin(); + unsigned char orig_op = *prev_pc; // save op + // replace current push-op with each non-push-op + for (auto op : non_push_ops) { + t.vin[0].scriptSig[index] = op; + BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); + BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly"); + } + t.vin[0].scriptSig[index] = orig_op; // restore op + BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); + } + // Check tx-size (non-standard if transaction weight is > MAX_STANDARD_TX_WEIGHT) t.vin.clear(); t.vin.resize(2438); // size per input (empty scriptSig): 41 bytes diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index e19a96eafc..d684b97787 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -24,6 +24,7 @@ #include <txdb.h> #include <util/memory.h> #include <util/strencodings.h> +#include <util/string.h> #include <util/time.h> #include <util/translation.h> #include <validation.h> diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 56ad62eb24..0930309c3a 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -13,6 +13,7 @@ #include <random.h> #include <scheduler.h> #include <txmempool.h> +#include <util/string.h> #include <type_traits> diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index eb0d31fbdc..73b37f909f 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -894,7 +894,7 @@ struct ArgsMergeTestingSetup : public BasicTestingSetup { if (action == SECTION_SET || action == SECTION_NEGATE) prefix = section + "."; if (action == SET || action == SECTION_SET) { for (int i = 0; i < 2; ++i) { - values.push_back(prefix + name + "=" + value_prefix + std::to_string(++suffix)); + values.push_back(prefix + name + "=" + value_prefix + ToString(++suffix)); } } if (action == NEGATE || action == SECTION_NEGATE) { @@ -1182,6 +1182,12 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney) BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK(ParseMoney("1", ret)); BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney(" 1", ret)); + BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney("1 ", ret)); + BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney(" 1 ", ret)); + BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK(ParseMoney("0.1", ret)); BOOST_CHECK_EQUAL(ret, COIN/10); BOOST_CHECK(ParseMoney("0.01", ret)); @@ -1198,12 +1204,26 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney) BOOST_CHECK_EQUAL(ret, COIN/10000000); BOOST_CHECK(ParseMoney("0.00000001", ret)); BOOST_CHECK_EQUAL(ret, COIN/100000000); + BOOST_CHECK(ParseMoney(" 0.00000001 ", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); + BOOST_CHECK(ParseMoney("0.00000001 ", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); + BOOST_CHECK(ParseMoney(" 0.00000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); // Parsing amount that can not be represented in ret should fail BOOST_CHECK(!ParseMoney("0.000000001", ret)); // Parsing empty string should fail BOOST_CHECK(!ParseMoney("", ret)); + BOOST_CHECK(!ParseMoney(" ", ret)); + BOOST_CHECK(!ParseMoney(" ", ret)); + + // Parsing two numbers should fail + BOOST_CHECK(!ParseMoney("1 2", ret)); + BOOST_CHECK(!ParseMoney(" 1 2 ", ret)); + BOOST_CHECK(!ParseMoney(" 1.2 3 ", ret)); + BOOST_CHECK(!ParseMoney(" 1 2.3 ", ret)); // Attempted 63 bit overflow should fail BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp index 78dbf848bb..cee4e0ce3c 100644 --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <util/string.h> #include <util/threadnames.h> #include <test/util/setup_common.h> @@ -32,7 +33,7 @@ std::set<std::string> RenameEnMasse(int num_threads) std::mutex lock; auto RenameThisThread = [&](int i) { - util::ThreadRename(TEST_THREAD_NAME_BASE + std::to_string(i)); + util::ThreadRename(TEST_THREAD_NAME_BASE + ToString(i)); std::lock_guard<std::mutex> guard(lock); names.insert(util::ThreadGetInternalName()); }; @@ -65,7 +66,7 @@ BOOST_AUTO_TEST_CASE(util_threadnames_test_rename_threaded) // Names "test_thread.[n]" should exist for n = [0, 99] for (int i = 0; i < 100; ++i) { - BOOST_CHECK(names.find(TEST_THREAD_NAME_BASE + std::to_string(i)) != names.end()); + BOOST_CHECK(names.find(TEST_THREAD_NAME_BASE + ToString(i)) != names.end()); } } |