aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz/float.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz/float.cpp')
-rw-r--r--src/test/fuzz/float.cpp64
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);
}
}