aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz')
-rw-r--r--src/test/fuzz/FuzzedDataProvider.h563
-rw-r--r--src/test/fuzz/addition_overflow.cpp4
-rw-r--r--src/test/fuzz/addrdb.cpp2
-rw-r--r--src/test/fuzz/addrman.cpp156
-rw-r--r--src/test/fuzz/asmap.cpp2
-rw-r--r--src/test/fuzz/asmap_direct.cpp2
-rw-r--r--src/test/fuzz/autofile.cpp70
-rw-r--r--src/test/fuzz/banman.cpp89
-rw-r--r--src/test/fuzz/base_encode_decode.cpp2
-rw-r--r--src/test/fuzz/bech32.cpp4
-rw-r--r--src/test/fuzz/block.cpp4
-rw-r--r--src/test/fuzz/block_header.cpp2
-rw-r--r--src/test/fuzz/blockfilter.cpp2
-rw-r--r--src/test/fuzz/bloom_filter.cpp80
-rw-r--r--src/test/fuzz/buffered_file.cpp67
-rw-r--r--src/test/fuzz/chain.cpp2
-rw-r--r--src/test/fuzz/checkqueue.cpp2
-rw-r--r--src/test/fuzz/coins_view.cpp349
-rw-r--r--src/test/fuzz/connman.cpp219
-rw-r--r--src/test/fuzz/crypto.cpp178
-rw-r--r--src/test/fuzz/crypto_aes256.cpp2
-rw-r--r--src/test/fuzz/crypto_aes256cbc.cpp2
-rw-r--r--src/test/fuzz/crypto_chacha20.cpp49
-rw-r--r--src/test/fuzz/crypto_chacha20_poly1305_aead.cpp79
-rw-r--r--src/test/fuzz/crypto_common.cpp2
-rw-r--r--src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp2
-rw-r--r--src/test/fuzz/crypto_poly1305.cpp2
-rw-r--r--src/test/fuzz/cuckoocache.cpp2
-rwxr-xr-xsrc/test/fuzz/danger_link_all.sh28
-rw-r--r--src/test/fuzz/data_stream.cpp25
-rw-r--r--src/test/fuzz/decode_tx.cpp4
-rw-r--r--src/test/fuzz/descriptor_parse.cpp4
-rw-r--r--src/test/fuzz/deserialize.cpp140
-rw-r--r--src/test/fuzz/eval_script.cpp4
-rw-r--r--src/test/fuzz/fee_rate.cpp2
-rw-r--r--src/test/fuzz/fees.cpp2
-rw-r--r--src/test/fuzz/flatfile.cpp2
-rw-r--r--src/test/fuzz/float.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp38
-rw-r--r--src/test/fuzz/fuzz.h27
-rw-r--r--src/test/fuzz/golomb_rice.cpp2
-rw-r--r--src/test/fuzz/hex.cpp4
-rw-r--r--src/test/fuzz/http_request.cpp2
-rw-r--r--src/test/fuzz/integer.cpp4
-rw-r--r--src/test/fuzz/key.cpp4
-rw-r--r--src/test/fuzz/key_io.cpp4
-rw-r--r--src/test/fuzz/kitchen_sink.cpp37
-rw-r--r--src/test/fuzz/load_external_block_file.cpp8
-rw-r--r--src/test/fuzz/locale.cpp2
-rw-r--r--src/test/fuzz/merkleblock.cpp50
-rw-r--r--src/test/fuzz/message.cpp4
-rw-r--r--src/test/fuzz/muhash.cpp53
-rw-r--r--src/test/fuzz/multiplication_overflow.cpp4
-rw-r--r--src/test/fuzz/net.cpp187
-rw-r--r--src/test/fuzz/net_permissions.cpp15
-rw-r--r--src/test/fuzz/netaddress.cpp2
-rw-r--r--src/test/fuzz/node_eviction.cpp44
-rw-r--r--src/test/fuzz/p2p_transport_deserializer.cpp6
-rw-r--r--src/test/fuzz/parse_hd_keypath.cpp4
-rw-r--r--src/test/fuzz/parse_iso8601.cpp4
-rw-r--r--src/test/fuzz/parse_numbers.cpp4
-rw-r--r--src/test/fuzz/parse_script.cpp4
-rw-r--r--src/test/fuzz/parse_univalue.cpp4
-rw-r--r--src/test/fuzz/policy_estimator.cpp78
-rw-r--r--src/test/fuzz/policy_estimator_io.cpp6
-rw-r--r--src/test/fuzz/pow.cpp9
-rw-r--r--src/test/fuzz/prevector.cpp2
-rw-r--r--src/test/fuzz/primitives_transaction.cpp2
-rw-r--r--src/test/fuzz/process_message.cpp75
-rw-r--r--src/test/fuzz/process_messages.cpp39
-rw-r--r--src/test/fuzz/protocol.cpp2
-rw-r--r--src/test/fuzz/psbt.cpp4
-rw-r--r--src/test/fuzz/random.cpp2
-rw-r--r--src/test/fuzz/rbf.cpp3
-rw-r--r--src/test/fuzz/rolling_bloom_filter.cpp48
-rw-r--r--src/test/fuzz/script.cpp26
-rw-r--r--src/test/fuzz/script_assets_test_minimizer.cpp4
-rw-r--r--src/test/fuzz/script_bitcoin_consensus.cpp2
-rw-r--r--src/test/fuzz/script_descriptor_cache.cpp2
-rw-r--r--src/test/fuzz/script_flags.cpp4
-rw-r--r--src/test/fuzz/script_interpreter.cpp2
-rw-r--r--src/test/fuzz/script_ops.cpp101
-rw-r--r--src/test/fuzz/script_sigcache.cpp6
-rw-r--r--src/test/fuzz/script_sign.cpp4
-rw-r--r--src/test/fuzz/scriptnum_ops.cpp194
-rw-r--r--src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp2
-rw-r--r--src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp2
-rw-r--r--src/test/fuzz/signature_checker.cpp6
-rw-r--r--src/test/fuzz/signet.cpp6
-rw-r--r--src/test/fuzz/span.cpp2
-rw-r--r--src/test/fuzz/spanparsing.cpp4
-rw-r--r--src/test/fuzz/string.cpp2
-rw-r--r--src/test/fuzz/strprintf.cpp123
-rw-r--r--src/test/fuzz/system.cpp120
-rw-r--r--src/test/fuzz/timedata.cpp2
-rw-r--r--src/test/fuzz/transaction.cpp6
-rw-r--r--src/test/fuzz/tx_in.cpp4
-rw-r--r--src/test/fuzz/tx_out.cpp4
-rw-r--r--src/test/fuzz/txrequest.cpp2
-rw-r--r--src/test/fuzz/util.cpp25
-rw-r--r--src/test/fuzz/util.h299
101 files changed, 2105 insertions, 1788 deletions
diff --git a/src/test/fuzz/FuzzedDataProvider.h b/src/test/fuzz/FuzzedDataProvider.h
index 3e069eba69..744a9d78ce 100644
--- a/src/test/fuzz/FuzzedDataProvider.h
+++ b/src/test/fuzz/FuzzedDataProvider.h
@@ -14,6 +14,7 @@
#define LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_
#include <algorithm>
+#include <array>
#include <climits>
#include <cstddef>
#include <cstdint>
@@ -34,272 +35,362 @@ class FuzzedDataProvider {
: data_ptr_(data), remaining_bytes_(size) {}
~FuzzedDataProvider() = default;
- // Returns a std::vector containing |num_bytes| of input data. If fewer than
- // |num_bytes| of data remain, returns a shorter std::vector containing all
- // of the data that's left. Can be used with any byte sized type, such as
- // char, unsigned char, uint8_t, etc.
- template <typename T> std::vector<T> ConsumeBytes(size_t num_bytes) {
- num_bytes = std::min(num_bytes, remaining_bytes_);
- return ConsumeBytes<T>(num_bytes, num_bytes);
- }
+ // See the implementation below (after the class definition) for more verbose
+ // comments for each of the methods.
- // Similar to |ConsumeBytes|, but also appends the terminator value at the end
- // of the resulting vector. Useful, when a mutable null-terminated C-string is
- // needed, for example. But that is a rare case. Better avoid it, if possible,
- // and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods.
+ // Methods returning std::vector of bytes. These are the most popular choice
+ // when splitting fuzzing input into pieces, as every piece is put into a
+ // separate buffer (i.e. ASan would catch any under-/overflow) and the memory
+ // will be released automatically.
+ template <typename T> std::vector<T> ConsumeBytes(size_t num_bytes);
template <typename T>
- std::vector<T> ConsumeBytesWithTerminator(size_t num_bytes,
- T terminator = 0) {
- num_bytes = std::min(num_bytes, remaining_bytes_);
- std::vector<T> result = ConsumeBytes<T>(num_bytes + 1, num_bytes);
- result.back() = terminator;
- return result;
- }
+ std::vector<T> ConsumeBytesWithTerminator(size_t num_bytes, T terminator = 0);
+ template <typename T> std::vector<T> ConsumeRemainingBytes();
- // Returns a std::string containing |num_bytes| of input data. Using this and
- // |.c_str()| on the resulting string is the best way to get an immutable
- // null-terminated C string. If fewer than |num_bytes| of data remain, returns
- // a shorter std::string containing all of the data that's left.
- std::string ConsumeBytesAsString(size_t num_bytes) {
- static_assert(sizeof(std::string::value_type) == sizeof(uint8_t),
- "ConsumeBytesAsString cannot convert the data to a string.");
-
- num_bytes = std::min(num_bytes, remaining_bytes_);
- std::string result(
- reinterpret_cast<const std::string::value_type *>(data_ptr_),
- num_bytes);
- Advance(num_bytes);
- return result;
- }
+ // Methods returning strings. Use only when you need a std::string or a null
+ // terminated C-string. Otherwise, prefer the methods returning std::vector.
+ std::string ConsumeBytesAsString(size_t num_bytes);
+ std::string ConsumeRandomLengthString(size_t max_length);
+ std::string ConsumeRandomLengthString();
+ std::string ConsumeRemainingBytesAsString();
- // Returns a number in the range [min, max] by consuming bytes from the
- // input data. The value might not be uniformly distributed in the given
- // range. If there's no input data left, always returns |min|. |min| must
- // be less than or equal to |max|.
- template <typename T> T ConsumeIntegralInRange(T min, T max) {
- static_assert(std::is_integral<T>::value, "An integral type is required.");
- static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
+ // Methods returning integer values.
+ template <typename T> T ConsumeIntegral();
+ template <typename T> T ConsumeIntegralInRange(T min, T max);
- if (min > max)
- abort();
+ // Methods returning floating point values.
+ template <typename T> T ConsumeFloatingPoint();
+ template <typename T> T ConsumeFloatingPointInRange(T min, T max);
- // Use the biggest type possible to hold the range and the result.
- uint64_t range = static_cast<uint64_t>(max) - min;
- uint64_t result = 0;
- size_t offset = 0;
-
- while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
- remaining_bytes_ != 0) {
- // Pull bytes off the end of the seed data. Experimentally, this seems to
- // allow the fuzzer to more easily explore the input space. This makes
- // sense, since it works by modifying inputs that caused new code to run,
- // and this data is often used to encode length of data read by
- // |ConsumeBytes|. Separating out read lengths makes it easier modify the
- // contents of the data that is actually read.
- --remaining_bytes_;
- result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
- offset += CHAR_BIT;
- }
+ // 0 <= return value <= 1.
+ template <typename T> T ConsumeProbability();
- // Avoid division by 0, in case |range + 1| results in overflow.
- if (range != std::numeric_limits<decltype(range)>::max())
- result = result % (range + 1);
+ bool ConsumeBool();
- return static_cast<T>(min + result);
- }
+ // Returns a value chosen from the given enum.
+ template <typename T> T ConsumeEnum();
- // Returns a std::string of length from 0 to |max_length|. When it runs out of
- // input data, returns what remains of the input. Designed to be more stable
- // with respect to a fuzzer inserting characters than just picking a random
- // length and then consuming that many bytes with |ConsumeBytes|.
- std::string ConsumeRandomLengthString(size_t max_length) {
- // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\"
- // followed by anything else to the end of the string. As a result of this
- // logic, a fuzzer can insert characters into the string, and the string
- // will be lengthened to include those new characters, resulting in a more
- // stable fuzzer than picking the length of a string independently from
- // picking its contents.
- std::string result;
-
- // Reserve the anticipated capaticity to prevent several reallocations.
- result.reserve(std::min(max_length, remaining_bytes_));
- for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) {
- char next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
- Advance(1);
- if (next == '\\' && remaining_bytes_ != 0) {
- next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
- Advance(1);
- if (next != '\\')
- break;
- }
- result += next;
- }
-
- result.shrink_to_fit();
- return result;
- }
+ // Returns a value from the given array.
+ template <typename T, size_t size> T PickValueInArray(const T (&array)[size]);
+ template <typename T, size_t size>
+ T PickValueInArray(const std::array<T, size> &array);
+ template <typename T> T PickValueInArray(std::initializer_list<const T> list);
- // Returns a std::vector containing all remaining bytes of the input data.
- template <typename T> std::vector<T> ConsumeRemainingBytes() {
- return ConsumeBytes<T>(remaining_bytes_);
- }
+ // Writes data to the given destination and returns number of bytes written.
+ size_t ConsumeData(void *destination, size_t num_bytes);
- // Returns a std::string containing all remaining bytes of the input data.
- // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string
- // object.
- std::string ConsumeRemainingBytesAsString() {
- return ConsumeBytesAsString(remaining_bytes_);
- }
+ // Reports the remaining bytes available for fuzzed input.
+ size_t remaining_bytes() { return remaining_bytes_; }
- // Returns a number in the range [Type's min, Type's max]. The value might
- // not be uniformly distributed in the given range. If there's no input data
- // left, always returns |min|.
- template <typename T> T ConsumeIntegral() {
- return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
- std::numeric_limits<T>::max());
- }
+ private:
+ FuzzedDataProvider(const FuzzedDataProvider &) = delete;
+ FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete;
- // Reads one byte and returns a bool, or false when no data remains.
- bool ConsumeBool() { return 1 & ConsumeIntegral<uint8_t>(); }
+ void CopyAndAdvance(void *destination, size_t num_bytes);
- // Returns a copy of the value selected from the given fixed-size |array|.
- template <typename T, size_t size>
- T PickValueInArray(const T (&array)[size]) {
- static_assert(size > 0, "The array must be non empty.");
- return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
- }
+ void Advance(size_t num_bytes);
template <typename T>
- T PickValueInArray(std::initializer_list<const T> list) {
- // TODO(Dor1s): switch to static_assert once C++14 is allowed.
- if (!list.size())
- abort();
-
- return *(list.begin() + ConsumeIntegralInRange<size_t>(0, list.size() - 1));
- }
-
- // Returns an enum value. The enum must start at 0 and be contiguous. It must
- // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as:
- // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue };
- template <typename T> T ConsumeEnum() {
- static_assert(std::is_enum<T>::value, "|T| must be an enum type.");
- return static_cast<T>(ConsumeIntegralInRange<uint32_t>(
- 0, static_cast<uint32_t>(T::kMaxValue)));
- }
+ std::vector<T> ConsumeBytes(size_t size, size_t num_bytes);
- // Returns a floating point number in the range [0.0, 1.0]. If there's no
- // input data left, always returns 0.
- template <typename T> T ConsumeProbability() {
- static_assert(std::is_floating_point<T>::value,
- "A floating point type is required.");
+ template <typename TS, typename TU> TS ConvertUnsignedToSigned(TU value);
- // Use different integral types for different floating point types in order
- // to provide better density of the resulting values.
- using IntegralType =
- typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t,
- uint64_t>::type;
+ const uint8_t *data_ptr_;
+ size_t remaining_bytes_;
+};
- T result = static_cast<T>(ConsumeIntegral<IntegralType>());
- result /= static_cast<T>(std::numeric_limits<IntegralType>::max());
- return result;
+// Returns a std::vector containing |num_bytes| of input data. If fewer than
+// |num_bytes| of data remain, returns a shorter std::vector containing all
+// of the data that's left. Can be used with any byte sized type, such as
+// char, unsigned char, uint8_t, etc.
+template <typename T>
+std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t num_bytes) {
+ num_bytes = std::min(num_bytes, remaining_bytes_);
+ return ConsumeBytes<T>(num_bytes, num_bytes);
+}
+
+// Similar to |ConsumeBytes|, but also appends the terminator value at the end
+// of the resulting vector. Useful, when a mutable null-terminated C-string is
+// needed, for example. But that is a rare case. Better avoid it, if possible,
+// and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods.
+template <typename T>
+std::vector<T> FuzzedDataProvider::ConsumeBytesWithTerminator(size_t num_bytes,
+ T terminator) {
+ num_bytes = std::min(num_bytes, remaining_bytes_);
+ std::vector<T> result = ConsumeBytes<T>(num_bytes + 1, num_bytes);
+ result.back() = terminator;
+ return result;
+}
+
+// Returns a std::vector containing all remaining bytes of the input data.
+template <typename T>
+std::vector<T> FuzzedDataProvider::ConsumeRemainingBytes() {
+ return ConsumeBytes<T>(remaining_bytes_);
+}
+
+// Returns a std::string containing |num_bytes| of input data. Using this and
+// |.c_str()| on the resulting string is the best way to get an immutable
+// null-terminated C string. If fewer than |num_bytes| of data remain, returns
+// a shorter std::string containing all of the data that's left.
+inline std::string FuzzedDataProvider::ConsumeBytesAsString(size_t num_bytes) {
+ static_assert(sizeof(std::string::value_type) == sizeof(uint8_t),
+ "ConsumeBytesAsString cannot convert the data to a string.");
+
+ num_bytes = std::min(num_bytes, remaining_bytes_);
+ std::string result(
+ reinterpret_cast<const std::string::value_type *>(data_ptr_), num_bytes);
+ Advance(num_bytes);
+ return result;
+}
+
+// Returns a std::string of length from 0 to |max_length|. When it runs out of
+// input data, returns what remains of the input. Designed to be more stable
+// with respect to a fuzzer inserting characters than just picking a random
+// length and then consuming that many bytes with |ConsumeBytes|.
+inline std::string
+FuzzedDataProvider::ConsumeRandomLengthString(size_t max_length) {
+ // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\"
+ // followed by anything else to the end of the string. As a result of this
+ // logic, a fuzzer can insert characters into the string, and the string
+ // will be lengthened to include those new characters, resulting in a more
+ // stable fuzzer than picking the length of a string independently from
+ // picking its contents.
+ std::string result;
+
+ // Reserve the anticipated capaticity to prevent several reallocations.
+ result.reserve(std::min(max_length, remaining_bytes_));
+ for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) {
+ char next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
+ Advance(1);
+ if (next == '\\' && remaining_bytes_ != 0) {
+ next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
+ Advance(1);
+ if (next != '\\')
+ break;
+ }
+ result += next;
}
- // Returns a floating point value in the range [Type's lowest, Type's max] by
- // consuming bytes from the input data. If there's no input data left, always
- // returns approximately 0.
- template <typename T> T ConsumeFloatingPoint() {
- return ConsumeFloatingPointInRange<T>(std::numeric_limits<T>::lowest(),
- std::numeric_limits<T>::max());
+ result.shrink_to_fit();
+ return result;
+}
+
+// Returns a std::string of length from 0 to |remaining_bytes_|.
+inline std::string FuzzedDataProvider::ConsumeRandomLengthString() {
+ return ConsumeRandomLengthString(remaining_bytes_);
+}
+
+// Returns a std::string containing all remaining bytes of the input data.
+// Prefer using |ConsumeRemainingBytes| unless you actually need a std::string
+// object.
+inline std::string FuzzedDataProvider::ConsumeRemainingBytesAsString() {
+ return ConsumeBytesAsString(remaining_bytes_);
+}
+
+// Returns a number in the range [Type's min, Type's max]. The value might
+// not be uniformly distributed in the given range. If there's no input data
+// left, always returns |min|.
+template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
+ return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());
+}
+
+// Returns a number in the range [min, max] by consuming bytes from the
+// input data. The value might not be uniformly distributed in the given
+// range. If there's no input data left, always returns |min|. |min| must
+// be less than or equal to |max|.
+template <typename T>
+T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
+ static_assert(std::is_integral<T>::value, "An integral type is required.");
+ static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
+
+ if (min > max)
+ abort();
+
+ // Use the biggest type possible to hold the range and the result.
+ uint64_t range = static_cast<uint64_t>(max) - min;
+ uint64_t result = 0;
+ size_t offset = 0;
+
+ while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
+ remaining_bytes_ != 0) {
+ // Pull bytes off the end of the seed data. Experimentally, this seems to
+ // allow the fuzzer to more easily explore the input space. This makes
+ // sense, since it works by modifying inputs that caused new code to run,
+ // and this data is often used to encode length of data read by
+ // |ConsumeBytes|. Separating out read lengths makes it easier modify the
+ // contents of the data that is actually read.
+ --remaining_bytes_;
+ result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
+ offset += CHAR_BIT;
}
- // Returns a floating point value in the given range by consuming bytes from
- // the input data. If there's no input data left, returns |min|. Note that
- // |min| must be less than or equal to |max|.
- template <typename T> T ConsumeFloatingPointInRange(T min, T max) {
- if (min > max)
- abort();
-
- T range = .0;
- T result = min;
- constexpr T zero(.0);
- if (max > zero && min < zero && max > min + std::numeric_limits<T>::max()) {
- // The diff |max - min| would overflow the given floating point type. Use
- // the half of the diff as the range and consume a bool to decide whether
- // the result is in the first of the second part of the diff.
- range = (max / 2.0) - (min / 2.0);
- if (ConsumeBool()) {
- result += range;
- }
- } else {
- range = max - min;
+ // Avoid division by 0, in case |range + 1| results in overflow.
+ if (range != std::numeric_limits<decltype(range)>::max())
+ result = result % (range + 1);
+
+ return static_cast<T>(min + result);
+}
+
+// Returns a floating point value in the range [Type's lowest, Type's max] by
+// consuming bytes from the input data. If there's no input data left, always
+// returns approximately 0.
+template <typename T> T FuzzedDataProvider::ConsumeFloatingPoint() {
+ return ConsumeFloatingPointInRange<T>(std::numeric_limits<T>::lowest(),
+ std::numeric_limits<T>::max());
+}
+
+// Returns a floating point value in the given range by consuming bytes from
+// the input data. If there's no input data left, returns |min|. Note that
+// |min| must be less than or equal to |max|.
+template <typename T>
+T FuzzedDataProvider::ConsumeFloatingPointInRange(T min, T max) {
+ if (min > max)
+ abort();
+
+ T range = .0;
+ T result = min;
+ constexpr T zero(.0);
+ if (max > zero && min < zero && max > min + std::numeric_limits<T>::max()) {
+ // The diff |max - min| would overflow the given floating point type. Use
+ // the half of the diff as the range and consume a bool to decide whether
+ // the result is in the first of the second part of the diff.
+ range = (max / 2.0) - (min / 2.0);
+ if (ConsumeBool()) {
+ result += range;
}
-
- return result + range * ConsumeProbability<T>();
+ } else {
+ range = max - min;
}
- // Reports the remaining bytes available for fuzzed input.
- size_t remaining_bytes() { return remaining_bytes_; }
-
- private:
- FuzzedDataProvider(const FuzzedDataProvider &) = delete;
- FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete;
-
- void Advance(size_t num_bytes) {
- if (num_bytes > remaining_bytes_)
+ return result + range * ConsumeProbability<T>();
+}
+
+// Returns a floating point number in the range [0.0, 1.0]. If there's no
+// input data left, always returns 0.
+template <typename T> T FuzzedDataProvider::ConsumeProbability() {
+ static_assert(std::is_floating_point<T>::value,
+ "A floating point type is required.");
+
+ // Use different integral types for different floating point types in order
+ // to provide better density of the resulting values.
+ using IntegralType =
+ typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t,
+ uint64_t>::type;
+
+ T result = static_cast<T>(ConsumeIntegral<IntegralType>());
+ result /= static_cast<T>(std::numeric_limits<IntegralType>::max());
+ return result;
+}
+
+// Reads one byte and returns a bool, or false when no data remains.
+inline bool FuzzedDataProvider::ConsumeBool() {
+ return 1 & ConsumeIntegral<uint8_t>();
+}
+
+// Returns an enum value. The enum must start at 0 and be contiguous. It must
+// also contain |kMaxValue| aliased to its largest (inclusive) value. Such as:
+// enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue };
+template <typename T> T FuzzedDataProvider::ConsumeEnum() {
+ static_assert(std::is_enum<T>::value, "|T| must be an enum type.");
+ return static_cast<T>(
+ ConsumeIntegralInRange<uint32_t>(0, static_cast<uint32_t>(T::kMaxValue)));
+}
+
+// Returns a copy of the value selected from the given fixed-size |array|.
+template <typename T, size_t size>
+T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) {
+ static_assert(size > 0, "The array must be non empty.");
+ return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
+}
+
+template <typename T, size_t size>
+T FuzzedDataProvider::PickValueInArray(const std::array<T, size> &array) {
+ static_assert(size > 0, "The array must be non empty.");
+ return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
+}
+
+template <typename T>
+T FuzzedDataProvider::PickValueInArray(std::initializer_list<const T> list) {
+ // TODO(Dor1s): switch to static_assert once C++14 is allowed.
+ if (!list.size())
+ abort();
+
+ return *(list.begin() + ConsumeIntegralInRange<size_t>(0, list.size() - 1));
+}
+
+// Writes |num_bytes| of input data to the given destination pointer. If there
+// is not enough data left, writes all remaining bytes. Return value is the
+// number of bytes written.
+// In general, it's better to avoid using this function, but it may be useful
+// in cases when it's necessary to fill a certain buffer or object with
+// fuzzing data.
+inline size_t FuzzedDataProvider::ConsumeData(void *destination,
+ size_t num_bytes) {
+ num_bytes = std::min(num_bytes, remaining_bytes_);
+ CopyAndAdvance(destination, num_bytes);
+ return num_bytes;
+}
+
+// Private methods.
+inline void FuzzedDataProvider::CopyAndAdvance(void *destination,
+ size_t num_bytes) {
+ std::memcpy(destination, data_ptr_, num_bytes);
+ Advance(num_bytes);
+}
+
+inline void FuzzedDataProvider::Advance(size_t num_bytes) {
+ if (num_bytes > remaining_bytes_)
+ abort();
+
+ data_ptr_ += num_bytes;
+ remaining_bytes_ -= num_bytes;
+}
+
+template <typename T>
+std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t size, size_t num_bytes) {
+ static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type.");
+
+ // The point of using the size-based constructor below is to increase the
+ // odds of having a vector object with capacity being equal to the length.
+ // That part is always implementation specific, but at least both libc++ and
+ // libstdc++ allocate the requested number of bytes in that constructor,
+ // which seems to be a natural choice for other implementations as well.
+ // To increase the odds even more, we also call |shrink_to_fit| below.
+ std::vector<T> result(size);
+ if (size == 0) {
+ if (num_bytes != 0)
abort();
-
- data_ptr_ += num_bytes;
- remaining_bytes_ -= num_bytes;
- }
-
- template <typename T>
- std::vector<T> ConsumeBytes(size_t size, size_t num_bytes_to_consume) {
- static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type.");
-
- // The point of using the size-based constructor below is to increase the
- // odds of having a vector object with capacity being equal to the length.
- // That part is always implementation specific, but at least both libc++ and
- // libstdc++ allocate the requested number of bytes in that constructor,
- // which seems to be a natural choice for other implementations as well.
- // To increase the odds even more, we also call |shrink_to_fit| below.
- std::vector<T> result(size);
- if (size == 0) {
- if (num_bytes_to_consume != 0)
- abort();
- return result;
- }
-
- std::memcpy(result.data(), data_ptr_, num_bytes_to_consume);
- Advance(num_bytes_to_consume);
-
- // Even though |shrink_to_fit| is also implementation specific, we expect it
- // to provide an additional assurance in case vector's constructor allocated
- // a buffer which is larger than the actual amount of data we put inside it.
- result.shrink_to_fit();
return result;
}
- template <typename TS, typename TU> TS ConvertUnsignedToSigned(TU value) {
- static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types.");
- static_assert(!std::numeric_limits<TU>::is_signed,
- "Source type must be unsigned.");
-
- // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream.
- if (std::numeric_limits<TS>::is_modulo)
- return static_cast<TS>(value);
-
- // Avoid using implementation-defined unsigned to signer conversions.
- // To learn more, see https://stackoverflow.com/questions/13150449.
- if (value <= std::numeric_limits<TS>::max()) {
- return static_cast<TS>(value);
- } else {
- constexpr auto TS_min = std::numeric_limits<TS>::min();
- return TS_min + static_cast<char>(value - TS_min);
- }
+ CopyAndAdvance(result.data(), num_bytes);
+
+ // Even though |shrink_to_fit| is also implementation specific, we expect it
+ // to provide an additional assurance in case vector's constructor allocated
+ // a buffer which is larger than the actual amount of data we put inside it.
+ result.shrink_to_fit();
+ return result;
+}
+
+template <typename TS, typename TU>
+TS FuzzedDataProvider::ConvertUnsignedToSigned(TU value) {
+ static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types.");
+ static_assert(!std::numeric_limits<TU>::is_signed,
+ "Source type must be unsigned.");
+
+ // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream.
+ if (std::numeric_limits<TS>::is_modulo)
+ return static_cast<TS>(value);
+
+ // Avoid using implementation-defined unsigned to signed conversions.
+ // To learn more, see https://stackoverflow.com/questions/13150449.
+ if (value <= std::numeric_limits<TS>::max()) {
+ return static_cast<TS>(value);
+ } else {
+ constexpr auto TS_min = std::numeric_limits<TS>::min();
+ return TS_min + static_cast<char>(value - TS_min);
}
-
- const uint8_t *data_ptr_;
- size_t remaining_bytes_;
-};
+}
#endif // LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_
diff --git a/src/test/fuzz/addition_overflow.cpp b/src/test/fuzz/addition_overflow.cpp
index a455992b13..c6cfbd8d30 100644
--- a/src/test/fuzz/addition_overflow.cpp
+++ b/src/test/fuzz/addition_overflow.cpp
@@ -14,7 +14,7 @@
#if __has_builtin(__builtin_add_overflow)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
+#elif defined(__GNUC__)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif
@@ -40,7 +40,7 @@ void TestAdditionOverflow(FuzzedDataProvider& fuzzed_data_provider)
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(addition_overflow)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
TestAdditionOverflow<int64_t>(fuzzed_data_provider);
diff --git a/src/test/fuzz/addrdb.cpp b/src/test/fuzz/addrdb.cpp
index 16b1cb755a..d15c785673 100644
--- a/src/test/fuzz/addrdb.cpp
+++ b/src/test/fuzz/addrdb.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(addrdb)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index 0ceeea2d36..1ea6b3d01d 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -17,17 +17,27 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_addrman()
{
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+class CAddrManDeterministic : public CAddrMan
{
- FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+public:
+ void MakeDeterministic(const uint256& random_seed)
+ {
+ insecure_rand = FastRandomContext{random_seed};
+ Clear();
+ }
+};
+FUZZ_TARGET_INIT(addrman, initialize_addrman)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
- CAddrMan addr_man;
+ CAddrManDeterministic addr_man;
+ addr_man.MakeDeterministic(ConsumeUInt256(fuzzed_data_provider));
if (fuzzed_data_provider.ConsumeBool()) {
addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (!SanityCheckASMap(addr_man.m_asmap)) {
@@ -35,83 +45,71 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
}
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
- case 0: {
- addr_man.Clear();
- break;
- }
- case 1: {
- addr_man.ResolveCollisions();
- break;
- }
- case 2: {
- (void)addr_man.SelectTriedCollision();
- break;
- }
- case 3: {
- (void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
- break;
- }
- case 4: {
- (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
- break;
- }
- case 5: {
- const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
- if (opt_address && opt_net_addr) {
- addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
- }
- break;
- }
- case 6: {
- std::vector<CAddress> addresses;
- while (fuzzed_data_provider.ConsumeBool()) {
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ addr_man.Clear();
+ },
+ [&] {
+ addr_man.ResolveCollisions();
+ },
+ [&] {
+ (void)addr_man.SelectTriedCollision();
+ },
+ [&] {
+ (void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ },
+ [&] {
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- if (!opt_address) {
- break;
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_address && opt_net_addr) {
+ addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
}
- addresses.push_back(*opt_address);
- }
- const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
- if (opt_net_addr) {
- addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
- }
- break;
- }
- case 7: {
- const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
- if (opt_service) {
- addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
- }
- break;
- }
- case 8: {
- const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
- if (opt_service) {
- addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
- }
- break;
- }
- case 9: {
- const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
- if (opt_service) {
- addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
- }
- break;
- }
- case 10: {
- const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
- if (opt_service) {
- addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
- }
- break;
- }
- case 11: {
- (void)addr_man.Check();
- break;
- }
- }
+ },
+ [&] {
+ std::vector<CAddress> addresses;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ if (!opt_address) {
+ break;
+ }
+ addresses.push_back(*opt_address);
+ }
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_net_addr) {
+ addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
+ }
+ },
+ [&] {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ },
+ [&] {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ },
+ [&] {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
+ }
+ },
+ [&] {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
+ }
+ },
+ [&] {
+ (void)addr_man.Check();
+ });
}
(void)addr_man.size();
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
diff --git a/src/test/fuzz/asmap.cpp b/src/test/fuzz/asmap.cpp
index e3aefa18a3..4c5bc0cbf2 100644
--- a/src/test/fuzz/asmap.cpp
+++ b/src/test/fuzz/asmap.cpp
@@ -27,7 +27,7 @@ static const std::vector<bool> IPV4_PREFIX_ASMAP = {
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)
+FUZZ_TARGET(asmap)
{
// Encoding: [7 bits: asmap size] [1 bit: ipv6?] [3-130 bytes: asmap] [4 or 16 bytes: addr]
if (buffer.size() < 1 + 3 + 4) return;
diff --git a/src/test/fuzz/asmap_direct.cpp b/src/test/fuzz/asmap_direct.cpp
index 2d21eff9d6..8b7822dc16 100644
--- a/src/test/fuzz/asmap_direct.cpp
+++ b/src/test/fuzz/asmap_direct.cpp
@@ -11,7 +11,7 @@
#include <assert.h>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(asmap_direct)
{
// Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
std::optional<size_t> sep_pos_opt;
diff --git a/src/test/fuzz/autofile.cpp b/src/test/fuzz/autofile.cpp
index 7ea0bdd2a7..9ecd172e19 100644
--- a/src/test/fuzz/autofile.cpp
+++ b/src/test/fuzz/autofile.cpp
@@ -15,49 +15,43 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(autofile)
{
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;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ 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&) {
+ }
+ },
+ [&] {
+ 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&) {
+ }
+ },
+ [&] {
+ try {
+ auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ } catch (const std::ios_base::failure&) {
+ }
+ },
+ [&] {
+ auto_file.fclose();
+ },
+ [&] {
+ ReadFromStream(fuzzed_data_provider, auto_file);
+ },
+ [&] {
+ WriteToStream(fuzzed_data_provider, auto_file);
+ });
}
(void)auto_file.Get();
(void)auto_file.GetType();
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index fc4a1d9261..e0715f3e29 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -24,64 +24,57 @@ int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
}
} // namespace
-void initialize()
+void initialize_banman()
{
- InitializeFuzzingContext();
+ static const auto testing_setup = MakeFuzzingContext<>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(banman, initialize_banman)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
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;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ ban_man.ClearBanned();
+ },
+ [] {},
+ [&] {
+ ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
+ },
+ [&] {
+ ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
+ },
+ [&] {
+ ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
+ },
+ [&] {
+ ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
+ },
+ [&] {
+ banmap_t banmap;
+ ban_man.GetBanned(banmap);
+ },
+ [&] {
+ ban_man.DumpBanlist();
+ },
+ [] {},
+ [&] {
+ ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
+ });
}
}
fs::remove(banlist_file);
diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp
index 8d49f93c2f..4470e13a61 100644
--- a/src/test/fuzz/base_encode_decode.cpp
+++ b/src/test/fuzz/base_encode_decode.cpp
@@ -14,7 +14,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(base_encode_decode)
{
const std::string random_encoded_string(buffer.begin(), buffer.end());
diff --git a/src/test/fuzz/bech32.cpp b/src/test/fuzz/bech32.cpp
index 8b91f9bc96..95cd4b413f 100644
--- a/src/test/fuzz/bech32.cpp
+++ b/src/test/fuzz/bech32.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -13,7 +13,7 @@
#include <utility>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(bech32)
{
const std::string random_string(buffer.begin(), buffer.end());
const std::pair<std::string, std::vector<uint8_t>> r1 = bech32::Decode(random_string);
diff --git a/src/test/fuzz/block.cpp b/src/test/fuzz/block.cpp
index 91bd34a251..65a33de4b4 100644
--- a/src/test/fuzz/block.cpp
+++ b/src/test/fuzz/block.cpp
@@ -17,13 +17,13 @@
#include <cassert>
#include <string>
-void initialize()
+void initialize_block()
{
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(block, initialize_block)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CBlock block;
diff --git a/src/test/fuzz/block_header.cpp b/src/test/fuzz/block_header.cpp
index 09c2b4a951..c73270dcb3 100644
--- a/src/test/fuzz/block_header.cpp
+++ b/src/test/fuzz/block_header.cpp
@@ -14,7 +14,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(block_header)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
diff --git a/src/test/fuzz/blockfilter.cpp b/src/test/fuzz/blockfilter.cpp
index 7232325a20..7fa06085f8 100644
--- a/src/test/fuzz/blockfilter.cpp
+++ b/src/test/fuzz/blockfilter.cpp
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(blockfilter)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider);
diff --git a/src/test/fuzz/bloom_filter.cpp b/src/test/fuzz/bloom_filter.cpp
index d955c71bc9..d43c182644 100644
--- a/src/test/fuzz/bloom_filter.cpp
+++ b/src/test/fuzz/bloom_filter.cpp
@@ -15,7 +15,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(bloom_filter)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@@ -25,47 +25,43 @@ 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, 3)) {
- case 0: {
- const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
- (void)bloom_filter.contains(b);
- bloom_filter.insert(b);
- const bool present = bloom_filter.contains(b);
- assert(present);
- break;
- }
- case 1: {
- const std::optional<COutPoint> out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
- if (!out_point) {
- break;
- }
- (void)bloom_filter.contains(*out_point);
- bloom_filter.insert(*out_point);
- const bool present = bloom_filter.contains(*out_point);
- assert(present);
- break;
- }
- case 2: {
- const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
- if (!u256) {
- break;
- }
- (void)bloom_filter.contains(*u256);
- bloom_filter.insert(*u256);
- const bool present = bloom_filter.contains(*u256);
- assert(present);
- break;
- }
- case 3: {
- const std::optional<CMutableTransaction> mut_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
- if (!mut_tx) {
- break;
- }
- const CTransaction tx{*mut_tx};
- (void)bloom_filter.IsRelevantAndUpdate(tx);
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ (void)bloom_filter.contains(b);
+ bloom_filter.insert(b);
+ const bool present = bloom_filter.contains(b);
+ assert(present);
+ },
+ [&] {
+ const std::optional<COutPoint> out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
+ if (!out_point) {
+ return;
+ }
+ (void)bloom_filter.contains(*out_point);
+ bloom_filter.insert(*out_point);
+ const bool present = bloom_filter.contains(*out_point);
+ assert(present);
+ },
+ [&] {
+ const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
+ if (!u256) {
+ return;
+ }
+ (void)bloom_filter.contains(*u256);
+ bloom_filter.insert(*u256);
+ const bool present = bloom_filter.contains(*u256);
+ assert(present);
+ },
+ [&] {
+ const std::optional<CMutableTransaction> mut_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mut_tx) {
+ return;
+ }
+ const CTransaction tx{*mut_tx};
+ (void)bloom_filter.IsRelevantAndUpdate(tx);
+ });
(void)bloom_filter.IsWithinSizeConstraints();
}
}
diff --git a/src/test/fuzz/buffered_file.cpp b/src/test/fuzz/buffered_file.cpp
index e575640be5..3a1b2dbbe7 100644
--- a/src/test/fuzz/buffered_file.cpp
+++ b/src/test/fuzz/buffered_file.cpp
@@ -15,7 +15,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(buffered_file)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
@@ -31,41 +31,36 @@ void test_one_input(const std::vector<uint8_t>& buffer)
if (opt_buffered_file && fuzzed_file != nullptr) {
bool setpos_fail = false;
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 4)) {
- 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->SetLimit(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
- break;
- }
- case 2: {
- if (!opt_buffered_file->SetPos(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096))) {
- setpos_fail = true;
- }
- break;
- }
- case 3: {
- 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 4: {
- ReadFromStream(fuzzed_data_provider, *opt_buffered_file);
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ 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&) {
+ }
+ },
+ [&] {
+ opt_buffered_file->SetLimit(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
+ },
+ [&] {
+ if (!opt_buffered_file->SetPos(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096))) {
+ setpos_fail = true;
+ }
+ },
+ [&] {
+ if (setpos_fail) {
+ // Calling FindByte(...) after a failed SetPos(...) call may result in an infinite loop.
+ return;
+ }
+ try {
+ opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>());
+ } catch (const std::ios_base::failure&) {
+ }
+ },
+ [&] {
+ ReadFromStream(fuzzed_data_provider, *opt_buffered_file);
+ });
}
opt_buffered_file->GetPos();
opt_buffered_file->GetType();
diff --git a/src/test/fuzz/chain.cpp b/src/test/fuzz/chain.cpp
index 47c71850ce..9f7074b423 100644
--- a/src/test/fuzz/chain.cpp
+++ b/src/test/fuzz/chain.cpp
@@ -11,7 +11,7 @@
#include <optional>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(chain)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::optional<CDiskBlockIndex> disk_block_index = ConsumeDeserializable<CDiskBlockIndex>(fuzzed_data_provider);
diff --git a/src/test/fuzz/checkqueue.cpp b/src/test/fuzz/checkqueue.cpp
index c69043bb6b..0b16f0f0d5 100644
--- a/src/test/fuzz/checkqueue.cpp
+++ b/src/test/fuzz/checkqueue.cpp
@@ -32,7 +32,7 @@ struct DumbCheck {
};
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(checkqueue)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index ac034809b0..8ece94d771 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -34,14 +34,12 @@ bool operator==(const Coin& a, const Coin& b)
}
} // namespace
-void initialize()
+void initialize_coins_view()
{
- static const ECCVerifyHandle ecc_verify_handle;
- ECC_Start();
- SelectParams(CBaseChainParams::REGTEST);
+ static const auto testing_setup = MakeFuzzingContext<const TestingSetup>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
CCoinsView backend_coins_view;
@@ -50,103 +48,93 @@ void test_one_input(const std::vector<uint8_t>& buffer)
Coin random_coin;
CMutableTransaction random_mutable_transaction;
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 9)) {
- case 0: {
- if (random_coin.IsSpent()) {
- break;
- }
- Coin coin = random_coin;
- bool expected_code_path = false;
- const bool possible_overwrite = fuzzed_data_provider.ConsumeBool();
- try {
- coins_view_cache.AddCoin(random_out_point, std::move(coin), possible_overwrite);
- expected_code_path = true;
- } catch (const std::logic_error& e) {
- if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) {
- assert(!possible_overwrite);
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ if (random_coin.IsSpent()) {
+ return;
+ }
+ Coin coin = random_coin;
+ bool expected_code_path = false;
+ const bool possible_overwrite = fuzzed_data_provider.ConsumeBool();
+ try {
+ coins_view_cache.AddCoin(random_out_point, std::move(coin), possible_overwrite);
expected_code_path = true;
+ } catch (const std::logic_error& e) {
+ if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) {
+ assert(!possible_overwrite);
+ expected_code_path = true;
+ }
}
- }
- assert(expected_code_path);
- break;
- }
- case 1: {
- (void)coins_view_cache.Flush();
- break;
- }
- case 2: {
- coins_view_cache.SetBestBlock(ConsumeUInt256(fuzzed_data_provider));
- break;
- }
- case 3: {
- Coin move_to;
- (void)coins_view_cache.SpendCoin(random_out_point, fuzzed_data_provider.ConsumeBool() ? &move_to : nullptr);
- break;
- }
- case 4: {
- coins_view_cache.Uncache(random_out_point);
- break;
- }
- case 5: {
- if (fuzzed_data_provider.ConsumeBool()) {
- backend_coins_view = CCoinsView{};
- }
- coins_view_cache.SetBackend(backend_coins_view);
- break;
- }
- case 6: {
- const std::optional<COutPoint> opt_out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
- if (!opt_out_point) {
- break;
- }
- random_out_point = *opt_out_point;
- break;
- }
- case 7: {
- const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider);
- if (!opt_coin) {
- break;
- }
- random_coin = *opt_coin;
- break;
- }
- case 8: {
- const std::optional<CMutableTransaction> opt_mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
- if (!opt_mutable_transaction) {
- break;
- }
- random_mutable_transaction = *opt_mutable_transaction;
- break;
- }
- case 9: {
- CCoinsMap coins_map;
- while (fuzzed_data_provider.ConsumeBool()) {
- CCoinsCacheEntry coins_cache_entry;
- coins_cache_entry.flags = fuzzed_data_provider.ConsumeIntegral<unsigned char>();
+ assert(expected_code_path);
+ },
+ [&] {
+ (void)coins_view_cache.Flush();
+ },
+ [&] {
+ coins_view_cache.SetBestBlock(ConsumeUInt256(fuzzed_data_provider));
+ },
+ [&] {
+ Coin move_to;
+ (void)coins_view_cache.SpendCoin(random_out_point, fuzzed_data_provider.ConsumeBool() ? &move_to : nullptr);
+ },
+ [&] {
+ coins_view_cache.Uncache(random_out_point);
+ },
+ [&] {
if (fuzzed_data_provider.ConsumeBool()) {
- coins_cache_entry.coin = random_coin;
- } else {
- const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider);
- if (!opt_coin) {
- break;
+ backend_coins_view = CCoinsView{};
+ }
+ coins_view_cache.SetBackend(backend_coins_view);
+ },
+ [&] {
+ const std::optional<COutPoint> opt_out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
+ if (!opt_out_point) {
+ return;
+ }
+ random_out_point = *opt_out_point;
+ },
+ [&] {
+ const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider);
+ if (!opt_coin) {
+ return;
+ }
+ random_coin = *opt_coin;
+ },
+ [&] {
+ const std::optional<CMutableTransaction> opt_mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!opt_mutable_transaction) {
+ return;
+ }
+ random_mutable_transaction = *opt_mutable_transaction;
+ },
+ [&] {
+ CCoinsMap coins_map;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ CCoinsCacheEntry coins_cache_entry;
+ coins_cache_entry.flags = fuzzed_data_provider.ConsumeIntegral<unsigned char>();
+ if (fuzzed_data_provider.ConsumeBool()) {
+ coins_cache_entry.coin = random_coin;
+ } else {
+ const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider);
+ if (!opt_coin) {
+ return;
+ }
+ coins_cache_entry.coin = *opt_coin;
}
- coins_cache_entry.coin = *opt_coin;
+ coins_map.emplace(random_out_point, std::move(coins_cache_entry));
}
- coins_map.emplace(random_out_point, std::move(coins_cache_entry));
- }
- bool expected_code_path = false;
- try {
- coins_view_cache.BatchWrite(coins_map, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock());
- expected_code_path = true;
- } catch (const std::logic_error& e) {
- if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) {
+ bool expected_code_path = false;
+ try {
+ coins_view_cache.BatchWrite(coins_map, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock());
expected_code_path = true;
+ } catch (const std::logic_error& e) {
+ if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) {
+ expected_code_path = true;
+ }
}
- }
- assert(expected_code_path);
- break;
- }
- }
+ assert(expected_code_path);
+ });
}
{
@@ -199,97 +187,90 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
if (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 6)) {
- case 0: {
- const CTransaction transaction{random_mutable_transaction};
- bool is_spent = false;
- for (const CTxOut& tx_out : transaction.vout) {
- if (Coin{tx_out, 0, transaction.IsCoinBase()}.IsSpent()) {
- is_spent = true;
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const CTransaction transaction{random_mutable_transaction};
+ bool is_spent = false;
+ for (const CTxOut& tx_out : transaction.vout) {
+ if (Coin{tx_out, 0, transaction.IsCoinBase()}.IsSpent()) {
+ is_spent = true;
+ }
+ }
+ if (is_spent) {
+ // Avoid:
+ // coins.cpp:69: void CCoinsViewCache::AddCoin(const COutPoint &, Coin &&, bool): Assertion `!coin.IsSpent()' failed.
+ return;
}
- }
- if (is_spent) {
- // Avoid:
- // coins.cpp:69: void CCoinsViewCache::AddCoin(const COutPoint &, Coin &&, bool): Assertion `!coin.IsSpent()' failed.
- break;
- }
- bool expected_code_path = false;
- const int height = fuzzed_data_provider.ConsumeIntegral<int>();
- const bool possible_overwrite = fuzzed_data_provider.ConsumeBool();
- try {
- AddCoins(coins_view_cache, transaction, height, possible_overwrite);
- expected_code_path = true;
- } catch (const std::logic_error& e) {
- if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) {
- assert(!possible_overwrite);
+ bool expected_code_path = false;
+ const int height = fuzzed_data_provider.ConsumeIntegral<int>();
+ const bool possible_overwrite = fuzzed_data_provider.ConsumeBool();
+ try {
+ AddCoins(coins_view_cache, transaction, height, possible_overwrite);
expected_code_path = true;
+ } catch (const std::logic_error& e) {
+ if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) {
+ assert(!possible_overwrite);
+ expected_code_path = true;
+ }
}
- }
- assert(expected_code_path);
- break;
- }
- case 1: {
- (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, false);
- (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, true);
- break;
- }
- case 2: {
- TxValidationState state;
- CAmount tx_fee_out;
- const CTransaction transaction{random_mutable_transaction};
- if (ContainsSpentInput(transaction, coins_view_cache)) {
- // Avoid:
- // consensus/tx_verify.cpp:171: bool Consensus::CheckTxInputs(const CTransaction &, TxValidationState &, const CCoinsViewCache &, int, CAmount &): Assertion `!coin.IsSpent()' failed.
- break;
- }
- try {
- (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out);
- assert(MoneyRange(tx_fee_out));
- } catch (const std::runtime_error&) {
- }
- break;
- }
- case 3: {
- const CTransaction transaction{random_mutable_transaction};
- if (ContainsSpentInput(transaction, coins_view_cache)) {
- // Avoid:
- // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
- break;
- }
- (void)GetP2SHSigOpCount(transaction, coins_view_cache);
- break;
- }
- case 4: {
- const CTransaction transaction{random_mutable_transaction};
- if (ContainsSpentInput(transaction, coins_view_cache)) {
- // Avoid:
- // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
- break;
- }
- const int flags = fuzzed_data_provider.ConsumeIntegral<int>();
- if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
- // Avoid:
- // script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed.
- break;
- }
- (void)GetTransactionSigOpCost(transaction, coins_view_cache, flags);
- break;
- }
- case 5: {
- CCoinsStats stats;
- bool expected_code_path = false;
- try {
- (void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED);
- } catch (const std::logic_error&) {
- expected_code_path = true;
- }
- assert(expected_code_path);
- break;
- }
- case 6: {
- (void)IsWitnessStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
- break;
- }
- }
+ assert(expected_code_path);
+ },
+ [&] {
+ (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, false);
+ (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, true);
+ },
+ [&] {
+ TxValidationState state;
+ CAmount tx_fee_out;
+ const CTransaction transaction{random_mutable_transaction};
+ if (ContainsSpentInput(transaction, coins_view_cache)) {
+ // Avoid:
+ // consensus/tx_verify.cpp:171: bool Consensus::CheckTxInputs(const CTransaction &, TxValidationState &, const CCoinsViewCache &, int, CAmount &): Assertion `!coin.IsSpent()' failed.
+ return;
+ }
+ try {
+ (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out);
+ assert(MoneyRange(tx_fee_out));
+ } catch (const std::runtime_error&) {
+ }
+ },
+ [&] {
+ const CTransaction transaction{random_mutable_transaction};
+ if (ContainsSpentInput(transaction, coins_view_cache)) {
+ // Avoid:
+ // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
+ return;
+ }
+ (void)GetP2SHSigOpCount(transaction, coins_view_cache);
+ },
+ [&] {
+ const CTransaction transaction{random_mutable_transaction};
+ if (ContainsSpentInput(transaction, coins_view_cache)) {
+ // Avoid:
+ // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
+ return;
+ }
+ const int flags = fuzzed_data_provider.ConsumeIntegral<int>();
+ if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
+ // Avoid:
+ // script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed.
+ return;
+ }
+ (void)GetTransactionSigOpCost(transaction, coins_view_cache, flags);
+ },
+ [&] {
+ CCoinsStats stats;
+ bool expected_code_path = false;
+ try {
+ (void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED);
+ } catch (const std::logic_error&) {
+ expected_code_path = true;
+ }
+ assert(expected_code_path);
+ },
+ [&] {
+ (void)IsWitnessStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
+ });
}
}
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
index 6521c3f3b2..71b4b00116 100644
--- a/src/test/fuzz/connman.cpp
+++ b/src/test/fuzz/connman.cpp
@@ -15,14 +15,15 @@
#include <cstdint>
#include <vector>
-void initialize()
+void initialize_connman()
{
- InitializeFuzzingContext();
+ static const auto testing_setup = MakeFuzzingContext<>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(connman, initialize_connman)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeBool()};
CAddress random_address;
CNetAddr random_netaddr;
@@ -31,121 +32,107 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CSubNet random_subnet;
std::string random_string;
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 30)) {
- case 0:
- random_address = ConsumeAddress(fuzzed_data_provider);
- break;
- case 1:
- random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
- break;
- case 2:
- random_service = ConsumeService(fuzzed_data_provider);
- break;
- case 3:
- random_subnet = ConsumeSubNet(fuzzed_data_provider);
- break;
- case 4:
- random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
- break;
- case 5: {
- std::vector<CAddress> addresses;
- while (fuzzed_data_provider.ConsumeBool()) {
- addresses.push_back(ConsumeAddress(fuzzed_data_provider));
- }
- // Limit nTimePenalty to int32_t to avoid signed integer overflow
- (void)connman.AddNewAddresses(addresses, ConsumeAddress(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>());
- break;
- }
- case 6:
- connman.AddNode(random_string);
- break;
- case 7:
- connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- case 8:
- connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
- break;
- case 9:
- connman.DisconnectNode(random_netaddr);
- break;
- case 10:
- connman.DisconnectNode(random_string);
- break;
- case 11:
- connman.DisconnectNode(random_subnet);
- break;
- case 12:
- connman.ForEachNode([](auto) {});
- break;
- case 13:
- connman.ForEachNodeThen([](auto) {}, []() {});
- break;
- case 14:
- (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
- break;
- case 15:
- (void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
- break;
- case 16: {
- (void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
- break;
- }
- case 17:
- (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- case 18:
- (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({CConnman::CONNECTIONS_NONE, CConnman::CONNECTIONS_IN, CConnman::CONNECTIONS_OUT, CConnman::CONNECTIONS_ALL}));
- break;
- case 19:
- connman.MarkAddressGood(random_address);
- break;
- case 20:
- (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
- break;
- case 21:
- // Limit now to int32_t to avoid signed integer overflow
- (void)connman.PoissonNextSendInbound(fuzzed_data_provider.ConsumeIntegral<int32_t>(), fuzzed_data_provider.ConsumeIntegral<int>());
- break;
- case 22: {
- CSerializedNetMsg serialized_net_msg;
- serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
- serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
- connman.PushMessage(&random_node, std::move(serialized_net_msg));
- break;
- }
- case 23:
- connman.RemoveAddedNode(random_string);
- break;
- case 24: {
- const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
- if (SanityCheckASMap(asmap)) {
- connman.SetAsmap(asmap);
- }
- break;
- }
- case 25:
- connman.SetBestHeight(fuzzed_data_provider.ConsumeIntegral<int>());
- break;
- case 26:
- connman.SetMaxOutboundTarget(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- case 27:
- connman.SetMaxOutboundTimeframe(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- case 28:
- connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
- break;
- case 29:
- connman.SetServices(random_service, static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()));
- break;
- case 30:
- connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
- break;
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ random_address = ConsumeAddress(fuzzed_data_provider);
+ },
+ [&] {
+ random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
+ },
+ [&] {
+ random_service = ConsumeService(fuzzed_data_provider);
+ },
+ [&] {
+ random_subnet = ConsumeSubNet(fuzzed_data_provider);
+ },
+ [&] {
+ random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
+ },
+ [&] {
+ std::vector<CAddress> addresses;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ addresses.push_back(ConsumeAddress(fuzzed_data_provider));
+ }
+ // Limit nTimePenalty to int32_t to avoid signed integer overflow
+ (void)connman.AddNewAddresses(addresses, ConsumeAddress(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>());
+ },
+ [&] {
+ connman.AddNode(random_string);
+ },
+ [&] {
+ connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ },
+ [&] {
+ connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
+ },
+ [&] {
+ connman.DisconnectNode(random_netaddr);
+ },
+ [&] {
+ connman.DisconnectNode(random_string);
+ },
+ [&] {
+ connman.DisconnectNode(random_subnet);
+ },
+ [&] {
+ connman.ForEachNode([](auto) {});
+ },
+ [&] {
+ connman.ForEachNodeThen([](auto) {}, []() {});
+ },
+ [&] {
+ (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
+ },
+ [&] {
+ (void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
+ },
+ [&] {
+ (void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
+ },
+ [&] {
+ (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ },
+ [&] {
+ (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({CConnman::CONNECTIONS_NONE, CConnman::CONNECTIONS_IN, CConnman::CONNECTIONS_OUT, CConnman::CONNECTIONS_ALL}));
+ },
+ [&] {
+ connman.MarkAddressGood(random_address);
+ },
+ [&] {
+ (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ // Limit now to int32_t to avoid signed integer overflow
+ (void)connman.PoissonNextSendInbound(fuzzed_data_provider.ConsumeIntegral<int32_t>(), fuzzed_data_provider.ConsumeIntegral<int>());
+ },
+ [&] {
+ CSerializedNetMsg serialized_net_msg;
+ serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
+ serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ connman.PushMessage(&random_node, std::move(serialized_net_msg));
+ },
+ [&] {
+ connman.RemoveAddedNode(random_string);
+ },
+ [&] {
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (SanityCheckASMap(asmap)) {
+ connman.SetAsmap(asmap);
+ }
+ },
+ [&] {
+ connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ connman.SetServices(random_service, ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS));
+ },
+ [&] {
+ connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
+ });
}
(void)connman.GetAddedNodeInfo();
- (void)connman.GetBestHeight();
- (void)connman.GetExtraOutboundCount();
+ (void)connman.GetExtraFullOutboundCount();
(void)connman.GetLocalServices();
(void)connman.GetMaxOutboundTarget();
(void)connman.GetMaxOutboundTimeframe();
diff --git a/src/test/fuzz/crypto.cpp b/src/test/fuzz/crypto.cpp
index 664e65accc..c2bb3a1a4e 100644
--- a/src/test/fuzz/crypto.cpp
+++ b/src/test/fuzz/crypto.cpp
@@ -4,6 +4,7 @@
#include <crypto/hmac_sha256.h>
#include <crypto/hmac_sha512.h>
+#include <crypto/muhash.h>
#include <crypto/ripemd160.h>
#include <crypto/sha1.h>
#include <crypto/sha256.h>
@@ -17,7 +18,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
@@ -35,99 +36,98 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CSHA512 sha512;
SHA3_256 sha3;
CSipHasher sip_hasher{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
+ MuHash3072 muhash;
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
- case 0: {
- if (fuzzed_data_provider.ConsumeBool()) {
- data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
- if (data.empty()) {
- data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
}
- }
- (void)hash160.Write(data);
- (void)hash256.Write(data);
- (void)hmac_sha256.Write(data.data(), data.size());
- (void)hmac_sha512.Write(data.data(), data.size());
- (void)ripemd160.Write(data.data(), data.size());
- (void)sha1.Write(data.data(), data.size());
- (void)sha256.Write(data.data(), data.size());
- (void)sha3.Write(data);
- (void)sha512.Write(data.data(), data.size());
- (void)sip_hasher.Write(data.data(), data.size());
+ (void)hash160.Write(data);
+ (void)hash256.Write(data);
+ (void)hmac_sha256.Write(data.data(), data.size());
+ (void)hmac_sha512.Write(data.data(), data.size());
+ (void)ripemd160.Write(data.data(), data.size());
+ (void)sha1.Write(data.data(), data.size());
+ (void)sha256.Write(data.data(), data.size());
+ (void)sha3.Write(data);
+ (void)sha512.Write(data.data(), data.size());
+ (void)sip_hasher.Write(data.data(), data.size());
- (void)Hash(data);
- (void)Hash160(data);
- (void)sha512.Size();
- break;
- }
- case 1: {
- (void)hash160.Reset();
- (void)hash256.Reset();
- (void)ripemd160.Reset();
- (void)sha1.Reset();
- (void)sha256.Reset();
- (void)sha3.Reset();
- (void)sha512.Reset();
- break;
- }
- case 2: {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 9)) {
- case 0: {
- data.resize(CHash160::OUTPUT_SIZE);
- hash160.Finalize(data);
- break;
- }
- case 1: {
- data.resize(CHash256::OUTPUT_SIZE);
- hash256.Finalize(data);
- break;
- }
- case 2: {
- data.resize(CHMAC_SHA256::OUTPUT_SIZE);
- hmac_sha256.Finalize(data.data());
- break;
- }
- case 3: {
- data.resize(CHMAC_SHA512::OUTPUT_SIZE);
- hmac_sha512.Finalize(data.data());
- break;
- }
- case 4: {
- data.resize(CRIPEMD160::OUTPUT_SIZE);
- ripemd160.Finalize(data.data());
- break;
- }
- case 5: {
- data.resize(CSHA1::OUTPUT_SIZE);
- sha1.Finalize(data.data());
- break;
- }
- case 6: {
- data.resize(CSHA256::OUTPUT_SIZE);
- sha256.Finalize(data.data());
- break;
- }
- case 7: {
- data.resize(CSHA512::OUTPUT_SIZE);
- sha512.Finalize(data.data());
- break;
- }
- case 8: {
- data.resize(1);
- data[0] = sip_hasher.Finalize() % 256;
- break;
- }
- case 9: {
- data.resize(SHA3_256::OUTPUT_SIZE);
- sha3.Finalize(data);
- break;
- }
- }
- break;
- }
- }
+ (void)Hash(data);
+ (void)Hash160(data);
+ (void)sha512.Size();
+
+ if (fuzzed_data_provider.ConsumeBool()) {
+ muhash *= MuHash3072(data);
+ } else {
+ muhash /= MuHash3072(data);
+ }
+ },
+ [&] {
+ (void)hash160.Reset();
+ (void)hash256.Reset();
+ (void)ripemd160.Reset();
+ (void)sha1.Reset();
+ (void)sha256.Reset();
+ (void)sha3.Reset();
+ (void)sha512.Reset();
+ muhash = MuHash3072();
+ },
+ [&] {
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ data.resize(CHash160::OUTPUT_SIZE);
+ hash160.Finalize(data);
+ },
+ [&] {
+ data.resize(CHash256::OUTPUT_SIZE);
+ hash256.Finalize(data);
+ },
+ [&] {
+ data.resize(CHMAC_SHA256::OUTPUT_SIZE);
+ hmac_sha256.Finalize(data.data());
+ },
+ [&] {
+ data.resize(CHMAC_SHA512::OUTPUT_SIZE);
+ hmac_sha512.Finalize(data.data());
+ },
+ [&] {
+ data.resize(CRIPEMD160::OUTPUT_SIZE);
+ ripemd160.Finalize(data.data());
+ },
+ [&] {
+ data.resize(CSHA1::OUTPUT_SIZE);
+ sha1.Finalize(data.data());
+ },
+ [&] {
+ data.resize(CSHA256::OUTPUT_SIZE);
+ sha256.Finalize(data.data());
+ },
+ [&] {
+ data.resize(CSHA512::OUTPUT_SIZE);
+ sha512.Finalize(data.data());
+ },
+ [&] {
+ data.resize(1);
+ data[0] = sip_hasher.Finalize() % 256;
+ },
+ [&] {
+ data.resize(SHA3_256::OUTPUT_SIZE);
+ sha3.Finalize(data);
+ },
+ [&] {
+ uint256 out;
+ muhash.Finalize(out);
+ });
+ });
}
if (fuzzed_data_provider.ConsumeBool()) {
uint64_t state[25];
diff --git a/src/test/fuzz/crypto_aes256.cpp b/src/test/fuzz/crypto_aes256.cpp
index ae14073c96..ccabd1f7dc 100644
--- a/src/test/fuzz/crypto_aes256.cpp
+++ b/src/test/fuzz/crypto_aes256.cpp
@@ -11,7 +11,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_aes256)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);
diff --git a/src/test/fuzz/crypto_aes256cbc.cpp b/src/test/fuzz/crypto_aes256cbc.cpp
index 52983c7e79..6d4138e546 100644
--- a/src/test/fuzz/crypto_aes256cbc.cpp
+++ b/src/test/fuzz/crypto_aes256cbc.cpp
@@ -11,7 +11,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_aes256cbc)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);
diff --git a/src/test/fuzz/crypto_chacha20.cpp b/src/test/fuzz/crypto_chacha20.cpp
index b7438d312d..bb8dd4594f 100644
--- a/src/test/fuzz/crypto_chacha20.cpp
+++ b/src/test/fuzz/crypto_chacha20.cpp
@@ -10,7 +10,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_chacha20)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
@@ -20,31 +20,26 @@ void test_one_input(const std::vector<uint8_t>& buffer)
chacha20 = ChaCha20{key.data(), key.size()};
}
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 4)) {
- case 0: {
- const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
- chacha20.SetKey(key.data(), key.size());
- break;
- }
- case 1: {
- chacha20.SetIV(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- }
- case 2: {
- chacha20.Seek(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- }
- case 3: {
- std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
- chacha20.Keystream(output.data(), output.size());
- break;
- }
- case 4: {
- std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
- const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
- chacha20.Crypt(input.data(), output.data(), input.size());
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
+ chacha20.SetKey(key.data(), key.size());
+ },
+ [&] {
+ chacha20.SetIV(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ },
+ [&] {
+ chacha20.Seek(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ },
+ [&] {
+ std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ chacha20.Keystream(output.data(), output.size());
+ },
+ [&] {
+ std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
+ chacha20.Crypt(input.data(), output.data(), input.size());
+ });
}
}
diff --git a/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp
index 48e4263f27..0e1c44cded 100644
--- a/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp
+++ b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp
@@ -13,7 +13,7 @@
#include <limits>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_chacha20_poly1305_aead)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
@@ -29,44 +29,43 @@ void test_one_input(const std::vector<uint8_t>& buffer)
std::vector<uint8_t> out(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
bool is_encrypt = fuzzed_data_provider.ConsumeBool();
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 6)) {
- case 0: {
- buffer_size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(64, 4096);
- in = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
- out = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
- break;
- }
- case 1: {
- (void)aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), out.size(), in.data(), buffer_size, is_encrypt);
- break;
- }
- case 2: {
- uint32_t len = 0;
- const bool ok = aead.GetLength(&len, seqnr_aad, aad_pos, in.data());
- assert(ok);
- break;
- }
- case 3: {
- seqnr_payload += 1;
- aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN;
- if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > CHACHA20_ROUND_OUTPUT) {
- aad_pos = 0;
- seqnr_aad += 1;
- }
- break;
- }
- case 4: {
- seqnr_payload = fuzzed_data_provider.ConsumeIntegral<int>();
- break;
- }
- case 5: {
- seqnr_aad = fuzzed_data_provider.ConsumeIntegral<int>();
- break;
- }
- case 6: {
- is_encrypt = fuzzed_data_provider.ConsumeBool();
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ buffer_size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(64, 4096);
+ in = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ out = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ },
+ [&] {
+ (void)aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), out.size(), in.data(), buffer_size, is_encrypt);
+ },
+ [&] {
+ uint32_t len = 0;
+ const bool ok = aead.GetLength(&len, seqnr_aad, aad_pos, in.data());
+ assert(ok);
+ },
+ [&] {
+ if (AdditionOverflow(seqnr_payload, static_cast<uint64_t>(1))) {
+ return;
+ }
+ seqnr_payload += 1;
+ aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN;
+ if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > CHACHA20_ROUND_OUTPUT) {
+ aad_pos = 0;
+ if (AdditionOverflow(seqnr_aad, static_cast<uint64_t>(1))) {
+ return;
+ }
+ seqnr_aad += 1;
+ }
+ },
+ [&] {
+ seqnr_payload = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
+ },
+ [&] {
+ seqnr_aad = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
+ },
+ [&] {
+ is_encrypt = fuzzed_data_provider.ConsumeBool();
+ });
}
}
diff --git a/src/test/fuzz/crypto_common.cpp b/src/test/fuzz/crypto_common.cpp
index 7ccb125216..8e07dfedb9 100644
--- a/src/test/fuzz/crypto_common.cpp
+++ b/src/test/fuzz/crypto_common.cpp
@@ -13,7 +13,7 @@
#include <cstring>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_common)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const uint16_t random_u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
diff --git a/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp
index e0a4e90c10..8cb9c55283 100644
--- a/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp
+++ b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp
@@ -11,7 +11,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_hkdf_hmac_sha256_l32)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
diff --git a/src/test/fuzz/crypto_poly1305.cpp b/src/test/fuzz/crypto_poly1305.cpp
index 5681e6a693..ac555ed68c 100644
--- a/src/test/fuzz/crypto_poly1305.cpp
+++ b/src/test/fuzz/crypto_poly1305.cpp
@@ -10,7 +10,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(crypto_poly1305)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
diff --git a/src/test/fuzz/cuckoocache.cpp b/src/test/fuzz/cuckoocache.cpp
index 5b45aa79d8..dc20dc3f62 100644
--- a/src/test/fuzz/cuckoocache.cpp
+++ b/src/test/fuzz/cuckoocache.cpp
@@ -26,7 +26,7 @@ struct RandomHasher {
};
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(cuckoocache)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
fuzzed_data_provider_ptr = &fuzzed_data_provider;
diff --git a/src/test/fuzz/danger_link_all.sh b/src/test/fuzz/danger_link_all.sh
new file mode 100755
index 0000000000..2ddd00c658
--- /dev/null
+++ b/src/test/fuzz/danger_link_all.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# 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.
+
+export LC_ALL=C.UTF-8
+
+set -e
+
+ROOT_DIR="$(git rev-parse --show-toplevel)"
+
+# Run only once (break make recursion)
+if [ -d "${ROOT_DIR}/lock_fuzz_link_all" ]; then
+ exit
+fi
+mkdir "${ROOT_DIR}/lock_fuzz_link_all"
+
+echo "Linking each fuzz target separately."
+for FUZZING_HARNESS in $(PRINT_ALL_FUZZ_TARGETS_AND_ABORT=1 "${ROOT_DIR}/src/test/fuzz/fuzz" | sort -u); do
+ echo "Building src/test/fuzz/${FUZZING_HARNESS} ..."
+ git checkout -- "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
+ sed -i "s/std::getenv(\"FUZZ\")/\"${FUZZING_HARNESS}\"/g" "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
+ make
+ mv "${ROOT_DIR}/src/test/fuzz/fuzz" "${ROOT_DIR}/src/test/fuzz/${FUZZING_HARNESS}"
+done
+git checkout -- "${ROOT_DIR}/src/test/fuzz/fuzz.cpp"
+rmdir "${ROOT_DIR}/lock_fuzz_link_all"
+echo "Successfully built all fuzz targets."
diff --git a/src/test/fuzz/data_stream.cpp b/src/test/fuzz/data_stream.cpp
new file mode 100644
index 0000000000..f3b6e6af04
--- /dev/null
+++ b/src/test/fuzz/data_stream.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 <addrman.h>
+#include <net.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void initialize_data_stream_addr_man()
+{
+ static const auto testing_setup = MakeFuzzingContext<>();
+}
+
+FUZZ_TARGET_INIT(data_stream_addr_man, initialize_data_stream_addr_man)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ CDataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
+ CAddrMan addr_man;
+ CAddrDB::Read(addr_man, data_stream);
+}
diff --git a/src/test/fuzz/decode_tx.cpp b/src/test/fuzz/decode_tx.cpp
index a2b18c0365..57431e65ba 100644
--- a/src/test/fuzz/decode_tx.cpp
+++ b/src/test/fuzz/decode_tx.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(decode_tx)
{
const std::string tx_hex = HexStr(buffer);
CMutableTransaction mtx;
diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp
index 7b57a2c1e2..0d1921f285 100644
--- a/src/test/fuzz/descriptor_parse.cpp
+++ b/src/test/fuzz/descriptor_parse.cpp
@@ -8,14 +8,14 @@
#include <test/fuzz/fuzz.h>
#include <util/memory.h>
-void initialize()
+void initialize_descriptor_parse()
{
static const ECCVerifyHandle verify_handle;
ECC_Start();
SelectParams(CBaseChainParams::MAIN);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(descriptor_parse, initialize_descriptor_parse)
{
const std::string descriptor(buffer.begin(), buffer.end());
FlatSigningProvider signing_provider;
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 8ca5366c8a..74dec6475e 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -34,12 +34,21 @@
#include <test/fuzz/fuzz.h>
-void initialize()
+void initialize_deserialize()
{
// Fuzzers using pubkey must hold an ECCVerifyHandle.
static const ECCVerifyHandle verify_handle;
}
+#define FUZZ_TARGET_DESERIALIZE(name, code) \
+ FUZZ_TARGET_INIT(name, initialize_deserialize) \
+ { \
+ try { \
+ code \
+ } catch (const invalid_fuzzing_input_exception&) { \
+ } \
+ }
+
namespace {
struct invalid_fuzzing_input_exception : public std::exception {
@@ -92,44 +101,51 @@ void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
-{
- try {
-#if BLOCK_FILTER_DESERIALIZE
+FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
BlockFilter block_filter;
DeserializeFromFuzzingInput(buffer, block_filter);
-#elif ADDR_INFO_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
CAddrInfo addr_info;
DeserializeFromFuzzingInput(buffer, addr_info);
-#elif BLOCK_FILE_INFO_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
CBlockFileInfo block_file_info;
DeserializeFromFuzzingInput(buffer, block_file_info);
-#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
CBlockHeaderAndShortTxIDs block_header_and_short_txids;
DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
-#elif FEE_RATE_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
CFeeRate fee_rate;
DeserializeFromFuzzingInput(buffer, fee_rate);
AssertEqualAfterSerializeDeserialize(fee_rate);
-#elif MERKLE_BLOCK_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
CMerkleBlock merkle_block;
DeserializeFromFuzzingInput(buffer, merkle_block);
-#elif OUT_POINT_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
COutPoint out_point;
DeserializeFromFuzzingInput(buffer, out_point);
AssertEqualAfterSerializeDeserialize(out_point);
-#elif PARTIAL_MERKLE_TREE_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
CPartialMerkleTree partial_merkle_tree;
DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
-#elif PUB_KEY_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
CPubKey pub_key;
DeserializeFromFuzzingInput(buffer, pub_key);
// TODO: The following equivalence should hold for CPubKey? Fix.
// AssertEqualAfterSerializeDeserialize(pub_key);
-#elif SCRIPT_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(script_deserialize, {
CScript script;
DeserializeFromFuzzingInput(buffer, script);
-#elif SUB_NET_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, {
CSubNet sub_net_1;
DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION);
AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION);
@@ -139,67 +155,85 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CSubNet sub_net_3;
DeserializeFromFuzzingInput(buffer, sub_net_3);
AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT);
-#elif TX_IN_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
CTxIn tx_in;
DeserializeFromFuzzingInput(buffer, tx_in);
AssertEqualAfterSerializeDeserialize(tx_in);
-#elif FLAT_FILE_POS_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
FlatFilePos flat_file_pos;
DeserializeFromFuzzingInput(buffer, flat_file_pos);
AssertEqualAfterSerializeDeserialize(flat_file_pos);
-#elif KEY_ORIGIN_INFO_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
KeyOriginInfo key_origin_info;
DeserializeFromFuzzingInput(buffer, key_origin_info);
AssertEqualAfterSerializeDeserialize(key_origin_info);
-#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
PartiallySignedTransaction partially_signed_transaction;
DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
-#elif PREFILLED_TRANSACTION_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
PrefilledTransaction prefilled_transaction;
DeserializeFromFuzzingInput(buffer, prefilled_transaction);
-#elif PSBT_INPUT_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
PSBTInput psbt_input;
DeserializeFromFuzzingInput(buffer, psbt_input);
-#elif PSBT_OUTPUT_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
PSBTOutput psbt_output;
DeserializeFromFuzzingInput(buffer, psbt_output);
-#elif BLOCK_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(block_deserialize, {
CBlock block;
DeserializeFromFuzzingInput(buffer, block);
-#elif BLOCKLOCATOR_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
CBlockLocator bl;
DeserializeFromFuzzingInput(buffer, bl);
-#elif BLOCKMERKLEROOT
+})
+FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
CBlock block;
DeserializeFromFuzzingInput(buffer, block);
bool mutated;
BlockMerkleRoot(block, &mutated);
-#elif ADDRMAN_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
CAddrMan am;
DeserializeFromFuzzingInput(buffer, am);
-#elif BLOCKHEADER_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
CBlockHeader bh;
DeserializeFromFuzzingInput(buffer, bh);
-#elif BANENTRY_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(banentry_deserialize, {
CBanEntry be;
DeserializeFromFuzzingInput(buffer, be);
-#elif TXUNDO_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
CTxUndo tu;
DeserializeFromFuzzingInput(buffer, tu);
-#elif BLOCKUNDO_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
CBlockUndo bu;
DeserializeFromFuzzingInput(buffer, bu);
-#elif COINS_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
Coin coin;
DeserializeFromFuzzingInput(buffer, coin);
-#elif NETADDR_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
CNetAddr na;
DeserializeFromFuzzingInput(buffer, na);
if (na.IsAddrV1Compatible()) {
AssertEqualAfterSerializeDeserialize(na);
}
AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
-#elif SERVICE_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(service_deserialize, {
CService s;
DeserializeFromFuzzingInput(buffer, s);
if (s.IsAddrV1Compatible()) {
@@ -213,50 +247,56 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CService s2;
DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
-#elif MESSAGEHEADER_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
CMessageHeader mh;
DeserializeFromFuzzingInput(buffer, mh);
(void)mh.IsCommandValid();
-#elif ADDRESS_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(address_deserialize, {
CAddress a;
DeserializeFromFuzzingInput(buffer, a);
-#elif INV_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
CInv i;
DeserializeFromFuzzingInput(buffer, i);
-#elif BLOOMFILTER_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
CBloomFilter bf;
DeserializeFromFuzzingInput(buffer, bf);
-#elif DISKBLOCKINDEX_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
CDiskBlockIndex dbi;
DeserializeFromFuzzingInput(buffer, dbi);
-#elif TXOUTCOMPRESSOR_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
CTxOut to;
auto toc = Using<TxOutCompression>(to);
DeserializeFromFuzzingInput(buffer, toc);
-#elif BLOCKTRANSACTIONS_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
BlockTransactions bt;
DeserializeFromFuzzingInput(buffer, bt);
-#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
BlockTransactionsRequest btr;
DeserializeFromFuzzingInput(buffer, btr);
-#elif SNAPSHOTMETADATA_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, {
SnapshotMetadata snapshot_metadata;
DeserializeFromFuzzingInput(buffer, snapshot_metadata);
-#elif UINT160_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
uint160 u160;
DeserializeFromFuzzingInput(buffer, u160);
AssertEqualAfterSerializeDeserialize(u160);
-#elif UINT256_DESERIALIZE
+})
+FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
uint256 u256;
DeserializeFromFuzzingInput(buffer, u256);
AssertEqualAfterSerializeDeserialize(u256);
-#else
-#error Need at least one fuzz target to compile
-#endif
+})
// Classes intentionally not covered in this file since their deserialization code is
// fuzzed elsewhere:
// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
- } catch (const invalid_fuzzing_input_exception&) {
- }
-}
diff --git a/src/test/fuzz/eval_script.cpp b/src/test/fuzz/eval_script.cpp
index c556599db3..635288fc36 100644
--- a/src/test/fuzz/eval_script.cpp
+++ b/src/test/fuzz/eval_script.cpp
@@ -10,12 +10,12 @@
#include <limits>
-void initialize()
+void initialize_eval_script()
{
static const ECCVerifyHandle verify_handle;
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(eval_script, initialize_eval_script)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
diff --git a/src/test/fuzz/fee_rate.cpp b/src/test/fuzz/fee_rate.cpp
index f3d44d9f93..2955213635 100644
--- a/src/test/fuzz/fee_rate.cpp
+++ b/src/test/fuzz/fee_rate.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(fee_rate)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const CAmount satoshis_per_k = ConsumeMoney(fuzzed_data_provider);
diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp
index ce8700befa..61c7681bf9 100644
--- a/src/test/fuzz/fees.cpp
+++ b/src/test/fuzz/fees.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(fees)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const CFeeRate minimal_incremental_fee{ConsumeMoney(fuzzed_data_provider)};
diff --git a/src/test/fuzz/flatfile.cpp b/src/test/fuzz/flatfile.cpp
index 95dabb8bab..d142e374b1 100644
--- a/src/test/fuzz/flatfile.cpp
+++ b/src/test/fuzz/flatfile.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(flatfile)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::optional<FlatFilePos> flat_file_pos = ConsumeDeserializable<FlatFilePos>(fuzzed_data_provider);
diff --git a/src/test/fuzz/float.cpp b/src/test/fuzz/float.cpp
index a24bae5b35..d18a87d177 100644
--- a/src/test/fuzz/float.cpp
+++ b/src/test/fuzz/float.cpp
@@ -12,7 +12,7 @@
#include <cassert>
#include <cstdint>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(float)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 753cfffdcb..fd87667755 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -5,6 +5,7 @@
#include <test/fuzz/fuzz.h>
#include <test/util/setup_common.h>
+#include <util/check.h>
#include <cstdint>
#include <unistd.h>
@@ -12,6 +13,36 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
+std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>>& FuzzTargets()
+{
+ static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>> g_fuzz_targets;
+ return g_fuzz_targets;
+}
+
+void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init)
+{
+ const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init));
+ Assert(it_ins.second);
+}
+
+static TypeTestOneInput* g_test_one_input{nullptr};
+
+void initialize()
+{
+ if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) {
+ for (const auto& t : FuzzTargets()) {
+ std::cout << t.first << std::endl;
+ }
+ Assert(false);
+ }
+ std::string_view fuzz_target{Assert(std::getenv("FUZZ"))};
+ const auto it = FuzzTargets().find(fuzz_target);
+ Assert(it != FuzzTargets().end());
+ Assert(!g_test_one_input);
+ g_test_one_input = &std::get<0>(it->second);
+ std::get<1>(it->second)();
+}
+
#if defined(PROVIDE_MAIN_FUNCTION)
static bool read_stdin(std::vector<uint8_t>& data)
{
@@ -24,14 +55,10 @@ static bool read_stdin(std::vector<uint8_t>& data)
}
#endif
-// Default initialization: Override using a non-weak initialize().
-__attribute__((weak)) void initialize()
-{
-}
-
// This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
+ static const auto& test_one_input = *Assert(g_test_one_input);
const std::vector<uint8_t> input(data, data + size);
test_one_input(input);
return 0;
@@ -48,6 +75,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
__attribute__((weak)) int main(int argc, char** argv)
{
initialize();
+ static const auto& test_one_input = *Assert(g_test_one_input);
#ifdef __AFL_INIT
// Enable AFL deferred forkserver mode. Requires compilation using
// afl-clang-fast++. See fuzzing.md for details.
diff --git a/src/test/fuzz/fuzz.h b/src/test/fuzz/fuzz.h
index 3be202b16e..52841e069a 100644
--- a/src/test/fuzz/fuzz.h
+++ b/src/test/fuzz/fuzz.h
@@ -1,14 +1,33 @@
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-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.
#ifndef BITCOIN_TEST_FUZZ_FUZZ_H
#define BITCOIN_TEST_FUZZ_FUZZ_H
-#include <stdint.h>
+#include <cstdint>
+#include <functional>
+#include <string_view>
#include <vector>
-void initialize();
-void test_one_input(const std::vector<uint8_t>& buffer);
+using TypeTestOneInput = std::function<void(const std::vector<uint8_t>&)>;
+using TypeInitialize = std::function<void()>;
+
+void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init);
+
+inline void FuzzFrameworkEmptyFun() {}
+
+#define FUZZ_TARGET(name) \
+ FUZZ_TARGET_INIT(name, FuzzFrameworkEmptyFun)
+
+#define FUZZ_TARGET_INIT(name, init_fun) \
+ void name##_fuzz_target(const std::vector<uint8_t>&); \
+ struct name##_Before_Main { \
+ name##_Before_Main() \
+ { \
+ FuzzFrameworkRegisterTarget(#name, name##_fuzz_target, init_fun); \
+ } \
+ } const static g_##name##_before_main; \
+ void name##_fuzz_target(const std::vector<uint8_t>& buffer)
#endif // BITCOIN_TEST_FUZZ_FUZZ_H
diff --git a/src/test/fuzz/golomb_rice.cpp b/src/test/fuzz/golomb_rice.cpp
index a9f450b0c4..c99bf940c7 100644
--- a/src/test/fuzz/golomb_rice.cpp
+++ b/src/test/fuzz/golomb_rice.cpp
@@ -54,7 +54,7 @@ std::vector<uint64_t> BuildHashedSet(const std::unordered_set<std::vector<uint8_
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(golomb_rice)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::vector<uint8_t> golomb_rice_data;
diff --git a/src/test/fuzz/hex.cpp b/src/test/fuzz/hex.cpp
index 6a8699fd0f..cc1bc1c8cf 100644
--- a/src/test/fuzz/hex.cpp
+++ b/src/test/fuzz/hex.cpp
@@ -16,12 +16,12 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_hex()
{
static const ECCVerifyHandle verify_handle;
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(hex, initialize_hex)
{
const std::string random_hex_string(buffer.begin(), buffer.end());
const std::vector<unsigned char> data = ParseHex(random_hex_string);
diff --git a/src/test/fuzz/http_request.cpp b/src/test/fuzz/http_request.cpp
index 36d44e361f..e3b62032bc 100644
--- a/src/test/fuzz/http_request.cpp
+++ b/src/test/fuzz/http_request.cpp
@@ -39,7 +39,7 @@ extern "C" int evhttp_parse_headers_(struct evhttp_request*, struct evbuffer*);
std::string RequestMethodString(HTTPRequest::RequestMethod m);
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(http_request)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
evhttp_request* evreq = evhttp_request_new(nullptr, nullptr);
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index 35d6804d4f..ac83d91ea0 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -40,12 +40,12 @@
#include <set>
#include <vector>
-void initialize()
+void initialize_integer()
{
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(integer, initialize_integer)
{
if (buffer.size() < sizeof(uint256) + sizeof(uint160)) {
return;
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp
index 955b954700..aa8f826e4a 100644
--- a/src/test/fuzz/key.cpp
+++ b/src/test/fuzz/key.cpp
@@ -26,14 +26,14 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_key()
{
static const ECCVerifyHandle ecc_verify_handle;
ECC_Start();
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(key, initialize_key)
{
const CKey key = [&] {
CKey k;
diff --git a/src/test/fuzz/key_io.cpp b/src/test/fuzz/key_io.cpp
index 62aefb650d..665ca01fa1 100644
--- a/src/test/fuzz/key_io.cpp
+++ b/src/test/fuzz/key_io.cpp
@@ -14,14 +14,14 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_key_io()
{
static const ECCVerifyHandle verify_handle;
ECC_Start();
SelectParams(CBaseChainParams::MAIN);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(key_io, initialize_key_io)
{
const std::string random_string(buffer.begin(), buffer.end());
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
index 82cbc00a3a..fa4024fc38 100644
--- a/src/test/fuzz/kitchen_sink.cpp
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -2,6 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <merkleblock.h>
+#include <policy/fees.h>
#include <rpc/util.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
@@ -9,18 +11,49 @@
#include <util/error.h>
#include <util/translation.h>
+#include <array>
#include <cstdint>
#include <vector>
+namespace {
+constexpr TransactionError ALL_TRANSACTION_ERROR[] = {
+ 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,
+};
+}; // namespace
+
// 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)
+FUZZ_TARGET(kitchen_sink)
{
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});
+ const TransactionError transaction_error = fuzzed_data_provider.PickValueInArray(ALL_TRANSACTION_ERROR);
(void)JSONRPCTransactionError(transaction_error);
(void)RPCErrorFromTransactionError(transaction_error);
(void)TransactionErrorString(transaction_error);
+
+ (void)StringForFeeEstimateHorizon(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS));
+
+ const OutputType output_type = fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES);
+ const std::string& output_type_string = FormatOutputType(output_type);
+ OutputType output_type_parsed;
+ const bool parsed = ParseOutputType(output_type_string, output_type_parsed);
+ assert(parsed);
+ assert(output_type == output_type_parsed);
+ (void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64), output_type_parsed);
+
+ const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ const std::vector<bool> bits = BytesToBits(bytes);
+ const std::vector<uint8_t> bytes_decoded = BitsToBytes(bits);
+ assert(bytes == bytes_decoded);
}
diff --git a/src/test/fuzz/load_external_block_file.cpp b/src/test/fuzz/load_external_block_file.cpp
index d9de9d9866..95597bf082 100644
--- a/src/test/fuzz/load_external_block_file.cpp
+++ b/src/test/fuzz/load_external_block_file.cpp
@@ -13,12 +13,12 @@
#include <cstdint>
#include <vector>
-void initialize()
+void initialize_load_external_block_file()
{
- InitializeFuzzingContext();
+ static const auto testing_setup = MakeFuzzingContext<const TestingSetup>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
@@ -27,5 +27,5 @@ void test_one_input(const std::vector<uint8_t>& buffer)
return;
}
FlatFilePos flat_file_pos;
- LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
+ ::ChainstateActive().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
}
diff --git a/src/test/fuzz/locale.cpp b/src/test/fuzz/locale.cpp
index 2b181c6da1..5b1acae57b 100644
--- a/src/test/fuzz/locale.cpp
+++ b/src/test/fuzz/locale.cpp
@@ -35,7 +35,7 @@ bool IsAvailableLocale(const std::string& locale_identifier)
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(locale)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string locale_identifier = ConsumeLocaleIdentifier(fuzzed_data_provider);
diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp
index 4710e75757..23e0baa564 100644
--- a/src/test/fuzz/merkleblock.cpp
+++ b/src/test/fuzz/merkleblock.cpp
@@ -13,37 +13,35 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(merkleblock)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CPartialMerkleTree partial_merkle_tree;
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1)) {
- case 0: {
- const std::optional<CPartialMerkleTree> opt_partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider);
- if (opt_partial_merkle_tree) {
- partial_merkle_tree = *opt_partial_merkle_tree;
- }
- break;
- }
- case 1: {
- CMerkleBlock merkle_block;
- const std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider);
- CBloomFilter bloom_filter;
- std::set<uint256> txids;
- if (opt_block && !opt_block->vtx.empty()) {
- if (fuzzed_data_provider.ConsumeBool()) {
- merkle_block = CMerkleBlock{*opt_block, bloom_filter};
- } else if (fuzzed_data_provider.ConsumeBool()) {
- while (fuzzed_data_provider.ConsumeBool()) {
- txids.insert(ConsumeUInt256(fuzzed_data_provider));
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const std::optional<CPartialMerkleTree> opt_partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider);
+ if (opt_partial_merkle_tree) {
+ partial_merkle_tree = *opt_partial_merkle_tree;
+ }
+ },
+ [&] {
+ CMerkleBlock merkle_block;
+ const std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider);
+ CBloomFilter bloom_filter;
+ std::set<uint256> txids;
+ if (opt_block && !opt_block->vtx.empty()) {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ merkle_block = CMerkleBlock{*opt_block, bloom_filter};
+ } else if (fuzzed_data_provider.ConsumeBool()) {
+ while (fuzzed_data_provider.ConsumeBool()) {
+ txids.insert(ConsumeUInt256(fuzzed_data_provider));
+ }
+ merkle_block = CMerkleBlock{*opt_block, txids};
}
- merkle_block = CMerkleBlock{*opt_block, txids};
}
- }
- partial_merkle_tree = merkle_block.txn;
- break;
- }
- }
+ partial_merkle_tree = merkle_block.txn;
+ });
(void)partial_merkle_tree.GetNumTransactions();
std::vector<uint256> matches;
std::vector<unsigned int> indices;
diff --git a/src/test/fuzz/message.cpp b/src/test/fuzz/message.cpp
index fa0322a391..06cd0afe2a 100644
--- a/src/test/fuzz/message.cpp
+++ b/src/test/fuzz/message.cpp
@@ -16,14 +16,14 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_message()
{
static const ECCVerifyHandle ecc_verify_handle;
ECC_Start();
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(message, initialize_message)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string random_message = fuzzed_data_provider.ConsumeRandomLengthString(1024);
diff --git a/src/test/fuzz/muhash.cpp b/src/test/fuzz/muhash.cpp
new file mode 100644
index 0000000000..8f843ca773
--- /dev/null
+++ b/src/test/fuzz/muhash.cpp
@@ -0,0 +1,53 @@
+// 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 <crypto/muhash.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <vector>
+
+FUZZ_TARGET(muhash)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ std::vector<uint8_t> data2 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+ if (data2.empty()) {
+ data2.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+
+ data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ data2 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+
+ MuHash3072 muhash;
+
+ // Test that MuHash result is consistent independent of order of operations
+ muhash.Insert(data);
+ muhash.Insert(data2);
+
+ uint256 out;
+ muhash.Finalize(out);
+
+ muhash = MuHash3072();
+ muhash.Insert(data2);
+ muhash.Insert(data);
+
+ uint256 out2;
+ muhash.Finalize(out2);
+
+ assert(out == out2);
+
+ // Test that removing all added elements brings the object back to it's initial state
+ muhash /= muhash;
+ muhash.Finalize(out);
+
+ MuHash3072 muhash2;
+ muhash2.Finalize(out2);
+
+ assert(out == out2);
+}
diff --git a/src/test/fuzz/multiplication_overflow.cpp b/src/test/fuzz/multiplication_overflow.cpp
index a4b158c18b..0f054529a6 100644
--- a/src/test/fuzz/multiplication_overflow.cpp
+++ b/src/test/fuzz/multiplication_overflow.cpp
@@ -14,7 +14,7 @@
#if __has_builtin(__builtin_mul_overflow)
#define HAVE_BUILTIN_MUL_OVERFLOW
#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
+#elif defined(__GNUC__)
#define HAVE_BUILTIN_MUL_OVERFLOW
#endif
@@ -40,7 +40,7 @@ void TestMultiplicationOverflow(FuzzedDataProvider& fuzzed_data_provider)
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(multiplication_overflow)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
TestMultiplicationOverflow<int64_t>(fuzzed_data_provider);
diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp
index a0c8b7aac5..21dca4eb05 100644
--- a/src/test/fuzz/net.cpp
+++ b/src/test/fuzz/net.cpp
@@ -13,125 +13,93 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <cstdint>
#include <string>
#include <vector>
-void initialize()
+void initialize_net()
{
- static const BasicTestingSetup basic_testing_setup;
+ static const auto testing_setup = MakeFuzzingContext<>(CBaseChainParams::MAIN);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(net, initialize_net)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
-
- const std::optional<CAddress> address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- if (!address) {
- return;
- }
- const std::optional<CAddress> address_bind = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- if (!address_bind) {
- return;
- }
-
- CNode node{fuzzed_data_provider.ConsumeIntegral<NodeId>(),
- static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()),
- fuzzed_data_provider.ConsumeIntegral<int>(),
- INVALID_SOCKET,
- *address,
- fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
- fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
- *address_bind,
- fuzzed_data_provider.ConsumeRandomLengthString(32),
- fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH}),
- fuzzed_data_provider.ConsumeBool()};
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
+ CNode node{ConsumeNode(fuzzed_data_provider)};
+ node.SetCommonVersion(fuzzed_data_provider.ConsumeIntegral<int>());
while (fuzzed_data_provider.ConsumeBool()) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
- case 0: {
- node.CloseSocketDisconnect();
- break;
- }
- case 1: {
- node.MaybeSetAddrName(fuzzed_data_provider.ConsumeRandomLengthString(32));
- break;
- }
- case 2: {
- node.SetCommonVersion(fuzzed_data_provider.ConsumeIntegral<int>());
- break;
- }
- case 3: {
- const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
- if (!SanityCheckASMap(asmap)) {
- break;
- }
- CNodeStats stats;
- node.copyStats(stats, asmap);
- break;
- }
- case 4: {
- const CNode* add_ref_node = node.AddRef();
- assert(add_ref_node == &node);
- break;
- }
- case 5: {
- if (node.GetRefCount() > 0) {
- node.Release();
- }
- break;
- }
- case 6: {
- if (node.m_addr_known == nullptr) {
- break;
- }
- const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- if (!addr_opt) {
- break;
- }
- node.AddAddressKnown(*addr_opt);
- break;
- }
- case 7: {
- if (node.m_addr_known == nullptr) {
- break;
- }
- const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- if (!addr_opt) {
- break;
- }
- FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};
- node.PushAddress(*addr_opt, fast_random_context);
- break;
- }
- case 8: {
- const std::optional<CInv> inv_opt = ConsumeDeserializable<CInv>(fuzzed_data_provider);
- if (!inv_opt) {
- break;
- }
- node.AddKnownTx(inv_opt->hash);
- break;
- }
- case 9: {
- node.PushTxInventory(ConsumeUInt256(fuzzed_data_provider));
- break;
- }
- case 10: {
- const std::optional<CService> service_opt = ConsumeDeserializable<CService>(fuzzed_data_provider);
- if (!service_opt) {
- break;
- }
- node.SetAddrLocal(*service_opt);
- break;
- }
- case 11: {
- const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
- bool complete;
- node.ReceiveMsgBytes(b, complete);
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ node.CloseSocketDisconnect();
+ },
+ [&] {
+ node.MaybeSetAddrName(fuzzed_data_provider.ConsumeRandomLengthString(32));
+ },
+ [&] {
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (!SanityCheckASMap(asmap)) {
+ return;
+ }
+ CNodeStats stats;
+ node.copyStats(stats, asmap);
+ },
+ [&] {
+ const CNode* add_ref_node = node.AddRef();
+ assert(add_ref_node == &node);
+ },
+ [&] {
+ if (node.GetRefCount() > 0) {
+ node.Release();
+ }
+ },
+ [&] {
+ if (node.m_addr_known == nullptr) {
+ return;
+ }
+ const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ if (!addr_opt) {
+ return;
+ }
+ node.AddAddressKnown(*addr_opt);
+ },
+ [&] {
+ if (node.m_addr_known == nullptr) {
+ return;
+ }
+ const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ if (!addr_opt) {
+ return;
+ }
+ FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};
+ node.PushAddress(*addr_opt, fast_random_context);
+ },
+ [&] {
+ const std::optional<CInv> inv_opt = ConsumeDeserializable<CInv>(fuzzed_data_provider);
+ if (!inv_opt) {
+ return;
+ }
+ node.AddKnownTx(inv_opt->hash);
+ },
+ [&] {
+ node.PushTxInventory(ConsumeUInt256(fuzzed_data_provider));
+ },
+ [&] {
+ const std::optional<CService> service_opt = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (!service_opt) {
+ return;
+ }
+ node.SetAddrLocal(*service_opt);
+ },
+ [&] {
+ const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ bool complete;
+ node.ReceiveMsgBytes(b, complete);
+ });
}
(void)node.GetAddrLocal();
@@ -139,15 +107,12 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)node.GetId();
(void)node.GetLocalNonce();
(void)node.GetLocalServices();
- (void)node.GetMyStartingHeight();
const int ref_count = node.GetRefCount();
assert(ref_count >= 0);
(void)node.GetCommonVersion();
(void)node.RelayAddrsWithConn();
- 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>());
+ const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
(void)node.HasPermission(net_permission_flags);
(void)node.ConnectedThroughNetwork();
}
diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp
index 8a674ac1e9..544a33047b 100644
--- a/src/test/fuzz/net_permissions.cpp
+++ b/src/test/fuzz/net_permissions.cpp
@@ -13,22 +13,11 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(net_permissions)
{
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_ADDR,
- NetPermissionFlags::PF_ISIMPLICIT,
- NetPermissionFlags::PF_ALL,
- }) :
- static_cast<NetPermissionFlags>(fuzzed_data_provider.ConsumeIntegral<uint32_t>());
+ const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
NetWhitebindPermissions net_whitebind_permissions;
bilingual_str error_net_whitebind_permissions;
diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp
index 8252f38726..6e9bb47ff6 100644
--- a/src/test/fuzz/netaddress.cpp
+++ b/src/test/fuzz/netaddress.cpp
@@ -12,7 +12,7 @@
#include <netinet/in.h>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(netaddress)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/node_eviction.cpp b/src/test/fuzz/node_eviction.cpp
new file mode 100644
index 0000000000..aaebe83c0a
--- /dev/null
+++ b/src/test/fuzz/node_eviction.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 <net.h>
+#include <optional.h>
+#include <protocol.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <optional>
+#include <vector>
+
+FUZZ_TARGET(node_eviction)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ std::vector<NodeEvictionCandidate> eviction_candidates;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ eviction_candidates.push_back({
+ fuzzed_data_provider.ConsumeIntegral<NodeId>(),
+ fuzzed_data_provider.ConsumeIntegral<int64_t>(),
+ fuzzed_data_provider.ConsumeIntegral<int64_t>(),
+ fuzzed_data_provider.ConsumeIntegral<int64_t>(),
+ fuzzed_data_provider.ConsumeIntegral<int64_t>(),
+ fuzzed_data_provider.ConsumeBool(),
+ fuzzed_data_provider.ConsumeBool(),
+ fuzzed_data_provider.ConsumeBool(),
+ fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
+ fuzzed_data_provider.ConsumeBool(),
+ fuzzed_data_provider.ConsumeBool(),
+ });
+ }
+ // Make a copy since eviction_candidates may be in some valid but otherwise
+ // indeterminate state after the SelectNodeToEvict(&&) call.
+ const std::vector<NodeEvictionCandidate> eviction_candidates_copy = eviction_candidates;
+ const Optional<NodeId> node_to_evict = SelectNodeToEvict(std::move(eviction_candidates));
+ if (node_to_evict) {
+ assert(std::any_of(eviction_candidates_copy.begin(), eviction_candidates_copy.end(), [&node_to_evict](const NodeEvictionCandidate& eviction_candidate) { return *node_to_evict == eviction_candidate.id; }));
+ }
+}
diff --git a/src/test/fuzz/p2p_transport_deserializer.cpp b/src/test/fuzz/p2p_transport_deserializer.cpp
index 7a6236efac..163f1b839e 100644
--- a/src/test/fuzz/p2p_transport_deserializer.cpp
+++ b/src/test/fuzz/p2p_transport_deserializer.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -12,12 +12,12 @@
#include <limits>
#include <vector>
-void initialize()
+void initialize_p2p_transport_deserializer()
{
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(p2p_transport_deserializer, initialize_p2p_transport_deserializer)
{
// Construct deserializer, with a dummy NodeId
V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION};
diff --git a/src/test/fuzz/parse_hd_keypath.cpp b/src/test/fuzz/parse_hd_keypath.cpp
index f668ca8c48..411b70230a 100644
--- a/src/test/fuzz/parse_hd_keypath.cpp
+++ b/src/test/fuzz/parse_hd_keypath.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-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.
@@ -10,7 +10,7 @@
#include <cstdint>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(parse_hd_keypath)
{
const std::string keypath_str(buffer.begin(), buffer.end());
std::vector<uint32_t> keypath;
diff --git a/src/test/fuzz/parse_iso8601.cpp b/src/test/fuzz/parse_iso8601.cpp
index c86f8a853e..dcb24ac127 100644
--- a/src/test/fuzz/parse_iso8601.cpp
+++ b/src/test/fuzz/parse_iso8601.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -11,7 +11,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(parse_iso8601)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/parse_numbers.cpp b/src/test/fuzz/parse_numbers.cpp
index 59f89dc9fb..ddd2bcfba3 100644
--- a/src/test/fuzz/parse_numbers.cpp
+++ b/src/test/fuzz/parse_numbers.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-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.
@@ -8,7 +8,7 @@
#include <string>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(parse_numbers)
{
const std::string random_string(buffer.begin(), buffer.end());
diff --git a/src/test/fuzz/parse_script.cpp b/src/test/fuzz/parse_script.cpp
index 21ac1aecf3..060ad3db12 100644
--- a/src/test/fuzz/parse_script.cpp
+++ b/src/test/fuzz/parse_script.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-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.
@@ -6,7 +6,7 @@
#include <script/script.h>
#include <test/fuzz/fuzz.h>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(parse_script)
{
const std::string script_string(buffer.begin(), buffer.end());
try {
diff --git a/src/test/fuzz/parse_univalue.cpp b/src/test/fuzz/parse_univalue.cpp
index a269378607..afe382ba21 100644
--- a/src/test/fuzz/parse_univalue.cpp
+++ b/src/test/fuzz/parse_univalue.cpp
@@ -12,13 +12,13 @@
#include <limits>
#include <string>
-void initialize()
+void initialize_parse_univalue()
{
static const ECCVerifyHandle verify_handle;
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(parse_univalue, initialize_parse_univalue)
{
const std::string random_string(buffer.begin(), buffer.end());
bool valid = true;
diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp
index 6c94a47f3c..fff893fb3f 100644
--- a/src/test/fuzz/policy_estimator.cpp
+++ b/src/test/fuzz/policy_estimator.cpp
@@ -14,62 +14,58 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_policy_estimator()
{
- InitializeFuzzingContext();
+ static const auto testing_setup = MakeFuzzingContext<>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(policy_estimator, initialize_policy_estimator)
{
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 std::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()) {
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
if (!mtx) {
- break;
+ return;
}
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;
- }
- }
+ 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());
+ }
+ },
+ [&] {
+ std::vector<CTxMemPoolEntry> mempool_entries;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::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);
+ },
+ [&] {
+ (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider), /* inBlock */ fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ block_policy_estimator.FlushUnconfirmed();
+ });
(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);
+ (void)block_policy_estimator.estimateRawFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeFloatingPoint<double>(), fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS), 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}));
+ (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray(ALL_FEE_ESTIMATE_HORIZONS));
}
{
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
diff --git a/src/test/fuzz/policy_estimator_io.cpp b/src/test/fuzz/policy_estimator_io.cpp
index 0edcf201c7..73242870a0 100644
--- a/src/test/fuzz/policy_estimator_io.cpp
+++ b/src/test/fuzz/policy_estimator_io.cpp
@@ -10,12 +10,12 @@
#include <cstdint>
#include <vector>
-void initialize()
+void initialize_policy_estimator_io()
{
- InitializeFuzzingContext();
+ static const auto testing_setup = MakeFuzzingContext<>();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(policy_estimator_io, initialize_policy_estimator_io)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
diff --git a/src/test/fuzz/pow.cpp b/src/test/fuzz/pow.cpp
index b7fc72373d..c4348495bf 100644
--- a/src/test/fuzz/pow.cpp
+++ b/src/test/fuzz/pow.cpp
@@ -15,12 +15,12 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_pow()
{
SelectParams(CBaseChainParams::MAIN);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(pow, initialize_pow)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const Consensus::Params& consensus_params = Params().GetConsensus();
@@ -43,7 +43,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
current_block.nHeight = current_height;
}
if (fuzzed_data_provider.ConsumeBool()) {
- current_block.nTime = fixed_time + current_height * consensus_params.nPowTargetSpacing;
+ const uint32_t seconds = current_height * consensus_params.nPowTargetSpacing;
+ if (!AdditionOverflow(fixed_time, seconds)) {
+ current_block.nTime = fixed_time + seconds;
+ }
}
if (fuzzed_data_provider.ConsumeBool()) {
current_block.nBits = fixed_bits;
diff --git a/src/test/fuzz/prevector.cpp b/src/test/fuzz/prevector.cpp
index 626e187cbd..51956bbe9e 100644
--- a/src/test/fuzz/prevector.cpp
+++ b/src/test/fuzz/prevector.cpp
@@ -204,7 +204,7 @@ public:
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(prevector)
{
FuzzedDataProvider prov(buffer.data(), buffer.size());
prevector_tester<8, int> test;
diff --git a/src/test/fuzz/primitives_transaction.cpp b/src/test/fuzz/primitives_transaction.cpp
index 4a0f920f58..48815c8910 100644
--- a/src/test/fuzz/primitives_transaction.cpp
+++ b/src/test/fuzz/primitives_transaction.cpp
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(primitives_transaction)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const CScript script = ConsumeScript(fuzzed_data_provider);
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index 9390399878..e7cc0f5297 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -13,6 +13,7 @@
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
@@ -32,59 +33,81 @@
#include <vector>
namespace {
-
-#ifdef MESSAGE_TYPE
-#define TO_STRING_(s) #s
-#define TO_STRING(s) TO_STRING_(s)
-const std::string LIMIT_TO_MESSAGE_TYPE{TO_STRING(MESSAGE_TYPE)};
-#else
-const std::string LIMIT_TO_MESSAGE_TYPE;
-#endif
-
const TestingSetup* g_setup;
} // namespace
-void initialize()
+void initialize_process_message()
{
- static TestingSetup setup{
- CBaseChainParams::REGTEST,
- {
- "-nodebuglogfile",
- },
- };
- g_setup = &setup;
-
+ static const auto testing_setup = MakeFuzzingContext<const TestingSetup>();
+ g_setup = testing_setup.get();
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
}
SyncWithValidationInterfaceQueue();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+void fuzz_target(const std::vector<uint8_t>& buffer, const std::string& LIMIT_TO_MESSAGE_TYPE)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get();
TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate();
+ SetMockTime(1610000000); // any time to successfully reset ibd
chainstate.ResetIbd();
+
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) {
return;
}
- const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()};
- if (jump_out_of_ibd) chainstate.JumpOutOfIbd();
- CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
- CNode& p2p_node = *MakeUnique<CNode>(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND_FULL_RELAY).release();
- p2p_node.fSuccessfullyConnected = true;
- p2p_node.nVersion = PROTOCOL_VERSION;
- p2p_node.SetCommonVersion(PROTOCOL_VERSION);
+ CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release();
+
+ const bool successfully_connected{true};
+ p2p_node.fSuccessfullyConnected = successfully_connected;
connman.AddTestNode(p2p_node);
g_setup->m_node.peerman->InitializeNode(&p2p_node);
+ FillNode(fuzzed_data_provider, p2p_node, /* init_version */ successfully_connected);
+
+ const auto mock_time = ConsumeTime(fuzzed_data_provider);
+ SetMockTime(mock_time);
+
+ // fuzzed_data_provider is fully consumed after this call, don't use it
+ CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
try {
g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream,
GetTime<std::chrono::microseconds>(), std::atomic<bool>{false});
} catch (const std::ios_base::failure&) {
}
+ {
+ LOCK(p2p_node.cs_sendProcessing);
+ g_setup->m_node.peerman->SendMessages(&p2p_node);
+ }
SyncWithValidationInterfaceQueue();
LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement
g_setup->m_node.connman->StopNodes();
}
+
+FUZZ_TARGET_INIT(process_message, initialize_process_message) { fuzz_target(buffer, ""); }
+FUZZ_TARGET_INIT(process_message_addr, initialize_process_message) { fuzz_target(buffer, "addr"); }
+FUZZ_TARGET_INIT(process_message_block, initialize_process_message) { fuzz_target(buffer, "block"); }
+FUZZ_TARGET_INIT(process_message_blocktxn, initialize_process_message) { fuzz_target(buffer, "blocktxn"); }
+FUZZ_TARGET_INIT(process_message_cmpctblock, initialize_process_message) { fuzz_target(buffer, "cmpctblock"); }
+FUZZ_TARGET_INIT(process_message_feefilter, initialize_process_message) { fuzz_target(buffer, "feefilter"); }
+FUZZ_TARGET_INIT(process_message_filteradd, initialize_process_message) { fuzz_target(buffer, "filteradd"); }
+FUZZ_TARGET_INIT(process_message_filterclear, initialize_process_message) { fuzz_target(buffer, "filterclear"); }
+FUZZ_TARGET_INIT(process_message_filterload, initialize_process_message) { fuzz_target(buffer, "filterload"); }
+FUZZ_TARGET_INIT(process_message_getaddr, initialize_process_message) { fuzz_target(buffer, "getaddr"); }
+FUZZ_TARGET_INIT(process_message_getblocks, initialize_process_message) { fuzz_target(buffer, "getblocks"); }
+FUZZ_TARGET_INIT(process_message_getblocktxn, initialize_process_message) { fuzz_target(buffer, "getblocktxn"); }
+FUZZ_TARGET_INIT(process_message_getdata, initialize_process_message) { fuzz_target(buffer, "getdata"); }
+FUZZ_TARGET_INIT(process_message_getheaders, initialize_process_message) { fuzz_target(buffer, "getheaders"); }
+FUZZ_TARGET_INIT(process_message_headers, initialize_process_message) { fuzz_target(buffer, "headers"); }
+FUZZ_TARGET_INIT(process_message_inv, initialize_process_message) { fuzz_target(buffer, "inv"); }
+FUZZ_TARGET_INIT(process_message_mempool, initialize_process_message) { fuzz_target(buffer, "mempool"); }
+FUZZ_TARGET_INIT(process_message_notfound, initialize_process_message) { fuzz_target(buffer, "notfound"); }
+FUZZ_TARGET_INIT(process_message_ping, initialize_process_message) { fuzz_target(buffer, "ping"); }
+FUZZ_TARGET_INIT(process_message_pong, initialize_process_message) { fuzz_target(buffer, "pong"); }
+FUZZ_TARGET_INIT(process_message_sendcmpct, initialize_process_message) { fuzz_target(buffer, "sendcmpct"); }
+FUZZ_TARGET_INIT(process_message_sendheaders, initialize_process_message) { fuzz_target(buffer, "sendheaders"); }
+FUZZ_TARGET_INIT(process_message_tx, initialize_process_message) { fuzz_target(buffer, "tx"); }
+FUZZ_TARGET_INIT(process_message_verack, initialize_process_message) { fuzz_target(buffer, "verack"); }
+FUZZ_TARGET_INIT(process_message_version, initialize_process_message) { fuzz_target(buffer, "version"); }
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp
index 19ea92b750..810f0aac92 100644
--- a/src/test/fuzz/process_messages.cpp
+++ b/src/test/fuzz/process_messages.cpp
@@ -17,55 +17,50 @@
#include <validation.h>
#include <validationinterface.h>
+namespace {
const TestingSetup* g_setup;
+} // namespace
-void initialize()
+void initialize_process_messages()
{
- static TestingSetup setup{
- CBaseChainParams::REGTEST,
- {
- "-nodebuglogfile",
- },
- };
- g_setup = &setup;
-
+ static const auto testing_setup = MakeFuzzingContext<const TestingSetup>();
+ g_setup = testing_setup.get();
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
}
SyncWithValidationInterfaceQueue();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(process_messages, initialize_process_messages)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get();
TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate();
+ SetMockTime(1610000000); // any time to successfully reset ibd
chainstate.ResetIbd();
- std::vector<CNode*> peers;
- bool jump_out_of_ibd{false};
+ std::vector<CNode*> peers;
const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3);
for (int i = 0; i < num_peers_to_add; ++i) {
- const ServiceFlags service_flags = ServiceFlags(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH});
- peers.push_back(MakeUnique<CNode>(i, service_flags, 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, conn_type).release());
+ peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release());
CNode& p2p_node = *peers.back();
- p2p_node.fSuccessfullyConnected = true;
+ const bool successfully_connected{true};
+ p2p_node.fSuccessfullyConnected = successfully_connected;
p2p_node.fPauseSend = false;
- p2p_node.nVersion = PROTOCOL_VERSION;
- p2p_node.SetCommonVersion(PROTOCOL_VERSION);
g_setup->m_node.peerman->InitializeNode(&p2p_node);
+ FillNode(fuzzed_data_provider, p2p_node, /* init_version */ successfully_connected);
connman.AddTestNode(p2p_node);
}
while (fuzzed_data_provider.ConsumeBool()) {
- if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool();
- if (jump_out_of_ibd && chainstate.IsInitialBlockDownload()) chainstate.JumpOutOfIbd();
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
+ const auto mock_time = ConsumeTime(fuzzed_data_provider);
+ SetMockTime(mock_time);
+
CSerializedNetMsg net_msg;
net_msg.m_type = random_message_type;
net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
@@ -79,6 +74,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
connman.ProcessMessagesOnce(random_node);
} catch (const std::ios_base::failure&) {
}
+ {
+ LOCK(random_node.cs_sendProcessing);
+ g_setup->m_node.peerman->SendMessages(&random_node);
+ }
}
SyncWithValidationInterfaceQueue();
LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement
diff --git a/src/test/fuzz/protocol.cpp b/src/test/fuzz/protocol.cpp
index 78df0f89e7..572181366b 100644
--- a/src/test/fuzz/protocol.cpp
+++ b/src/test/fuzz/protocol.cpp
@@ -12,7 +12,7 @@
#include <stdexcept>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(protocol)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CInv> inv = ConsumeDeserializable<CInv>(fuzzed_data_provider);
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
index 908e2b16f2..0b4588c4ce 100644
--- a/src/test/fuzz/psbt.cpp
+++ b/src/test/fuzz/psbt.cpp
@@ -17,12 +17,12 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_psbt()
{
static const ECCVerifyHandle verify_handle;
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(psbt, initialize_psbt)
{
PartiallySignedTransaction psbt_mut;
const std::string raw_psbt{buffer.begin(), buffer.end()};
diff --git a/src/test/fuzz/random.cpp b/src/test/fuzz/random.cpp
index 7df6594ad6..96668734fd 100644
--- a/src/test/fuzz/random.cpp
+++ b/src/test/fuzz/random.cpp
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(random)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};
diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp
index 1fd88a5f7b..26c89a70c3 100644
--- a/src/test/fuzz/rbf.cpp
+++ b/src/test/fuzz/rbf.cpp
@@ -15,9 +15,10 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(rbf)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
if (!mtx) {
return;
diff --git a/src/test/fuzz/rolling_bloom_filter.cpp b/src/test/fuzz/rolling_bloom_filter.cpp
index 623b8cff3a..2a08b45aa3 100644
--- a/src/test/fuzz/rolling_bloom_filter.cpp
+++ b/src/test/fuzz/rolling_bloom_filter.cpp
@@ -14,7 +14,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(rolling_bloom_filter)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@@ -22,29 +22,27 @@ void test_one_input(const std::vector<uint8_t>& buffer)
fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, 1000),
0.999 / fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, std::numeric_limits<unsigned int>::max())};
while (fuzzed_data_provider.remaining_bytes() > 0) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 2)) {
- case 0: {
- const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
- (void)rolling_bloom_filter.contains(b);
- rolling_bloom_filter.insert(b);
- const bool present = rolling_bloom_filter.contains(b);
- assert(present);
- break;
- }
- case 1: {
- const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
- if (!u256) {
- break;
- }
- (void)rolling_bloom_filter.contains(*u256);
- rolling_bloom_filter.insert(*u256);
- const bool present = rolling_bloom_filter.contains(*u256);
- assert(present);
- break;
- }
- case 2:
- rolling_bloom_filter.reset();
- break;
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ (void)rolling_bloom_filter.contains(b);
+ rolling_bloom_filter.insert(b);
+ const bool present = rolling_bloom_filter.contains(b);
+ assert(present);
+ },
+ [&] {
+ const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
+ if (!u256) {
+ return;
+ }
+ (void)rolling_bloom_filter.contains(*u256);
+ rolling_bloom_filter.insert(*u256);
+ const bool present = rolling_bloom_filter.contains(*u256);
+ assert(present);
+ },
+ [&] {
+ rolling_bloom_filter.reset();
+ });
}
}
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index 4274fa4351..7fadf36f98 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -29,7 +29,7 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_script()
{
// Fuzzers using pubkey must hold an ECCVerifyHandle.
static const ECCVerifyHandle verify_handle;
@@ -37,7 +37,7 @@ void initialize()
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(script, initialize_script)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CScript> script_opt = ConsumeDeserializable<CScript>(fuzzed_data_provider);
@@ -71,7 +71,22 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)IsSolvable(signing_provider, script);
TxoutType which_type;
- (void)IsStandard(script, which_type);
+ bool is_standard_ret = IsStandard(script, which_type);
+ if (!is_standard_ret) {
+ assert(which_type == TxoutType::NONSTANDARD ||
+ which_type == TxoutType::NULL_DATA ||
+ which_type == TxoutType::MULTISIG);
+ }
+ if (which_type == TxoutType::NONSTANDARD) {
+ assert(!is_standard_ret);
+ }
+ if (which_type == TxoutType::NULL_DATA) {
+ assert(script.IsUnspendable());
+ }
+ if (script.IsUnspendable()) {
+ assert(which_type == TxoutType::NULL_DATA ||
+ which_type == TxoutType::NONSTANDARD);
+ }
(void)RecursiveDynamicUsage(script);
@@ -82,7 +97,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)script.IsPayToScriptHash();
(void)script.IsPayToWitnessScriptHash();
(void)script.IsPushOnly();
- (void)script.IsUnspendable();
(void)script.GetSigOpCount(/* fAccurate= */ false);
(void)FormatScript(script);
@@ -140,13 +154,13 @@ void test_one_input(const std::vector<uint8_t>& buffer)
{
WitnessUnknown witness_unknown_1{};
- witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<int>();
+ witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
witness_unknown_1.length = witness_unknown_program_1.size();
std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown_1.program);
WitnessUnknown witness_unknown_2{};
- witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<int>();
+ witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
const std::vector<uint8_t> witness_unknown_program_2 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
witness_unknown_2.length = witness_unknown_program_2.size();
std::copy(witness_unknown_program_2.begin(), witness_unknown_program_2.end(), witness_unknown_2.program);
diff --git a/src/test/fuzz/script_assets_test_minimizer.cpp b/src/test/fuzz/script_assets_test_minimizer.cpp
index d20fa43d68..2091ad5d91 100644
--- a/src/test/fuzz/script_assets_test_minimizer.cpp
+++ b/src/test/fuzz/script_assets_test_minimizer.cpp
@@ -188,9 +188,9 @@ void Test(const std::string& str)
ECCVerifyHandle handle;
-}
+} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(script_assets_test_minimizer)
{
if (buffer.size() < 2 || buffer.back() != '\n' || buffer[buffer.size() - 2] != ',') return;
const std::string str((const char*)buffer.data(), buffer.size() - 2);
diff --git a/src/test/fuzz/script_bitcoin_consensus.cpp b/src/test/fuzz/script_bitcoin_consensus.cpp
index 22f4b4f44a..fcd66b234e 100644
--- a/src/test/fuzz/script_bitcoin_consensus.cpp
+++ b/src/test/fuzz/script_bitcoin_consensus.cpp
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(script_bitcoin_consensus)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
diff --git a/src/test/fuzz/script_descriptor_cache.cpp b/src/test/fuzz/script_descriptor_cache.cpp
index 4bfe61cec7..1c62c018e7 100644
--- a/src/test/fuzz/script_descriptor_cache.cpp
+++ b/src/test/fuzz/script_descriptor_cache.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(script_descriptor_cache)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
DescriptorCache descriptor_cache;
diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp
index 300c78fca0..ce8915ca2c 100644
--- a/src/test/fuzz/script_flags.cpp
+++ b/src/test/fuzz/script_flags.cpp
@@ -13,12 +13,12 @@
/** Flags that are not forbidden by an assert */
static bool IsValidFlagCombination(unsigned flags);
-void initialize()
+void initialize_script_flags()
{
static const ECCVerifyHandle verify_handle;
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(script_flags, initialize_script_flags)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
try {
diff --git a/src/test/fuzz/script_interpreter.cpp b/src/test/fuzz/script_interpreter.cpp
index 26d5732f24..5d59771682 100644
--- a/src/test/fuzz/script_interpreter.cpp
+++ b/src/test/fuzz/script_interpreter.cpp
@@ -15,7 +15,7 @@
bool CastToBool(const std::vector<unsigned char>& vch);
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(script_interpreter)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
{
diff --git a/src/test/fuzz/script_ops.cpp b/src/test/fuzz/script_ops.cpp
index 7d24af20ac..bdbfe817ff 100644
--- a/src/test/fuzz/script_ops.cpp
+++ b/src/test/fuzz/script_ops.cpp
@@ -11,61 +11,58 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(script_ops)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CScript script = ConsumeScript(fuzzed_data_provider);
while (fuzzed_data_provider.remaining_bytes() > 0) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 7)) {
- case 0: {
- CScript s = ConsumeScript(fuzzed_data_provider);
- script = std::move(s);
- break;
- }
- case 1: {
- const CScript& s = ConsumeScript(fuzzed_data_provider);
- script = s;
- break;
- }
- case 2:
- script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
- break;
- case 3:
- script << ConsumeOpcodeType(fuzzed_data_provider);
- break;
- case 4:
- script << ConsumeScriptNum(fuzzed_data_provider);
- break;
- case 5:
- script << ConsumeRandomLengthByteVector(fuzzed_data_provider);
- break;
- case 6:
- script.clear();
- break;
- case 7: {
- (void)script.GetSigOpCount(false);
- (void)script.GetSigOpCount(true);
- (void)script.GetSigOpCount(script);
- (void)script.HasValidOps();
- (void)script.IsPayToScriptHash();
- (void)script.IsPayToWitnessScriptHash();
- (void)script.IsPushOnly();
- (void)script.IsUnspendable();
- {
- CScript::const_iterator pc = script.begin();
- opcodetype opcode;
- (void)script.GetOp(pc, opcode);
- std::vector<uint8_t> data;
- (void)script.GetOp(pc, opcode, data);
- (void)script.IsPushOnly(pc);
- }
- {
- int version;
- std::vector<uint8_t> program;
- (void)script.IsWitnessProgram(version, program);
- }
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ CScript s = ConsumeScript(fuzzed_data_provider);
+ script = std::move(s);
+ },
+ [&] {
+ const CScript& s = ConsumeScript(fuzzed_data_provider);
+ script = s;
+ },
+ [&] {
+ script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ },
+ [&] {
+ script << ConsumeOpcodeType(fuzzed_data_provider);
+ },
+ [&] {
+ script << ConsumeScriptNum(fuzzed_data_provider);
+ },
+ [&] {
+ script << ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ },
+ [&] {
+ script.clear();
+ },
+ [&] {
+ (void)script.GetSigOpCount(false);
+ (void)script.GetSigOpCount(true);
+ (void)script.GetSigOpCount(script);
+ (void)script.HasValidOps();
+ (void)script.IsPayToScriptHash();
+ (void)script.IsPayToWitnessScriptHash();
+ (void)script.IsPushOnly();
+ (void)script.IsUnspendable();
+ {
+ CScript::const_iterator pc = script.begin();
+ opcodetype opcode;
+ (void)script.GetOp(pc, opcode);
+ std::vector<uint8_t> data;
+ (void)script.GetOp(pc, opcode, data);
+ (void)script.IsPushOnly(pc);
+ }
+ {
+ int version;
+ std::vector<uint8_t> program;
+ (void)script.IsWitnessProgram(version, program);
+ }
+ });
}
}
diff --git a/src/test/fuzz/script_sigcache.cpp b/src/test/fuzz/script_sigcache.cpp
index 87af71897b..f7e45d6889 100644
--- a/src/test/fuzz/script_sigcache.cpp
+++ b/src/test/fuzz/script_sigcache.cpp
@@ -16,7 +16,7 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_script_sigcache()
{
static const ECCVerifyHandle ecc_verify_handle;
ECC_Start();
@@ -24,12 +24,12 @@ void initialize()
InitSignatureCache();
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(script_sigcache, initialize_script_sigcache)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
- const CTransaction tx = mutable_transaction ? CTransaction{*mutable_transaction} : CTransaction{};
+ const CTransaction tx{mutable_transaction ? *mutable_transaction : CMutableTransaction{}};
const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
const CAmount amount = ConsumeMoney(fuzzed_data_provider);
const bool store = fuzzed_data_provider.ConsumeBool();
diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp
index c626f950e7..fe850a6959 100644
--- a/src/test/fuzz/script_sign.cpp
+++ b/src/test/fuzz/script_sign.cpp
@@ -22,14 +22,14 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_script_sign()
{
static const ECCVerifyHandle ecc_verify_handle;
ECC_Start();
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128);
diff --git a/src/test/fuzz/scriptnum_ops.cpp b/src/test/fuzz/scriptnum_ops.cpp
index 68c1ae58ca..bc4867839c 100644
--- a/src/test/fuzz/scriptnum_ops.cpp
+++ b/src/test/fuzz/scriptnum_ops.cpp
@@ -24,110 +24,104 @@ bool IsValidSubtraction(const CScriptNum& lhs, const CScriptNum& rhs)
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(scriptnum_ops)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
CScriptNum script_num = ConsumeScriptNum(fuzzed_data_provider);
while (fuzzed_data_provider.remaining_bytes() > 0) {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 11)) {
- case 0: {
- const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>();
- assert((script_num == i) != (script_num != i));
- assert((script_num <= i) != (script_num > i));
- assert((script_num >= i) != (script_num < i));
- // Avoid signed integer overflow:
- // script/script.h:264:93: runtime error: signed integer overflow: -2261405121394637306 + -9223372036854775802 cannot be represented in type 'long'
- if (IsValidAddition(script_num, CScriptNum{i})) {
- assert((script_num + i) - i == script_num);
- }
- // Avoid signed integer overflow:
- // script/script.h:265:93: runtime error: signed integer overflow: 9223371895120855039 - -9223372036854710486 cannot be represented in type 'long'
- if (IsValidSubtraction(script_num, CScriptNum{i})) {
- assert((script_num - i) + i == script_num);
- }
- break;
- }
- case 1: {
- const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
- assert((script_num == random_script_num) != (script_num != random_script_num));
- assert((script_num <= random_script_num) != (script_num > random_script_num));
- assert((script_num >= random_script_num) != (script_num < random_script_num));
- // Avoid signed integer overflow:
- // script/script.h:264:93: runtime error: signed integer overflow: -9223126527765971126 + -9223372036854756825 cannot be represented in type 'long'
- if (IsValidAddition(script_num, random_script_num)) {
- assert((script_num + random_script_num) - random_script_num == script_num);
- }
- // Avoid signed integer overflow:
- // script/script.h:265:93: runtime error: signed integer overflow: 6052837899185946624 - -9223372036854775808 cannot be represented in type 'long'
- if (IsValidSubtraction(script_num, random_script_num)) {
- assert((script_num - random_script_num) + random_script_num == script_num);
- }
- break;
- }
- case 2: {
- const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
- if (!IsValidAddition(script_num, random_script_num)) {
- // Avoid assertion failure:
- // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed.
- break;
- }
- script_num += random_script_num;
- break;
- }
- case 3: {
- const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
- if (!IsValidSubtraction(script_num, random_script_num)) {
- // Avoid assertion failure:
- // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed.
- break;
- }
- script_num -= random_script_num;
- break;
- }
- case 4:
- script_num = script_num & fuzzed_data_provider.ConsumeIntegral<int64_t>();
- break;
- case 5:
- script_num = script_num & ConsumeScriptNum(fuzzed_data_provider);
- break;
- case 6:
- script_num &= ConsumeScriptNum(fuzzed_data_provider);
- break;
- case 7:
- if (script_num == CScriptNum{std::numeric_limits<int64_t>::min()}) {
- // Avoid assertion failure:
- // ./script/script.h:279: CScriptNum CScriptNum::operator-() const: Assertion `m_value != std::numeric_limits<int64_t>::min()' failed.
- break;
- }
- script_num = -script_num;
- break;
- case 8:
- script_num = fuzzed_data_provider.ConsumeIntegral<int64_t>();
- break;
- case 9: {
- const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>();
- if (!IsValidAddition(script_num, CScriptNum{random_integer})) {
- // Avoid assertion failure:
- // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed.
- break;
- }
- script_num += random_integer;
- break;
- }
- case 10: {
- const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>();
- if (!IsValidSubtraction(script_num, CScriptNum{random_integer})) {
- // Avoid assertion failure:
- // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed.
- break;
- }
- script_num -= random_integer;
- break;
- }
- case 11:
- script_num &= fuzzed_data_provider.ConsumeIntegral<int64_t>();
- break;
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ assert((script_num == i) != (script_num != i));
+ assert((script_num <= i) != (script_num > i));
+ assert((script_num >= i) != (script_num < i));
+ // Avoid signed integer overflow:
+ // script/script.h:264:93: runtime error: signed integer overflow: -2261405121394637306 + -9223372036854775802 cannot be represented in type 'long'
+ if (IsValidAddition(script_num, CScriptNum{i})) {
+ assert((script_num + i) - i == script_num);
+ }
+ // Avoid signed integer overflow:
+ // script/script.h:265:93: runtime error: signed integer overflow: 9223371895120855039 - -9223372036854710486 cannot be represented in type 'long'
+ if (IsValidSubtraction(script_num, CScriptNum{i})) {
+ assert((script_num - i) + i == script_num);
+ }
+ },
+ [&] {
+ const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
+ assert((script_num == random_script_num) != (script_num != random_script_num));
+ assert((script_num <= random_script_num) != (script_num > random_script_num));
+ assert((script_num >= random_script_num) != (script_num < random_script_num));
+ // Avoid signed integer overflow:
+ // script/script.h:264:93: runtime error: signed integer overflow: -9223126527765971126 + -9223372036854756825 cannot be represented in type 'long'
+ if (IsValidAddition(script_num, random_script_num)) {
+ assert((script_num + random_script_num) - random_script_num == script_num);
+ }
+ // Avoid signed integer overflow:
+ // script/script.h:265:93: runtime error: signed integer overflow: 6052837899185946624 - -9223372036854775808 cannot be represented in type 'long'
+ if (IsValidSubtraction(script_num, random_script_num)) {
+ assert((script_num - random_script_num) + random_script_num == script_num);
+ }
+ },
+ [&] {
+ const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
+ if (!IsValidAddition(script_num, random_script_num)) {
+ // Avoid assertion failure:
+ // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed.
+ return;
+ }
+ script_num += random_script_num;
+ },
+ [&] {
+ const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider);
+ if (!IsValidSubtraction(script_num, random_script_num)) {
+ // Avoid assertion failure:
+ // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed.
+ return;
+ }
+ script_num -= random_script_num;
+ },
+ [&] {
+ script_num = script_num & fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ },
+ [&] {
+ script_num = script_num & ConsumeScriptNum(fuzzed_data_provider);
+ },
+ [&] {
+ script_num &= ConsumeScriptNum(fuzzed_data_provider);
+ },
+ [&] {
+ if (script_num == CScriptNum{std::numeric_limits<int64_t>::min()}) {
+ // Avoid assertion failure:
+ // ./script/script.h:279: CScriptNum CScriptNum::operator-() const: Assertion `m_value != std::numeric_limits<int64_t>::min()' failed.
+ return;
+ }
+ script_num = -script_num;
+ },
+ [&] {
+ script_num = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ },
+ [&] {
+ const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ if (!IsValidAddition(script_num, CScriptNum{random_integer})) {
+ // Avoid assertion failure:
+ // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed.
+ return;
+ }
+ script_num += random_integer;
+ },
+ [&] {
+ const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ if (!IsValidSubtraction(script_num, CScriptNum{random_integer})) {
+ // Avoid assertion failure:
+ // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed.
+ return;
+ }
+ script_num -= random_integer;
+ },
+ [&] {
+ script_num &= fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ });
(void)script_num.getint();
(void)script_num.getvch();
}
diff --git a/src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp b/src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp
index d4f302a8d3..0435626356 100644
--- a/src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp
+++ b/src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp
@@ -14,7 +14,7 @@
int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char* out32, const unsigned char* seckey, size_t seckeylen);
int ec_seckey_export_der(const secp256k1_context* ctx, unsigned char* seckey, size_t* seckeylen, const unsigned char* key32, bool compressed);
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(secp256k1_ec_seckey_import_export_der)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
diff --git a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp
index ed8c7aba89..f437d53b57 100644
--- a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp
+++ b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp
@@ -14,7 +14,7 @@
bool SigHasLowR(const secp256k1_ecdsa_signature* sig);
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char* input, size_t inputlen);
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::vector<uint8_t> signature_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp
index e121c89665..3e7b72805e 100644
--- a/src/test/fuzz/signature_checker.cpp
+++ b/src/test/fuzz/signature_checker.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void initialize()
+void initialize_signature_checker()
{
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
}
@@ -24,7 +24,7 @@ class FuzzedSignatureChecker : public BaseSignatureChecker
FuzzedDataProvider& m_fuzzed_data_provider;
public:
- FuzzedSignatureChecker(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider(fuzzed_data_provider)
+ explicit FuzzedSignatureChecker(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider(fuzzed_data_provider)
{
}
@@ -52,7 +52,7 @@ public:
};
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(signature_checker, initialize_signature_checker)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
diff --git a/src/test/fuzz/signet.cpp b/src/test/fuzz/signet.cpp
index 786f1a83fe..83effec064 100644
--- a/src/test/fuzz/signet.cpp
+++ b/src/test/fuzz/signet.cpp
@@ -15,12 +15,12 @@
#include <optional>
#include <vector>
-void initialize()
+void initialize_signet()
{
- InitializeFuzzingContext(CBaseChainParams::SIGNET);
+ static const auto testing_setup = MakeFuzzingContext<>(CBaseChainParams::SIGNET);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(signet, initialize_signet)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
const std::optional<CBlock> block = ConsumeDeserializable<CBlock>(fuzzed_data_provider);
diff --git a/src/test/fuzz/span.cpp b/src/test/fuzz/span.cpp
index f6b6e8f6f0..8f753948df 100644
--- a/src/test/fuzz/span.cpp
+++ b/src/test/fuzz/span.cpp
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(span)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/spanparsing.cpp b/src/test/fuzz/spanparsing.cpp
index e5bf5dd608..b8996632bc 100644
--- a/src/test/fuzz/spanparsing.cpp
+++ b/src/test/fuzz/spanparsing.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -6,7 +6,7 @@
#include <test/fuzz/fuzz.h>
#include <util/spanparsing.h>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(spanparsing)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>();
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 271062dc95..282a2cd8ca 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -33,7 +33,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(string)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string random_string_1 = fuzzed_data_provider.ConsumeRandomLengthString(32);
diff --git a/src/test/fuzz/strprintf.cpp b/src/test/fuzz/strprintf.cpp
index 29064bc45c..b66a7abfb3 100644
--- a/src/test/fuzz/strprintf.cpp
+++ b/src/test/fuzz/strprintf.cpp
@@ -4,6 +4,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <tinyformat.h>
#include <util/strencodings.h>
#include <util/translation.h>
@@ -13,7 +14,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(str_printf)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string format_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
@@ -109,32 +110,32 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
try {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 5)) {
- case 0:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32));
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeRandomLengthString(32));
- break;
- case 1:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32).c_str());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeRandomLengthString(32).c_str());
- break;
- case 2:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<signed char>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<signed char>());
- break;
- case 3:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<unsigned char>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<unsigned char>());
- break;
- case 4:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<char>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<char>());
- break;
- case 5:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeBool());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeBool());
- break;
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32));
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeRandomLengthString(32));
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeRandomLengthString(32).c_str());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeRandomLengthString(32).c_str());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<signed char>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<signed char>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<unsigned char>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<unsigned char>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<char>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<char>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeBool());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeBool());
+ });
} catch (const tinyformat::format_error&) {
}
@@ -155,40 +156,40 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
try {
- switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 7)) {
- case 0:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeFloatingPoint<float>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeFloatingPoint<float>());
- break;
- case 1:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeFloatingPoint<double>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeFloatingPoint<double>());
- break;
- case 2:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int16_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int16_t>());
- break;
- case 3:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint16_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint16_t>());
- break;
- case 4:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int32_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int32_t>());
- break;
- case 5:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint32_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint32_t>());
- break;
- case 6:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int64_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int64_t>());
- break;
- case 7:
- (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- break;
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeFloatingPoint<float>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeFloatingPoint<float>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeFloatingPoint<double>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeFloatingPoint<double>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int16_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int16_t>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint16_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint16_t>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int32_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int32_t>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint32_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint32_t>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<int64_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<int64_t>());
+ },
+ [&] {
+ (void)strprintf(format_string, fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ (void)tinyformat::format(bilingual_string, fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ });
} catch (const tinyformat::format_error&) {
}
}
diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp
index 01b523cee4..47b38b6d23 100644
--- a/src/test/fuzz/system.cpp
+++ b/src/test/fuzz/system.cpp
@@ -22,7 +22,7 @@ std::string GetArgumentName(const std::string& name)
}
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(system)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
ArgsManager args_manager{};
@@ -32,71 +32,63 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
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;
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16));
+ },
+ [&] {
+ args_manager.SoftSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ },
+ [&] {
+ args_manager.ForceSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ },
+ [&] {
+ args_manager.SoftSetBoolArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeBool());
+ },
+ [&] {
+ 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) {
+ return;
}
- if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) {
- continue;
+ args_manager.AddArg(argument_name, fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeIntegral<unsigned int>(), options_category);
+ },
+ [&] {
+ // 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);
}
- 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;
- }
- }
+ args_manager.AddHiddenArgs(hidden_arguments);
+ },
+ [&] {
+ args_manager.ClearArgs();
+ },
+ [&] {
+ 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&) {
+ }
+ });
}
const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16);
diff --git a/src/test/fuzz/timedata.cpp b/src/test/fuzz/timedata.cpp
index a0e579a88f..d7fa66298a 100644
--- a/src/test/fuzz/timedata.cpp
+++ b/src/test/fuzz/timedata.cpp
@@ -11,7 +11,7 @@
#include <string>
#include <vector>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(timedata)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000);
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 4f972dea1c..13ae450756 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -21,12 +21,12 @@
#include <cassert>
-void initialize()
+void initialize_transaction()
{
SelectParams(CBaseChainParams::REGTEST);
}
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET_INIT(transaction, initialize_transaction)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
try {
@@ -42,7 +42,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
return CTransaction(deserialize, ds);
} catch (const std::ios_base::failure&) {
valid_tx = false;
- return CTransaction();
+ return CTransaction{CMutableTransaction{}};
}
}();
bool valid_mutable_tx = true;
diff --git a/src/test/fuzz/tx_in.cpp b/src/test/fuzz/tx_in.cpp
index 8e116537d1..f8247c1fa4 100644
--- a/src/test/fuzz/tx_in.cpp
+++ b/src/test/fuzz/tx_in.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -12,7 +12,7 @@
#include <cassert>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(tx_in)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CTxIn tx_in;
diff --git a/src/test/fuzz/tx_out.cpp b/src/test/fuzz/tx_out.cpp
index aa1338d5ba..39a50b6c80 100644
--- a/src/test/fuzz/tx_out.cpp
+++ b/src/test/fuzz/tx_out.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-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.
@@ -10,7 +10,7 @@
#include <test/fuzz/fuzz.h>
#include <version.h>
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(tx_out)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
CTxOut tx_out;
diff --git a/src/test/fuzz/txrequest.cpp b/src/test/fuzz/txrequest.cpp
index 9529ad3274..72438ff2d7 100644
--- a/src/test/fuzz/txrequest.cpp
+++ b/src/test/fuzz/txrequest.cpp
@@ -310,7 +310,7 @@ public:
};
} // namespace
-void test_one_input(const std::vector<uint8_t>& buffer)
+FUZZ_TARGET(txrequest)
{
// Tester object (which encapsulates a TxRequestTracker).
Tester tester;
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
new file mode 100644
index 0000000000..0a541e4186
--- /dev/null
+++ b/src/test/fuzz/util.cpp
@@ -0,0 +1,25 @@
+// Copyright (c) 2021 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/util.h>
+#include <version.h>
+
+void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept
+{
+ const ServiceFlags remote_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
+ const NetPermissionFlags permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
+ const int32_t version = fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max());
+ const bool filter_txs = fuzzed_data_provider.ConsumeBool();
+
+ node.nServices = remote_services;
+ node.m_permissionFlags = permission_flags;
+ if (init_version) {
+ node.nVersion = version;
+ node.SetCommonVersion(std::min(version, PROTOCOL_VERSION));
+ }
+ if (node.m_tx_relay != nullptr) {
+ LOCK(node.m_tx_relay->cs_filter);
+ node.m_tx_relay->fRelayTxes = filter_txs;
+ }
+}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 481ffa3da4..7a2dcfe84a 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -22,10 +22,12 @@
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <txmempool.h>
#include <uint256.h>
#include <util/time.h>
+#include <util/vector.h>
#include <version.h>
#include <algorithm>
@@ -35,23 +37,34 @@
#include <string>
#include <vector>
-NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+template <typename... Callables>
+void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
+{
+ constexpr size_t call_size{sizeof...(callables)};
+ static_assert(call_size >= 1);
+ const size_t call_index{fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, call_size - 1)};
+
+ size_t i{0};
+ return ((i++ == call_index ? callables() : void()), ...);
+}
+
+[[nodiscard]] inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length);
return {s.begin(), s.end()};
}
-NODISCARD inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
}
-NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
return CDataStream{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
}
-NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
+[[nodiscard]] inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
{
const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
std::vector<std::string> r;
@@ -62,7 +75,7 @@ NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(Fuzzed
}
template <typename T>
-NODISCARD inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16) noexcept
+[[nodiscard]] inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16) noexcept
{
const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
std::vector<T> r;
@@ -73,7 +86,7 @@ NODISCARD inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProv
}
template <typename T>
-NODISCARD inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
const std::vector<uint8_t> buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
CDataStream ds{buffer, SER_NETWORK, INIT_PROTO_VERSION};
@@ -86,35 +99,44 @@ NODISCARD inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzz
return obj;
}
-NODISCARD inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept
+template <typename WeakEnumType, size_t size>
+[[nodiscard]] WeakEnumType ConsumeWeakEnum(FuzzedDataProvider& fuzzed_data_provider, const WeakEnumType (&all_types)[size]) noexcept
+{
+ return fuzzed_data_provider.ConsumeBool() ?
+ fuzzed_data_provider.PickValueInArray<WeakEnumType>(all_types) :
+ WeakEnumType(fuzzed_data_provider.ConsumeIntegral<typename std::underlying_type<WeakEnumType>::type>());
+}
+
+[[nodiscard]] inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return static_cast<opcodetype>(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE));
}
-NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
}
-NODISCARD inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
- static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:00Z");
+ // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) is a no-op.
+ static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:01Z");
static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
}
-NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
return {b.begin(), b.end()};
}
-NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
}
-NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> v160 = fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8);
if (v160.size() != 160 / 8) {
@@ -123,7 +145,7 @@ NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider
return uint160{v160};
}
-NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8);
if (v256.size() != 256 / 8) {
@@ -132,12 +154,12 @@ NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider
return uint256{v256};
}
-NODISCARD inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return UintToArith256(ConsumeUInt256(fuzzed_data_provider));
}
-NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
+[[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'
@@ -152,45 +174,39 @@ NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzze
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
}
-NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
CTxDestination tx_destination;
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
- case 0: {
- tx_destination = CNoDestination{};
- break;
- }
- case 1: {
- tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
- break;
- }
- case 2: {
- tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
- break;
- }
- case 3: {
- tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
- break;
- }
- case 4: {
- tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
- break;
- }
- case 5: {
- WitnessUnknown witness_unknown{};
- witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<int>();
- const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown.length = witness_unknown_program_1.size();
- std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
- tx_destination = witness_unknown;
- break;
- }
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ tx_destination = CNoDestination{};
+ },
+ [&] {
+ tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ WitnessUnknown witness_unknown{};
+ witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
+ const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
+ witness_unknown.length = witness_unknown_program_1.size();
+ std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
+ tx_destination = witness_unknown;
+ });
return tx_destination;
}
template <typename T>
-NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
+[[nodiscard]] bool MultiplicationOverflow(const T i, const T j) noexcept
{
static_assert(std::is_integral<T>::value, "Integral required.");
if (std::numeric_limits<T>::is_signed) {
@@ -213,7 +229,7 @@ NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
}
template <class T>
-NODISCARD bool AdditionOverflow(const T i, const T j) noexcept
+[[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept
{
static_assert(std::is_integral<T>::value, "Integral required.");
if (std::numeric_limits<T>::is_signed) {
@@ -223,7 +239,7 @@ NODISCARD bool AdditionOverflow(const T i, const T j) noexcept
return std::numeric_limits<T>::max() - i < j;
}
-NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
+[[nodiscard]] inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
{
for (const CTxIn& tx_in : tx.vin) {
const Coin& coin = inputs.AccessCoin(tx_in.prevout);
@@ -238,7 +254,7 @@ NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsVie
* Returns a byte vector of specified size regardless of the number of remaining bytes available
* from the fuzzer. Pads with zero value bytes if needed to achieve the specified size.
*/
-NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
+[[nodiscard]] inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
{
std::vector<uint8_t> result(length);
const std::vector<uint8_t> random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(length);
@@ -248,13 +264,13 @@ NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataPro
return result;
}
-CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
+inline CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
CNetAddr net_addr;
if (network == Network::NET_IPV4) {
- const in_addr v4_addr = {
- .s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+ in_addr v4_addr = {};
+ v4_addr.s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
net_addr = CNetAddr{v4_addr};
} else if (network == Network::NET_IPV6) {
if (fuzzed_data_provider.remaining_bytes() >= 16) {
@@ -270,40 +286,55 @@ CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
return net_addr;
}
-CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
+inline CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint8_t>()};
}
-CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcept
+inline CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
}
-CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
+inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
- return {ConsumeService(fuzzed_data_provider), static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()), fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+ return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
}
-CNode ConsumeNode(FuzzedDataProvider& fuzzed_data_provider) noexcept
+template <bool ReturnUniquePtr = false>
+auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<NodeId>& node_id_in = std::nullopt) noexcept
{
- const NodeId node_id = fuzzed_data_provider.ConsumeIntegral<NodeId>();
- const ServiceFlags local_services = static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
- const int my_starting_height = fuzzed_data_provider.ConsumeIntegral<int>();
+ const NodeId node_id = node_id_in.value_or(fuzzed_data_provider.ConsumeIntegral<NodeId>());
+ const ServiceFlags local_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
const SOCKET socket = INVALID_SOCKET;
const CAddress address = ConsumeAddress(fuzzed_data_provider);
const uint64_t keyed_net_group = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
const uint64_t local_host_nonce = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
const CAddress addr_bind = ConsumeAddress(fuzzed_data_provider);
const std::string addr_name = fuzzed_data_provider.ConsumeRandomLengthString(64);
- const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH});
- const bool inbound_onion = fuzzed_data_provider.ConsumeBool();
- return {node_id, local_services, my_starting_height, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion};
+ const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES);
+ const bool inbound_onion{conn_type == ConnectionType::INBOUND ? fuzzed_data_provider.ConsumeBool() : false};
+ if constexpr (ReturnUniquePtr) {
+ return std::make_unique<CNode>(node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion);
+ } else {
+ return CNode{node_id, local_services, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion};
+ }
}
+inline std::unique_ptr<CNode> ConsumeNodeAsUniquePtr(FuzzedDataProvider& fdp, const std::optional<NodeId>& node_id_in = std::nullopt) { return ConsumeNode<true>(fdp, node_id_in); }
+
+void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept;
-void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST)
+template <class T = const BasicTestingSetup>
+std::unique_ptr<T> MakeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST, const std::vector<const char*>& extra_args = {})
{
- static const BasicTestingSetup basic_testing_setup{chain_name, {"-nodebuglogfile"}};
+ // Prepend default arguments for fuzzing
+ const std::vector<const char*> arguments = Cat(
+ {
+ "-nodebuglogfile",
+ },
+ extra_args);
+
+ return MakeUnique<T>(chain_name, arguments);
}
class FuzzedFileProvider
@@ -322,32 +353,26 @@ public:
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;
- }
- }
+ CallOneOf(
+ m_fuzzed_data_provider,
+ [&] {
+ mode = "r";
+ },
+ [&] {
+ mode = "r+";
+ },
+ [&] {
+ mode = "w";
+ },
+ [&] {
+ mode = "w+";
+ },
+ [&] {
+ mode = "a";
+ },
+ [&] {
+ mode = "a+";
+ });
#ifdef _GNU_SOURCE
const cookie_io_functions_t io_hooks = {
FuzzedFileProvider::read,
@@ -419,7 +444,7 @@ public:
}
};
-NODISCARD inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {fuzzed_data_provider};
}
@@ -440,71 +465,69 @@ public:
}
};
-NODISCARD inline FuzzedAutoFileProvider ConsumeAutoFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[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; \
+#define WRITE_TO_STREAM_CASE(type, consume) \
+ [&] { \
+ type o = consume; \
+ stream << o; \
}
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))
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ WRITE_TO_STREAM_CASE(bool, fuzzed_data_provider.ConsumeBool()),
+ WRITE_TO_STREAM_CASE(char, fuzzed_data_provider.ConsumeIntegral<char>()),
+ WRITE_TO_STREAM_CASE(int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>()),
+ WRITE_TO_STREAM_CASE(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()),
+ WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()),
+ WRITE_TO_STREAM_CASE(uint16_t, fuzzed_data_provider.ConsumeIntegral<uint16_t>()),
+ WRITE_TO_STREAM_CASE(int32_t, fuzzed_data_provider.ConsumeIntegral<int32_t>()),
+ WRITE_TO_STREAM_CASE(uint32_t, fuzzed_data_provider.ConsumeIntegral<uint32_t>()),
+ WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()),
+ WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()),
+ WRITE_TO_STREAM_CASE(float, fuzzed_data_provider.ConsumeFloatingPoint<float>()),
+ WRITE_TO_STREAM_CASE(double, fuzzed_data_provider.ConsumeFloatingPoint<double>()),
+ WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)),
+ WRITE_TO_STREAM_CASE(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; \
+#define READ_FROM_STREAM_CASE(type) \
+ [&] { \
+ type o; \
+ stream >> o; \
}
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>)
- }
+ CallOneOf(
+ fuzzed_data_provider,
+ READ_FROM_STREAM_CASE(bool),
+ READ_FROM_STREAM_CASE(char),
+ READ_FROM_STREAM_CASE(int8_t),
+ READ_FROM_STREAM_CASE(uint8_t),
+ READ_FROM_STREAM_CASE(int16_t),
+ READ_FROM_STREAM_CASE(uint16_t),
+ READ_FROM_STREAM_CASE(int32_t),
+ READ_FROM_STREAM_CASE(uint32_t),
+ READ_FROM_STREAM_CASE(int64_t),
+ READ_FROM_STREAM_CASE(uint64_t),
+ READ_FROM_STREAM_CASE(float),
+ READ_FROM_STREAM_CASE(double),
+ READ_FROM_STREAM_CASE(std::string),
+ READ_FROM_STREAM_CASE(std::vector<char>));
} catch (const std::ios_base::failure&) {
break;
}