Branch data Line data Source code
1 : : // Copyright (c) 2020-2021 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 : :
15 [ + - ]: 445 : FUZZ_TARGET(float)
16 : : {
17 : 33 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
18 : :
19 : 33 : {
20 : 66 : const double d{[&] {
21 : 33 : double tmp;
22 : 33 : CallOneOf(
23 : : fuzzed_data_provider,
24 : : // an actual number
25 : 9 : [&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); },
26 : : // special numbers and NANs
27 : 7 : [&] { tmp = fuzzed_data_provider.PickValueInArray({
28 : : std::numeric_limits<double>::infinity(),
29 : : -std::numeric_limits<double>::infinity(),
30 : : std::numeric_limits<double>::min(),
31 : : -std::numeric_limits<double>::min(),
32 : : std::numeric_limits<double>::max(),
33 : : -std::numeric_limits<double>::max(),
34 : : std::numeric_limits<double>::lowest(),
35 : : -std::numeric_limits<double>::lowest(),
36 : : std::numeric_limits<double>::quiet_NaN(),
37 : : -std::numeric_limits<double>::quiet_NaN(),
38 : : std::numeric_limits<double>::signaling_NaN(),
39 : : -std::numeric_limits<double>::signaling_NaN(),
40 : : std::numeric_limits<double>::denorm_min(),
41 : : -std::numeric_limits<double>::denorm_min(),
42 : 7 : }); },
43 : : // Anything from raw memory (also checks that DecodeDouble doesn't crash on any input)
44 : 17 : [&] { tmp = DecodeDouble(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); });
45 : 33 : return tmp;
46 : 33 : }()};
47 : 33 : (void)memusage::DynamicUsage(d);
48 : :
49 : 33 : uint64_t encoded = EncodeDouble(d);
50 : 33 : if constexpr (std::numeric_limits<double>::is_iec559) {
51 [ + + ]: 33 : if (!std::isnan(d)) {
52 : 29 : uint64_t encoded_in_memory;
53 : 29 : std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory);
54 [ - + ]: 29 : assert(encoded_in_memory == encoded);
55 : : }
56 : : }
57 : 33 : double d_deserialized = DecodeDouble(encoded);
58 [ - + ]: 33 : assert(std::isnan(d) == std::isnan(d_deserialized));
59 [ + + - + ]: 33 : assert(std::isnan(d) || d == d_deserialized);
60 : : }
61 : 33 : }
|