LCOV - code coverage report
Current view: top level - src/test/fuzz - script.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 5 108 4.6 %
Date: 2023-10-05 12:38:51 Functions: 6 8 75.0 %
Branches: 4 220 1.8 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2019-2022 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 <chainparams.h>
       6                 :            : #include <compressor.h>
       7                 :            : #include <core_io.h>
       8                 :            : #include <core_memusage.h>
       9                 :            : #include <key_io.h>
      10                 :            : #include <policy/policy.h>
      11                 :            : #include <pubkey.h>
      12                 :            : #include <rpc/util.h>
      13                 :            : #include <script/descriptor.h>
      14                 :            : #include <script/interpreter.h>
      15                 :            : #include <script/script.h>
      16                 :            : #include <script/script_error.h>
      17         [ +  - ]:          2 : #include <script/sign.h>
      18         [ +  - ]:          2 : #include <script/signingprovider.h>
      19                 :            : #include <script/solver.h>
      20                 :            : #include <streams.h>
      21                 :            : #include <test/fuzz/FuzzedDataProvider.h>
      22                 :            : #include <test/fuzz/fuzz.h>
      23                 :            : #include <test/fuzz/util.h>
      24                 :            : #include <univalue.h>
      25                 :            : #include <util/chaintype.h>
      26                 :            : 
      27                 :          2 : #include <algorithm>
      28                 :            : #include <cassert>
      29                 :            : #include <cstdint>
      30                 :            : #include <optional>
      31                 :            : #include <string>
      32                 :            : #include <vector>
      33                 :            : 
      34                 :          0 : void initialize_script()
      35                 :            : {
      36                 :          0 :     SelectParams(ChainType::REGTEST);
      37                 :          0 : }
      38                 :            : 
      39   [ +  -  -  + ]:          4 : FUZZ_TARGET(script, .init = initialize_script)
      40                 :            : {
      41                 :          0 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      42                 :          0 :     const CScript script{ConsumeScript(fuzzed_data_provider)};
      43                 :            : 
      44         [ #  # ]:          0 :     CompressedScript compressed;
      45   [ #  #  #  # ]:          0 :     if (CompressScript(script, compressed)) {
      46         [ #  # ]:          0 :         const unsigned int size = compressed[0];
      47   [ #  #  #  # ]:          0 :         compressed.erase(compressed.begin());
      48         [ #  # ]:          0 :         assert(size <= 5);
      49         [ #  # ]:          0 :         CScript decompressed_script;
      50         [ #  # ]:          0 :         const bool ok = DecompressScript(decompressed_script, size, compressed);
      51         [ #  # ]:          0 :         assert(ok);
      52   [ #  #  #  # ]:          0 :         assert(script == decompressed_script);
      53                 :          0 :     }
      54                 :            : 
      55                 :            :     TxoutType which_type;
      56         [ #  # ]:          0 :     bool is_standard_ret = IsStandard(script, std::nullopt, which_type);
      57         [ #  # ]:          0 :     if (!is_standard_ret) {
      58   [ #  #  #  #  :          0 :         assert(which_type == TxoutType::NONSTANDARD ||
                   #  # ]
      59                 :            :                which_type == TxoutType::NULL_DATA ||
      60                 :            :                which_type == TxoutType::MULTISIG);
      61                 :          0 :     }
      62         [ #  # ]:          0 :     if (which_type == TxoutType::NONSTANDARD) {
      63         [ #  # ]:          0 :         assert(!is_standard_ret);
      64                 :          0 :     }
      65         [ #  # ]:          0 :     if (which_type == TxoutType::NULL_DATA) {
      66   [ #  #  #  # ]:          0 :         assert(script.IsUnspendable());
      67                 :          0 :     }
      68   [ #  #  #  # ]:          0 :     if (script.IsUnspendable()) {
      69   [ #  #  #  # ]:          0 :         assert(which_type == TxoutType::NULL_DATA ||
      70                 :            :                which_type == TxoutType::NONSTANDARD);
      71                 :          0 :     }
      72                 :            : 
      73         [ #  # ]:          0 :     CTxDestination address;
      74         [ #  # ]:          2 :     bool extract_destination_ret = ExtractDestination(script, address);
      75         [ #  # ]:          0 :     if (!extract_destination_ret) {
      76   [ #  #  #  #  :          0 :         assert(which_type == TxoutType::PUBKEY ||
             #  #  #  # ]
      77                 :            :                which_type == TxoutType::NONSTANDARD ||
      78                 :            :                which_type == TxoutType::NULL_DATA ||
      79                 :            :                which_type == TxoutType::MULTISIG);
      80                 :          0 :     }
      81   [ #  #  #  # ]:          0 :     if (which_type == TxoutType::NONSTANDARD ||
      82         [ #  # ]:          0 :         which_type == TxoutType::NULL_DATA ||
      83                 :          0 :         which_type == TxoutType::MULTISIG) {
      84         [ #  # ]:          0 :         assert(!extract_destination_ret);
      85                 :          0 :     }
      86                 :            : 
      87                 :          0 :     const FlatSigningProvider signing_provider;
      88         [ #  # ]:          0 :     (void)InferDescriptor(script, signing_provider);
      89         [ #  # ]:          0 :     (void)IsSegWitOutput(signing_provider, script);
      90                 :            : 
      91         [ #  # ]:          0 :     (void)RecursiveDynamicUsage(script);
      92                 :            : 
      93                 :          0 :     std::vector<std::vector<unsigned char>> solutions;
      94         [ #  # ]:          0 :     (void)Solver(script, solutions);
      95                 :            : 
      96         [ #  # ]:          0 :     (void)script.HasValidOps();
      97         [ #  # ]:          0 :     (void)script.IsPayToScriptHash();
      98         [ #  # ]:          0 :     (void)script.IsPayToWitnessScriptHash();
      99         [ #  # ]:          0 :     (void)script.IsPushOnly();
     100         [ #  # ]:          0 :     (void)script.GetSigOpCount(/* fAccurate= */ false);
     101                 :            : 
     102                 :            :     {
     103                 :          0 :         const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
     104         [ #  # ]:          0 :         CompressedScript compressed_script;
     105         [ #  # ]:          0 :         compressed_script.assign(bytes.begin(), bytes.end());
     106                 :            :         // DecompressScript(..., ..., bytes) is not guaranteed to be defined if the bytes vector is too short
     107   [ #  #  #  # ]:          0 :         if (compressed_script.size() >= 32) {
     108         [ #  # ]:          0 :             CScript decompressed_script;
     109   [ #  #  #  # ]:          0 :             DecompressScript(decompressed_script, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), compressed_script);
     110                 :          0 :         }
     111                 :          0 :     }
     112                 :            : 
     113                 :          0 :     const std::optional<CScript> other_script = ConsumeDeserializable<CScript>(fuzzed_data_provider);
     114         [ #  # ]:          0 :     if (other_script) {
     115                 :            :         {
     116         [ #  # ]:          0 :             CScript script_mut{script};
     117   [ #  #  #  # ]:          0 :             (void)FindAndDelete(script_mut, *other_script);
     118                 :          0 :         }
     119                 :          0 :         const std::vector<std::string> random_string_vector = ConsumeRandomLengthStringVector(fuzzed_data_provider);
     120         [ #  # ]:          0 :         const uint32_t u32{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
     121                 :          0 :         const uint32_t flags{u32 | SCRIPT_VERIFY_P2SH};
     122                 :            :         {
     123         [ #  # ]:          0 :             CScriptWitness wit;
     124         [ #  # ]:          0 :             for (const auto& s : random_string_vector) {
     125         [ #  # ]:          0 :                 wit.stack.emplace_back(s.begin(), s.end());
     126                 :            :             }
     127   [ #  #  #  # ]:          0 :             (void)CountWitnessSigOps(script, *other_script, &wit, flags);
     128         [ #  # ]:          0 :             wit.SetNull();
     129                 :          0 :         }
     130                 :          0 :     }
     131                 :            : 
     132         [ #  # ]:          0 :     (void)GetOpName(ConsumeOpcodeType(fuzzed_data_provider));
     133   [ #  #  #  # ]:          0 :     (void)ScriptErrorString(static_cast<ScriptError>(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, SCRIPT_ERR_ERROR_COUNT)));
     134                 :            : 
     135                 :            :     {
     136                 :          0 :         const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
     137         [ #  # ]:          0 :         CScript append_script{bytes.begin(), bytes.end()};
     138   [ #  #  #  # ]:          0 :         append_script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
     139         [ #  # ]:          0 :         append_script << ConsumeOpcodeType(fuzzed_data_provider);
     140   [ #  #  #  #  :          0 :         append_script << CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
                   #  # ]
     141         [ #  # ]:          0 :         append_script << ConsumeRandomLengthByteVector(fuzzed_data_provider);
     142                 :          0 :     }
     143                 :            : 
     144                 :            :     {
     145   [ #  #  #  # ]:          0 :         const CTxDestination tx_destination_1{
     146   [ #  #  #  # ]:          0 :             fuzzed_data_provider.ConsumeBool() ?
     147   [ #  #  #  # ]:          0 :                 DecodeDestination(fuzzed_data_provider.ConsumeRandomLengthString()) :
     148                 :          0 :                 ConsumeTxDestination(fuzzed_data_provider)};
     149                 :          0 :         const CTxDestination tx_destination_2{ConsumeTxDestination(fuzzed_data_provider)};
     150         [ #  # ]:          0 :         const std::string encoded_dest{EncodeDestination(tx_destination_1)};
     151         [ #  # ]:          0 :         const UniValue json_dest{DescribeAddress(tx_destination_1)};
     152         [ #  # ]:          0 :         (void)GetKeyForDestination(/*store=*/{}, tx_destination_1);
     153         [ #  # ]:          0 :         const CScript dest{GetScriptForDestination(tx_destination_1)};
     154         [ #  # ]:          0 :         const bool valid{IsValidDestination(tx_destination_1)};
     155                 :            : 
     156         [ #  # ]:          0 :         if (!std::get_if<PubKeyDestination>(&tx_destination_1)) {
     157                 :            :             // Only try to round trip non-pubkey destinations since PubKeyDestination has no encoding
     158   [ #  #  #  # ]:          0 :             Assert(dest.empty() != valid);
     159   [ #  #  #  #  :          0 :             Assert(tx_destination_1 == DecodeDestination(encoded_dest));
                   #  # ]
     160   [ #  #  #  # ]:          0 :             Assert(valid == IsValidDestinationString(encoded_dest));
     161                 :          0 :         }
     162                 :            : 
     163         [ #  # ]:          0 :         (void)(tx_destination_1 < tx_destination_2);
     164   [ #  #  #  # ]:          0 :         if (tx_destination_1 == tx_destination_2) {
     165   [ #  #  #  # ]:          0 :             Assert(encoded_dest == EncodeDestination(tx_destination_2));
     166   [ #  #  #  #  :          0 :             Assert(json_dest.write() == DescribeAddress(tx_destination_2).write());
             #  #  #  # ]
     167   [ #  #  #  #  :          0 :             Assert(dest == GetScriptForDestination(tx_destination_2));
                   #  # ]
     168                 :          0 :         }
     169                 :          0 :     }
     170                 :          0 : }

Generated by: LCOV version 1.14