Branch data Line data Source code
1 : : // Copyright (c) 2020-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #include <memusage.h>
6 : : #include <test/fuzz/FuzzedDataProvider.h>
7 : : #include <test/fuzz/fuzz.h>
8 : : #include <test/fuzz/util.h>
9 : : #include <util/serfloat.h>
10 : :
11 : : #include <cassert>
12 : : #include <cmath>
13 : : #include <limits>
14 : : #include <optional>
15 : :
16 [ + - ]: 480 : FUZZ_TARGET(float)
17 : : {
18 : 48 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
19 : :
20 : 48 : {
21 : 96 : const double d{[&] {
22 : 48 : std::optional<double> tmp;
23 : 48 : CallOneOf(
24 : : fuzzed_data_provider,
25 : : // an actual number
26 : 15 : [&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); },
27 : : // special numbers and NANs
28 : 9 : [&] { tmp = fuzzed_data_provider.PickValueInArray({
29 : : std::numeric_limits<double>::infinity(),
30 : : -std::numeric_limits<double>::infinity(),
31 : : std::numeric_limits<double>::min(),
32 : : -std::numeric_limits<double>::min(),
33 : : std::numeric_limits<double>::max(),
34 : : -std::numeric_limits<double>::max(),
35 : : std::numeric_limits<double>::lowest(),
36 : : -std::numeric_limits<double>::lowest(),
37 : : std::numeric_limits<double>::quiet_NaN(),
38 : : -std::numeric_limits<double>::quiet_NaN(),
39 : : std::numeric_limits<double>::signaling_NaN(),
40 : : -std::numeric_limits<double>::signaling_NaN(),
41 : : std::numeric_limits<double>::denorm_min(),
42 : : -std::numeric_limits<double>::denorm_min(),
43 : 9 : }); },
44 : : // Anything from raw memory (also checks that DecodeDouble doesn't crash on any input)
45 : 24 : [&] { tmp = DecodeDouble(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); });
46 : 48 : return *tmp;
47 : 48 : }()};
48 : 48 : (void)memusage::DynamicUsage(d);
49 : :
50 : 48 : uint64_t encoded = EncodeDouble(d);
51 : 48 : if constexpr (std::numeric_limits<double>::is_iec559) {
52 [ + + ]: 48 : if (!std::isnan(d)) {
53 : 41 : uint64_t encoded_in_memory;
54 : 41 : std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory);
55 [ - + ]: 41 : assert(encoded_in_memory == encoded);
56 : : }
57 : : }
58 : 48 : double d_deserialized = DecodeDouble(encoded);
59 [ - + ]: 48 : assert(std::isnan(d) == std::isnan(d_deserialized));
60 [ + + - + ]: 48 : assert(std::isnan(d) || d == d_deserialized);
61 : : }
62 : 48 : }
|