Bitcoin Core  29.1.0
P2P Digital Currency
overflow.cpp
Go to the documentation of this file.
1 // Copyright (c) 2025-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 
6 #include <test/fuzz/fuzz.h>
7 #include <util/check.h>
8 #include <util/overflow.h>
9 
10 #include <algorithm>
11 #include <limits>
12 #include <optional>
13 
14 namespace {
16 template <typename T, typename W>
17 void TestOverflow(FuzzedDataProvider& fuzzed_data_provider)
18 {
19  constexpr auto min{std::numeric_limits<T>::min()};
20  constexpr auto max{std::numeric_limits<T>::max()};
21  // Range needs to be at least twice as big to allow two numbers to be added without overflowing.
22  static_assert(min >= std::numeric_limits<W>::min() / 2);
23  static_assert(max <= std::numeric_limits<W>::max() / 2);
24 
25  auto widen = [](T value) -> W { return value; };
26  auto clamp = [](W value) -> W { return std::clamp<W>(value, min, max); };
27  auto check = [](W value) -> std::optional<W> { if (value >= min && value <= max) return value; else return std::nullopt; };
28 
29  const T i = fuzzed_data_provider.ConsumeIntegral<T>();
30  const T j = fuzzed_data_provider.ConsumeIntegral<T>();
31  const unsigned shift = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, std::numeric_limits<W>::digits - std::numeric_limits<T>::digits);
32 
33  Assert(clamp(widen(i) + widen(j)) == SaturatingAdd(i, j));
34  Assert(check(widen(i) + widen(j)) == CheckedAdd(i, j));
35 
36  Assert(clamp(widen(i) << shift) == SaturatingLeftShift(i, shift));
37  Assert(check(widen(i) << shift) == CheckedLeftShift(i, shift));
38 }
39 } // namespace
40 
41 FUZZ_TARGET(overflow)
42 {
43  FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
44  TestOverflow<int8_t, int64_t>(fuzzed_data_provider);
45  TestOverflow<int16_t, int64_t>(fuzzed_data_provider);
46  TestOverflow<int32_t, int64_t>(fuzzed_data_provider);
47  TestOverflow<uint8_t, uint64_t>(fuzzed_data_provider);
48  TestOverflow<uint16_t, uint64_t>(fuzzed_data_provider);
49  TestOverflow<uint32_t, uint64_t>(fuzzed_data_provider);
50 }
FUZZ_TARGET(overflow)
Definition: overflow.cpp:41
constexpr std::optional< T > CheckedLeftShift(T input, unsigned shift) noexcept
Left bit shift with overflow checking.
Definition: overflow.h:59
std::optional< T > CheckedAdd(const T i, const T j) noexcept
Definition: overflow.h:26
T SaturatingAdd(const T i, const T j) noexcept
Definition: overflow.h:35
constexpr T SaturatingLeftShift(T input, unsigned shift) noexcept
Left bit shift with safe minimum and maximum values.
Definition: overflow.h:78
T ConsumeIntegralInRange(T min, T max)
#define T(expected, seed, data)
#define Assert(val)
Identity function.
Definition: check.h:85