LCOV - code coverage report
Current view: top level - src/test/fuzz - script.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 98.1 % 103 101
Test Date: 2024-12-04 04:00:22 Functions: 100.0 % 3 3
Branches: 64.4 % 146 94

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

Generated by: LCOV version 2.0-1