Coverage Report

Created: 2025-04-09 20:14

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