Branch data Line data Source code
1 : : // Copyright (c) 2009-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 <consensus/amount.h> 6 : : #include <pubkey.h> 7 : : #include <script/interpreter.h> 8 : : #include <streams.h> 9 : : #include <test/util/script.h> 10 : : #include <version.h> 11 [ + - ]: 173 : 12 [ + - ]: 173 : #include <test/fuzz/fuzz.h> 13 : 173 : 14 [ + - - + ]: 1939 : FUZZ_TARGET(script_flags) 15 [ + - + - : 173 : { + - ] 16 : 1420 : CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); 17 : : try { 18 : : int nVersion; 19 [ + + ]: 1420 : ds >> nVersion; 20 [ + - ]: 1419 : ds.SetVersion(nVersion); 21 [ + - ]: 1420 : } catch (const std::ios_base::failure&) { 22 : : return; 23 [ + - ]: 1 : } 24 : : 25 [ + - ]: 173 : try { 26 [ + + ]: 1419 : const CTransaction tx(deserialize, ds); 27 : : 28 : : unsigned int verify_flags; 29 [ + + ]: 1382 : ds >> verify_flags; 30 : : 31 [ + - + + ]: 1369 : if (!IsValidFlagCombination(verify_flags)) return; 32 : : 33 : : unsigned int fuzzed_flags; 34 [ + + ]: 1368 : ds >> fuzzed_flags; 35 : : 36 : 1367 : std::vector<CTxOut> spent_outputs; 37 [ + + ]: 131373 : for (unsigned i = 0; i < tx.vin.size(); ++i) { 38 [ + - ]: 130023 : CTxOut prevout; 39 [ + + ]: 130023 : ds >> prevout; 40 [ + - + + ]: 130006 : if (!MoneyRange(prevout.nValue)) { 41 : : // prevouts should be consensus-valid 42 : 23473 : prevout.nValue = 1; 43 : 23473 : } 44 [ + - ]: 130006 : spent_outputs.push_back(prevout); 45 : 130023 : } 46 [ + - ]: 1350 : PrecomputedTransactionData txdata; 47 [ + - ]: 1350 : txdata.Init(tx, std::move(spent_outputs)); 48 : : 49 [ + + ]: 113929 : for (unsigned i = 0; i < tx.vin.size(); ++i) { 50 [ + - ]: 112688 : const CTxOut& prevout = txdata.m_spent_outputs.at(i); 51 [ + - ]: 112688 : const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL}; 52 : : 53 : : ScriptError serror; 54 [ + - + - : 112688 : const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror); + - ] 55 [ - + ]: 112688 : assert(ret == (serror == SCRIPT_ERR_OK)); 56 : : 57 : : // Verify that removing flags from a passing test or adding flags to a failing test does not change the result 58 [ + + ]: 112688 : if (ret) { 59 : 7795 : verify_flags &= ~fuzzed_flags; 60 : 7795 : } else { 61 : 104893 : verify_flags |= fuzzed_flags; 62 : : } 63 [ + - + + ]: 112688 : if (!IsValidFlagCombination(verify_flags)) return; 64 : : 65 : : ScriptError serror_fuzzed; 66 [ + - + - : 112579 : const bool ret_fuzzed = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror_fuzzed); + - ] 67 [ + - ]: 112579 : assert(ret_fuzzed == (serror_fuzzed == SCRIPT_ERR_OK)); 68 : : 69 [ - + ]: 112579 : assert(ret_fuzzed == ret); 70 [ + + ]: 112688 : } 71 [ + + - + ]: 1419 : } catch (const std::ios_base::failure&) { 72 : : return; 73 [ + - ]: 68 : } 74 [ - + ]: 1489 : }