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