Line data Source code
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> 6 : #include <test/fuzz/FuzzedDataProvider.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 : 16 4 : FUZZ_TARGET(float) 17 : { 18 0 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 19 : 20 : { 21 0 : const double d{[&] { 22 : double tmp; 23 0 : CallOneOf( 24 0 : fuzzed_data_provider, 25 2 : // an actual number 26 0 : [&] { tmp = fuzzed_data_provider.ConsumeFloatingPoint<double>(); }, 27 : // special numbers and NANs 28 0 : [&] { 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 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 : }()}; 48 0 : (void)memusage::DynamicUsage(d); 49 : 50 0 : uint64_t encoded = EncodeDouble(d); 51 : if constexpr (std::numeric_limits<double>::is_iec559) { 52 0 : if (!std::isnan(d)) { 53 : 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 : } 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 : } 62 0 : }