Bitcoin Core  25.99.0
P2P Digital Currency
float.cpp
Go to the documentation of this file.
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>
7 #include <test/fuzz/fuzz.h>
8 #include <test/fuzz/util.h>
9 #include <util/serfloat.h>
10 #include <version.h>
11 
12 #include <cassert>
13 #include <cmath>
14 #include <limits>
15 
17 {
18  FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
19 
20  {
21  const double d{[&] {
22  double tmp;
23  CallOneOf(
24  fuzzed_data_provider,
25  // an actual number
26  [&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); },
27  // special numbers and NANs
28  [&] { 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  }); },
44  // Anything from raw memory (also checks that DecodeDouble doesn't crash on any input)
45  [&] { tmp = DecodeDouble(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); });
46  return tmp;
47  }()};
48  (void)memusage::DynamicUsage(d);
49 
50  uint64_t encoded = EncodeDouble(d);
51  if constexpr (std::numeric_limits<double>::is_iec559) {
52  if (!std::isnan(d)) {
53  uint64_t encoded_in_memory;
54  std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory);
55  assert(encoded_in_memory == encoded);
56  }
57  }
58  double d_deserialized = DecodeDouble(encoded);
59  assert(std::isnan(d) == std::isnan(d_deserialized));
60  assert(std::isnan(d) || d == d_deserialized);
61  }
62 }
T PickValueInArray(const T(&array)[size])
FUZZ_TARGET(float)
Definition: float.cpp:16
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:29
uint64_t EncodeDouble(double f) noexcept
Definition: serfloat.cpp:37
double DecodeDouble(uint64_t v) noexcept
Definition: serfloat.cpp:10
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
Definition: util.h:35
assert(!tx.IsCoinBase())