diff options
Diffstat (limited to 'src/test/fuzz/float.cpp')
-rw-r--r-- | src/test/fuzz/float.cpp | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/src/test/fuzz/float.cpp b/src/test/fuzz/float.cpp index d18a87d177..2f77c8949e 100644 --- a/src/test/fuzz/float.cpp +++ b/src/test/fuzz/float.cpp @@ -3,40 +3,60 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <memusage.h> -#include <serialize.h> -#include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <util/serfloat.h> #include <version.h> #include <cassert> -#include <cstdint> +#include <cmath> +#include <limits> FUZZ_TARGET(float) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); { - const double d = fuzzed_data_provider.ConsumeFloatingPoint<double>(); + const double d{[&] { + double tmp; + CallOneOf( + fuzzed_data_provider, + // an actual number + [&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); }, + // special numbers and NANs + [&] { tmp = fuzzed_data_provider.PickValueInArray({ + std::numeric_limits<double>::infinity(), + -std::numeric_limits<double>::infinity(), + std::numeric_limits<double>::min(), + -std::numeric_limits<double>::min(), + std::numeric_limits<double>::max(), + -std::numeric_limits<double>::max(), + std::numeric_limits<double>::lowest(), + -std::numeric_limits<double>::lowest(), + std::numeric_limits<double>::quiet_NaN(), + -std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::signaling_NaN(), + -std::numeric_limits<double>::signaling_NaN(), + std::numeric_limits<double>::denorm_min(), + -std::numeric_limits<double>::denorm_min(), + }); }, + // Anything from raw memory (also checks that DecodeDouble doesn't crash on any input) + [&] { tmp = DecodeDouble(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); }); + return tmp; + }()}; (void)memusage::DynamicUsage(d); - assert(ser_uint64_to_double(ser_double_to_uint64(d)) == d); - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << d; - double d_deserialized; - stream >> d_deserialized; - assert(d == d_deserialized); - } - - { - const float f = fuzzed_data_provider.ConsumeFloatingPoint<float>(); - (void)memusage::DynamicUsage(f); - assert(ser_uint32_to_float(ser_float_to_uint32(f)) == f); - - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << f; - float f_deserialized; - stream >> f_deserialized; - assert(f == f_deserialized); + uint64_t encoded = EncodeDouble(d); + if constexpr (std::numeric_limits<double>::is_iec559) { + if (!std::isnan(d)) { + uint64_t encoded_in_memory; + std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory); + assert(encoded_in_memory == encoded); + } + } + double d_deserialized = DecodeDouble(encoded); + assert(std::isnan(d) == std::isnan(d_deserialized)); + assert(std::isnan(d) || d == d_deserialized); } } |