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