LCOV - code coverage report
Current view: top level - src/test/fuzz - script_interpreter.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 67.4 % 43 29
Test Date: 2025-08-28 04:05:06 Functions: 75.0 % 4 3
Branches: 39.5 % 38 15

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2020 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 <primitives/transaction.h>
       6                 :             : #include <script/interpreter.h>
       7                 :             : #include <test/fuzz/FuzzedDataProvider.h>
       8                 :             : #include <test/fuzz/fuzz.h>
       9                 :             : #include <test/fuzz/util.h>
      10                 :             : #include <util/check.h>
      11                 :             : 
      12                 :             : #include <cstdint>
      13                 :             : #include <optional>
      14                 :             : #include <string>
      15                 :             : #include <vector>
      16                 :             : 
      17                 :             : bool CastToBool(const std::vector<unsigned char>& vch);
      18                 :             : 
      19         [ +  - ]:        1151 : FUZZ_TARGET(script_interpreter)
      20                 :             : {
      21                 :         695 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      22                 :         695 :     {
      23                 :         695 :         const CScript script_code = ConsumeScript(fuzzed_data_provider);
      24                 :         695 :         const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
      25         [ +  + ]:         695 :         if (mtx) {
      26         [ +  - ]:         455 :             const CTransaction tx_to{*mtx};
      27                 :         455 :             const unsigned int in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
      28   [ -  +  +  + ]:         455 :             if (in < tx_to.vin.size()) {
      29                 :         429 :                 auto n_hash_type = fuzzed_data_provider.ConsumeIntegral<int>();
      30                 :         429 :                 auto amount = ConsumeMoney(fuzzed_data_provider);
      31                 :         429 :                 auto sigversion = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
      32         [ +  - ]:         429 :                 (void)SignatureHash(script_code, tx_to, in, n_hash_type, amount, sigversion, nullptr);
      33                 :         429 :                 const std::optional<CMutableTransaction> mtx_precomputed = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
      34         [ +  + ]:         429 :                 if (mtx_precomputed) {
      35         [ +  - ]:         209 :                     const CTransaction tx_precomputed{*mtx_precomputed};
      36         [ +  - ]:         209 :                     const PrecomputedTransactionData precomputed_transaction_data{tx_precomputed};
      37                 :         209 :                     n_hash_type = fuzzed_data_provider.ConsumeIntegral<int>();
      38                 :         209 :                     amount = ConsumeMoney(fuzzed_data_provider);
      39                 :         209 :                     sigversion = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
      40         [ +  - ]:         209 :                     (void)SignatureHash(script_code, tx_to, in, n_hash_type, amount, sigversion, &precomputed_transaction_data);
      41                 :         418 :                 }
      42                 :         429 :             }
      43                 :         455 :         }
      44                 :         695 :     }
      45                 :         695 :     {
      46         [ +  - ]:         695 :         (void)CastToBool(ConsumeRandomLengthByteVector(fuzzed_data_provider));
      47                 :             :     }
      48                 :         695 : }
      49                 :             : 
      50                 :             : /** Differential fuzzing for SignatureHash with and without cache. */
      51         [ +  - ]:         456 : FUZZ_TARGET(sighash_cache)
      52                 :             : {
      53                 :           0 :     FuzzedDataProvider provider(buffer.data(), buffer.size());
      54                 :             : 
      55                 :             :     // Get inputs to the sighash function that won't change across types.
      56                 :           0 :     const auto scriptcode{ConsumeScript(provider)};
      57                 :           0 :     const auto tx{ConsumeTransaction(provider, std::nullopt)};
      58         [ #  # ]:           0 :     if (tx.vin.empty()) return;
      59         [ #  # ]:           0 :     const auto in_index{provider.ConsumeIntegralInRange<uint32_t>(0, tx.vin.size() - 1)};
      60                 :           0 :     const auto amount{ConsumeMoney(provider)};
      61                 :           0 :     const auto sigversion{(SigVersion)provider.ConsumeIntegralInRange(0, 1)};
      62                 :             : 
      63                 :             :     // Check the sighash function will give the same result for 100 fuzzer-generated hash types whether or not a cache is
      64                 :             :     // provided. The cache is conserved across types to exercise cache hits.
      65                 :           0 :     SigHashCache sighash_cache{};
      66         [ #  # ]:           0 :     for (int i{0}; i < 100; ++i) {
      67         [ #  # ]:           0 :         const auto hash_type{((i & 2) == 0) ? provider.ConsumeIntegral<int8_t>() : provider.ConsumeIntegral<int32_t>()};
      68         [ #  # ]:           0 :         const auto nocache_res{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion)};
      69         [ #  # ]:           0 :         const auto cache_res{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &sighash_cache)};
      70         [ #  # ]:           0 :         Assert(nocache_res == cache_res);
      71                 :             :     }
      72                 :           0 : }
        

Generated by: LCOV version 2.0-1