Branch data 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 : }