LCOV - code coverage report
Current view: top level - src/test/fuzz - integer.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 99.0 % 201 199
Test Date: 2026-07-27 06:47:45 Functions: 100.0 % 4 4
Branches: 54.4 % 272 148

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2019-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 <arith_uint256.h>
       6                 :             : #include <common/args.h>
       7                 :             : #include <common/system.h>
       8                 :             : #include <compressor.h>
       9                 :             : #include <consensus/amount.h>
      10                 :             : #include <consensus/merkle.h>
      11                 :             : #include <core_io.h>
      12                 :             : #include <crypto/common.h>
      13                 :             : #include <crypto/siphash.h>
      14                 :             : #include <key_io.h>
      15                 :             : #include <memusage.h>
      16                 :             : #include <netbase.h>
      17                 :             : #include <policy/policy.h>
      18                 :             : #include <policy/settings.h>
      19                 :             : #include <pow.h>
      20                 :             : #include <protocol.h>
      21                 :             : #include <pubkey.h>
      22                 :             : #include <script/script.h>
      23                 :             : #include <serialize.h>
      24                 :             : #include <streams.h>
      25                 :             : #include <test/fuzz/FuzzedDataProvider.h>
      26                 :             : #include <test/fuzz/fuzz.h>
      27                 :             : #include <test/fuzz/util.h>
      28                 :             : #include <uint256.h>
      29                 :             : #include <univalue.h>
      30                 :             : #include <util/chaintype.h>
      31                 :             : #include <util/check.h>
      32                 :             : #include <util/moneystr.h>
      33                 :             : #include <util/overflow.h>
      34                 :             : #include <util/strencodings.h>
      35                 :             : #include <util/string.h>
      36                 :             : 
      37                 :             : #include <cassert>
      38                 :             : #include <chrono>
      39                 :             : #include <limits>
      40                 :             : #include <set>
      41                 :             : #include <vector>
      42                 :             : 
      43                 :             : using util::ToString;
      44                 :             : 
      45                 :           1 : void initialize_integer()
      46                 :             : {
      47                 :           1 :     SelectParams(ChainType::REGTEST);
      48                 :           1 : }
      49                 :             : 
      50         [ +  - ]:         875 : FUZZ_TARGET(integer, .init = initialize_integer)
      51                 :             : {
      52         [ +  + ]:         401 :     if (buffer.size() < sizeof(uint256) + sizeof(uint160)) {
      53                 :             :         return;
      54                 :             :     }
      55                 :         400 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      56         [ -  + ]:         400 :     const uint256 u256(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)));
      57         [ -  + ]:         400 :     const uint160 u160(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint160)));
      58                 :         400 :     const uint64_t u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
      59                 :         400 :     const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
      60                 :         400 :     const uint32_t u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
      61                 :         400 :     const int32_t i32 = fuzzed_data_provider.ConsumeIntegral<int32_t>();
      62                 :         400 :     const uint16_t u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
      63                 :         400 :     const int16_t i16 = fuzzed_data_provider.ConsumeIntegral<int16_t>();
      64                 :         400 :     const uint8_t u8 = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
      65                 :         400 :     const int8_t i8 = fuzzed_data_provider.ConsumeIntegral<int8_t>();
      66                 :             :     // We cannot assume a specific value of std::is_signed_v<char>:
      67                 :             :     // ConsumeIntegral<char>() instead of casting from {u,}int8_t.
      68                 :         400 :     const char ch = fuzzed_data_provider.ConsumeIntegral<char>();
      69                 :         400 :     const bool b = fuzzed_data_provider.ConsumeBool();
      70                 :         400 :     const uint64_t u64_2{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
      71                 :             : 
      72                 :         400 :     const Consensus::Params& consensus_params = Params().GetConsensus();
      73                 :         400 :     (void)CheckProofOfWorkImpl(u256, u32, consensus_params);
      74         [ +  + ]:         400 :     if (u64 <= MAX_MONEY) {
      75                 :         215 :         const uint64_t compressed_money_amount = CompressAmount(u64);
      76         [ -  + ]:         215 :         assert(u64 == DecompressAmount(compressed_money_amount));
      77   [ +  +  +  -  :         215 :         static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1);
                   +  - ]
      78         [ -  + ]:         215 :         assert(compressed_money_amount <= compressed_money_amount_max);
      79                 :             :     } else {
      80                 :         185 :         (void)CompressAmount(u64);
      81                 :             :     }
      82                 :         400 :     constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"};
      83                 :         400 :     constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"};
      84                 :         400 :     std::vector v256{u256, u256_min, u256_max};
      85         [ +  - ]:         400 :     (void)ComputeMerkleRoot(std::move(v256));
      86         [ +  - ]:         400 :     (void)DecompressAmount(u64);
      87                 :         400 :     {
      88   [ +  -  +  -  :         800 :         if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
                   +  + ]
      89         [ -  + ]:          46 :             assert(parsed.value() == i64);
      90                 :             :         }
      91                 :             :     }
      92                 :         400 :     (void)GetSizeOfCompactSize(u64);
      93         [ +  - ]:         400 :     (void)GetSpecialScriptSize(u32);
      94   [ +  +  +  +  :         400 :     if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) {
                   +  + ]
      95         [ +  - ]:         294 :         (void)GetVirtualTransactionSize(i64, i64, u32);
      96                 :             :     }
      97         [ +  - ]:         400 :     (void)HexDigit(ch);
      98                 :         400 :     (void)MoneyRange(i64);
      99         [ +  - ]:         400 :     (void)ToString(i64);
     100         [ +  - ]:         400 :     (void)IsDigit(ch);
     101                 :         400 :     (void)IsSpace(ch);
     102                 :         400 :     (void)IsSwitchChar(ch);
     103                 :         400 :     (void)memusage::DynamicUsage(ch);
     104                 :         400 :     (void)memusage::DynamicUsage(i16);
     105                 :         400 :     (void)memusage::DynamicUsage(i32);
     106                 :         400 :     (void)memusage::DynamicUsage(i64);
     107                 :         400 :     (void)memusage::DynamicUsage(i8);
     108                 :         400 :     (void)memusage::DynamicUsage(u16);
     109                 :         400 :     (void)memusage::DynamicUsage(u32);
     110                 :         400 :     (void)memusage::DynamicUsage(u64);
     111                 :         400 :     (void)memusage::DynamicUsage(u8);
     112                 :         400 :     const unsigned char uch = static_cast<unsigned char>(u8);
     113                 :         400 :     (void)memusage::DynamicUsage(uch);
     114                 :         400 :     {
     115         [ +  - ]:         400 :         const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)};
     116                 :         400 :         const size_t dynamic_usage = memusage::DynamicUsage(i64s);
     117                 :         400 :         const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s);
     118                 :         400 :         assert(dynamic_usage == incremental_dynamic_usage * i64s.size());
     119                 :         400 :     }
     120         [ +  - ]:         400 :     (void)MillisToTimeval(i64);
     121         [ +  - ]:         400 :     (void)SighashToStr(uch);
     122                 :         400 :     {
     123         [ +  - ]:         400 :         CSipHasher hasher{u64, u64_2};
     124         [ +  - ]:         400 :         const PresaltedSipHasher presalted_hasher{u64, u64_2};
     125         [ +  - ]:         400 :         hasher.Write(u256);
     126   [ +  -  -  + ]:         400 :         assert(presalted_hasher(u256) == hasher.Finalize());
     127                 :         400 :         uint8_t extra[4]{};
     128                 :         400 :         WriteLE32(extra, u32);
     129         [ +  - ]:         400 :         hasher.Write(extra);
     130   [ +  -  -  + ]:         400 :         assert(presalted_hasher(u256, u32) == hasher.Finalize());
     131                 :             :     }
     132                 :         400 :     {
     133                 :         400 :         const uint64_t data0{u160.GetUint64(0)}, data1{u160.GetUint64(1)};
     134                 :         400 :         SipHasher13UJ hasher{u64, u64_2};
     135                 :         400 :         const SipHasher13UJ fixed_hasher{u64, u64_2};
     136                 :         400 :         hasher.WriteJumbo(u256);
     137         [ -  + ]:         400 :         assert(fixed_hasher.Hash(u256) == hasher.Finalize());
     138                 :         400 :         hasher.Write(data0);
     139         [ -  + ]:         400 :         assert(fixed_hasher.Hash(u256, data0) == hasher.Finalize());
     140                 :             : 
     141                 :         400 :         SipHasher13UJ reference{u64, u64_2};
     142                 :         400 :         SipHasher13UJ mixed{u64, u64_2};
     143                 :         400 :         reference.WriteJumbo(u256);
     144                 :         400 :         mixed.WriteJumbo(u256);
     145                 :             : 
     146                 :        1200 :         const auto write_normal{[](SipHasher13UJ& hasher, uint64_t data, bool as_jumbo) {
     147         [ +  + ]:         800 :             if (as_jumbo) {
     148                 :          50 :                 uint256 data256{};
     149                 :          50 :                 WriteLE64(data256.data(), data);
     150                 :          50 :                 hasher.WriteJumbo(data256);
     151                 :             :             } else {
     152                 :         750 :                 hasher.Write(data);
     153                 :             :             }
     154                 :         800 :         }};
     155                 :             : 
     156                 :         400 :         reference.Write(data0).Write(data1);
     157                 :         400 :         write_normal(mixed, data0, b);
     158                 :         400 :         write_normal(mixed, data1, u8 & 1);
     159         [ -  + ]:         400 :         assert(mixed.Finalize() == reference.Finalize());
     160                 :             : 
     161                 :         400 :         reference.WriteJumbo(u256).Write(data0);
     162         [ -  + ]:         400 :         assert(mixed.Hash(u256, data0) == reference.Finalize());
     163                 :             :     }
     164         [ +  - ]:         400 :     (void)ToLower(ch);
     165         [ +  - ]:         400 :     (void)ToUpper(ch);
     166                 :         400 :     {
     167   [ +  -  +  -  :         400 :         if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
                   +  + ]
     168         [ -  + ]:          46 :             assert(parsed.value() == i64);
     169                 :             :         }
     170                 :             :     }
     171         [ +  + ]:         400 :     if (i32 >= 0 && i32 <= 16) {
     172         [ -  + ]:           2 :         assert(i32 == CScript::DecodeOP_N(CScript::EncodeOP_N(i32)));
     173                 :             :     }
     174                 :             : 
     175         [ +  - ]:         400 :     const std::chrono::seconds seconds{i64};
     176         [ +  - ]:         400 :     assert(count_seconds(seconds) == i64);
     177                 :             : 
     178         [ +  - ]:         400 :     const CScriptNum script_num{i64};
     179                 :         400 :     (void)script_num.getint();
     180         [ +  - ]:         400 :     (void)script_num.getvch();
     181                 :             : 
     182         [ +  - ]:         400 :     const arith_uint256 au256 = UintToArith256(u256);
     183   [ +  -  -  + ]:         400 :     assert(ArithToUint256(au256) == u256);
     184   [ +  -  +  -  :        1200 :     assert(uint256::FromHex(au256.GetHex()).value() == u256);
                   -  + ]
     185         [ +  - ]:         400 :     (void)au256.bits();
     186         [ +  - ]:         400 :     (void)au256.GetCompact(/* fNegative= */ false);
     187         [ +  - ]:         400 :     (void)au256.GetCompact(/* fNegative= */ true);
     188         [ +  - ]:         400 :     (void)au256.getdouble();
     189         [ +  - ]:         400 :     (void)au256.GetHex();
     190                 :         400 :     (void)au256.GetLow64();
     191                 :         400 :     (void)au256.size();
     192         [ +  - ]:         400 :     (void)au256.ToString();
     193                 :             : 
     194         [ +  - ]:         400 :     const CKeyID key_id{u160};
     195         [ +  - ]:         400 :     const CScriptID script_id{u160};
     196                 :             : 
     197                 :         400 :     {
     198                 :         400 :         DataStream stream{};
     199                 :             : 
     200                 :         400 :         uint256 deserialized_u256;
     201         [ +  - ]:         400 :         stream << u256;
     202         [ +  - ]:         400 :         stream >> deserialized_u256;
     203   [ +  -  -  + ]:         800 :         assert(u256 == deserialized_u256 && stream.empty());
     204                 :             : 
     205                 :         400 :         uint160 deserialized_u160;
     206         [ +  - ]:         400 :         stream << u160;
     207         [ +  - ]:         400 :         stream >> deserialized_u160;
     208   [ +  -  -  + ]:         800 :         assert(u160 == deserialized_u160 && stream.empty());
     209                 :             : 
     210                 :         400 :         uint64_t deserialized_u64;
     211         [ +  - ]:         400 :         stream << u64;
     212         [ +  - ]:         400 :         stream >> deserialized_u64;
     213   [ +  -  -  + ]:         800 :         assert(u64 == deserialized_u64 && stream.empty());
     214                 :             : 
     215                 :         400 :         int64_t deserialized_i64;
     216         [ +  - ]:         400 :         stream << i64;
     217         [ +  - ]:         400 :         stream >> deserialized_i64;
     218   [ +  -  -  + ]:         800 :         assert(i64 == deserialized_i64 && stream.empty());
     219                 :             : 
     220                 :         400 :         uint32_t deserialized_u32;
     221         [ +  - ]:         400 :         stream << u32;
     222         [ +  - ]:         400 :         stream >> deserialized_u32;
     223   [ +  -  -  + ]:         800 :         assert(u32 == deserialized_u32 && stream.empty());
     224                 :             : 
     225                 :         400 :         int32_t deserialized_i32;
     226         [ +  - ]:         400 :         stream << i32;
     227         [ +  - ]:         400 :         stream >> deserialized_i32;
     228   [ +  -  -  + ]:         800 :         assert(i32 == deserialized_i32 && stream.empty());
     229                 :             : 
     230                 :         400 :         uint16_t deserialized_u16;
     231         [ +  - ]:         400 :         stream << u16;
     232         [ +  - ]:         400 :         stream >> deserialized_u16;
     233   [ +  -  -  + ]:         800 :         assert(u16 == deserialized_u16 && stream.empty());
     234                 :             : 
     235                 :         400 :         int16_t deserialized_i16;
     236         [ +  - ]:         400 :         stream << i16;
     237         [ +  - ]:         400 :         stream >> deserialized_i16;
     238   [ +  -  -  + ]:         800 :         assert(i16 == deserialized_i16 && stream.empty());
     239                 :             : 
     240                 :         400 :         uint8_t deserialized_u8;
     241         [ +  - ]:         400 :         stream << u8;
     242         [ +  - ]:         400 :         stream >> deserialized_u8;
     243   [ +  -  -  + ]:         800 :         assert(u8 == deserialized_u8 && stream.empty());
     244                 :             : 
     245                 :         400 :         int8_t deserialized_i8;
     246         [ +  - ]:         400 :         stream << i8;
     247         [ +  - ]:         400 :         stream >> deserialized_i8;
     248   [ +  -  -  + ]:         800 :         assert(i8 == deserialized_i8 && stream.empty());
     249                 :             : 
     250                 :         400 :         bool deserialized_b;
     251         [ +  - ]:         400 :         stream << b;
     252         [ +  - ]:         400 :         stream >> deserialized_b;
     253   [ +  -  -  + ]:         800 :         assert(b == deserialized_b && stream.empty());
     254                 :           0 :     }
     255                 :             : 
     256                 :         400 :     {
     257                 :         400 :         const ServiceFlags service_flags = (ServiceFlags)u64;
     258         [ +  + ]:         400 :         (void)MayHaveUsefulAddressDB(service_flags);
     259                 :             :     }
     260                 :             : 
     261                 :         400 :     {
     262                 :         400 :         DataStream stream{};
     263                 :             : 
     264         [ +  - ]:         400 :         ser_writedata64(stream, u64);
     265         [ +  - ]:         400 :         const uint64_t deserialized_u64 = ser_readdata64(stream);
     266   [ +  -  -  + ]:         800 :         assert(u64 == deserialized_u64 && stream.empty());
     267                 :             : 
     268         [ +  - ]:         400 :         ser_writedata32(stream, u32);
     269         [ +  - ]:         400 :         const uint32_t deserialized_u32 = ser_readdata32(stream);
     270   [ +  -  -  + ]:         800 :         assert(u32 == deserialized_u32 && stream.empty());
     271                 :             : 
     272         [ +  - ]:         400 :         ser_writedata32be(stream, u32);
     273         [ +  - ]:         400 :         const uint32_t deserialized_u32be = ser_readdata32be(stream);
     274   [ +  -  -  + ]:         800 :         assert(u32 == deserialized_u32be && stream.empty());
     275                 :             : 
     276         [ +  - ]:         400 :         ser_writedata16(stream, u16);
     277         [ +  - ]:         400 :         const uint16_t deserialized_u16 = ser_readdata16(stream);
     278   [ +  -  -  + ]:         800 :         assert(u16 == deserialized_u16 && stream.empty());
     279                 :             : 
     280         [ +  - ]:         400 :         ser_writedata8(stream, u8);
     281         [ +  - ]:         400 :         const uint8_t deserialized_u8 = ser_readdata8(stream);
     282   [ +  -  -  + ]:         800 :         assert(u8 == deserialized_u8 && stream.empty());
     283                 :           0 :     }
     284                 :             : 
     285                 :         400 :     {
     286                 :         400 :         DataStream stream{};
     287                 :             : 
     288         [ +  - ]:         400 :         WriteCompactSize(stream, u64);
     289                 :         400 :         try {
     290         [ +  + ]:         400 :             const uint64_t deserialized_u64 = ReadCompactSize(stream);
     291   [ +  -  -  + ]:         258 :             assert(u64 == deserialized_u64 && stream.empty());
     292         [ -  + ]:         271 :         } catch (const std::ios_base::failure&) {
     293                 :         271 :         }
     294                 :         400 :     }
     295                 :         400 : }
        

Generated by: LCOV version