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