Line data Source code
1 : // Copyright (c) 2020-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 <script/script.h> 6 : #include <test/fuzz/FuzzedDataProvider.h> 7 : #include <test/fuzz/fuzz.h> 8 : #include <test/fuzz/util.h> 9 : 10 : #include <cassert> 11 : #include <cstdint> 12 : #include <limits> 13 : #include <vector> 14 : 15 : namespace { 16 0 : bool IsValidAddition(const CScriptNum& lhs, const CScriptNum& rhs) 17 : { 18 0 : return rhs == 0 || (rhs > 0 && lhs <= CScriptNum{std::numeric_limits<int64_t>::max()} - rhs) || (rhs < 0 && lhs >= CScriptNum{std::numeric_limits<int64_t>::min()} - rhs); 19 : } 20 : 21 0 : bool IsValidSubtraction(const CScriptNum& lhs, const CScriptNum& rhs) 22 : { 23 0 : return rhs == 0 || (rhs > 0 && lhs >= CScriptNum{std::numeric_limits<int64_t>::min()} + rhs) || (rhs < 0 && lhs <= CScriptNum{std::numeric_limits<int64_t>::max()} + rhs); 24 : } 25 2 : } // namespace 26 : 27 4 : FUZZ_TARGET(scriptnum_ops) 28 : { 29 0 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 30 0 : CScriptNum script_num = ConsumeScriptNum(fuzzed_data_provider); 31 0 : LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 1000000) { 32 0 : CallOneOf( 33 : fuzzed_data_provider, 34 0 : [&] { 35 0 : const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 36 0 : assert((script_num == i) != (script_num != i)); 37 0 : assert((script_num <= i) != (script_num > i)); 38 0 : assert((script_num >= i) != (script_num < i)); 39 : // Avoid signed integer overflow: 40 : // script/script.h:264:93: runtime error: signed integer overflow: -2261405121394637306 + -9223372036854775802 cannot be represented in type 'long' 41 0 : if (IsValidAddition(script_num, CScriptNum{i})) { 42 0 : assert((script_num + i) - i == script_num); 43 0 : } 44 : // Avoid signed integer overflow: 45 : // script/script.h:265:93: runtime error: signed integer overflow: 9223371895120855039 - -9223372036854710486 cannot be represented in type 'long' 46 0 : if (IsValidSubtraction(script_num, CScriptNum{i})) { 47 0 : assert((script_num - i) + i == script_num); 48 0 : } 49 0 : }, 50 0 : [&] { 51 0 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 52 0 : assert((script_num == random_script_num) != (script_num != random_script_num)); 53 0 : assert((script_num <= random_script_num) != (script_num > random_script_num)); 54 0 : assert((script_num >= random_script_num) != (script_num < random_script_num)); 55 : // Avoid signed integer overflow: 56 : // script/script.h:264:93: runtime error: signed integer overflow: -9223126527765971126 + -9223372036854756825 cannot be represented in type 'long' 57 0 : if (IsValidAddition(script_num, random_script_num)) { 58 0 : assert((script_num + random_script_num) - random_script_num == script_num); 59 0 : } 60 : // Avoid signed integer overflow: 61 : // script/script.h:265:93: runtime error: signed integer overflow: 6052837899185946624 - -9223372036854775808 cannot be represented in type 'long' 62 0 : if (IsValidSubtraction(script_num, random_script_num)) { 63 0 : assert((script_num - random_script_num) + random_script_num == script_num); 64 0 : } 65 0 : }, 66 0 : [&] { 67 0 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 68 0 : if (!IsValidAddition(script_num, random_script_num)) { 69 : // Avoid assertion failure: 70 : // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed. 71 0 : return; 72 : } 73 0 : script_num += random_script_num; 74 0 : }, 75 0 : [&] { 76 0 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 77 0 : if (!IsValidSubtraction(script_num, random_script_num)) { 78 : // Avoid assertion failure: 79 : // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed. 80 0 : return; 81 : } 82 0 : script_num -= random_script_num; 83 0 : }, 84 0 : [&] { 85 0 : script_num = script_num & fuzzed_data_provider.ConsumeIntegral<int64_t>(); 86 0 : }, 87 0 : [&] { 88 0 : script_num = script_num & ConsumeScriptNum(fuzzed_data_provider); 89 0 : }, 90 0 : [&] { 91 0 : script_num &= ConsumeScriptNum(fuzzed_data_provider); 92 0 : }, 93 0 : [&] { 94 0 : if (script_num == CScriptNum{std::numeric_limits<int64_t>::min()}) { 95 : // Avoid assertion failure: 96 : // ./script/script.h:279: CScriptNum CScriptNum::operator-() const: Assertion `m_value != std::numeric_limits<int64_t>::min()' failed. 97 0 : return; 98 : } 99 0 : script_num = -script_num; 100 0 : }, 101 0 : [&] { 102 0 : script_num = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 103 0 : }, 104 0 : [&] { 105 0 : const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 106 0 : if (!IsValidAddition(script_num, CScriptNum{random_integer})) { 107 : // Avoid assertion failure: 108 : // ./script/script.h:292: CScriptNum &CScriptNum::operator+=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)' failed. 109 0 : return; 110 : } 111 0 : script_num += random_integer; 112 0 : }, 113 0 : [&] { 114 0 : const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 115 0 : if (!IsValidSubtraction(script_num, CScriptNum{random_integer})) { 116 : // Avoid assertion failure: 117 : // ./script/script.h:300: CScriptNum &CScriptNum::operator-=(const int64_t &): Assertion `rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)' failed. 118 0 : return; 119 : } 120 0 : script_num -= random_integer; 121 0 : }, 122 0 : [&] { 123 0 : script_num &= fuzzed_data_provider.ConsumeIntegral<int64_t>(); 124 0 : }); 125 0 : (void)script_num.getint(); 126 0 : (void)script_num.getvch(); 127 0 : } 128 0 : }