Branch data 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 : 439519 : bool IsValidAddition(const CScriptNum& lhs, const CScriptNum& rhs) 17 : : { 18 [ + + + + : 439519 : 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 : 448775 : bool IsValidSubtraction(const CScriptNum& lhs, const CScriptNum& rhs) 22 : : { 23 [ + + + + : 448775 : 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 [ + - ]: 173 : } // namespace 26 : : 27 [ - + ]: 479 : FUZZ_TARGET(scriptnum_ops) 28 : : { 29 : 133 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 30 : 133 : CScriptNum script_num = ConsumeScriptNum(fuzzed_data_provider); 31 [ + + + + ]: 789825 : LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 1000000) { 32 : 789692 : CallOneOf( 33 : : fuzzed_data_provider, 34 : 1106381 : [&] { 35 : 316689 : const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 36 [ + - ]: 316689 : assert((script_num == i) != (script_num != i)); 37 [ + - ]: 316689 : assert((script_num <= i) != (script_num > i)); 38 [ + - ]: 316689 : 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 [ + + ]: 316689 : if (IsValidAddition(script_num, CScriptNum{i})) { 42 [ + - ]: 164547 : assert((script_num + i) - i == script_num); 43 : 164547 : } 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 [ + + ]: 316689 : if (IsValidSubtraction(script_num, CScriptNum{i})) { 47 [ - + ]: 177669 : assert((script_num - i) + i == script_num); 48 : 177669 : } 49 : 316689 : }, 50 : 833627 : [&] { 51 : 43935 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 52 [ + - ]: 43935 : assert((script_num == random_script_num) != (script_num != random_script_num)); 53 [ + - ]: 43935 : assert((script_num <= random_script_num) != (script_num > random_script_num)); 54 [ + - ]: 43935 : 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 [ + + ]: 43935 : if (IsValidAddition(script_num, random_script_num)) { 58 [ + - ]: 31182 : assert((script_num + random_script_num) - random_script_num == script_num); 59 : 31182 : } 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 [ + + ]: 43935 : if (IsValidSubtraction(script_num, random_script_num)) { 63 [ - + ]: 33270 : assert((script_num - random_script_num) + random_script_num == script_num); 64 : 33270 : } 65 : 43935 : }, 66 : 829262 : [&] { 67 : 39570 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 68 [ + + ]: 39570 : 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 : 10054 : return; 72 : : } 73 : 29516 : script_num += random_script_num; 74 : 39570 : }, 75 : 839816 : [&] { 76 : 50124 : const CScriptNum random_script_num = ConsumeScriptNum(fuzzed_data_provider); 77 [ + + ]: 50124 : 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 : 17826 : return; 81 : : } 82 : 32298 : script_num -= random_script_num; 83 : 50124 : }, 84 : 820882 : [&] { 85 : 31190 : script_num = script_num & fuzzed_data_provider.ConsumeIntegral<int64_t>(); 86 : 31190 : }, 87 : 826052 : [&] { 88 : 36360 : script_num = script_num & ConsumeScriptNum(fuzzed_data_provider); 89 : 36360 : }, 90 : 820275 : [&] { 91 : 30583 : script_num &= ConsumeScriptNum(fuzzed_data_provider); 92 : 30583 : }, 93 : 870077 : [&] { 94 [ + + ]: 80385 : 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 : 2241 : return; 98 : : } 99 : 78144 : script_num = -script_num; 100 : 80385 : }, 101 : 834165 : [&] { 102 : 44473 : script_num = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 103 : 44473 : }, 104 : 829017 : [&] { 105 : 39325 : const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 106 [ + + ]: 39325 : 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 : 11926 : return; 110 : : } 111 : 27399 : script_num += random_integer; 112 : 39325 : }, 113 : 827719 : [&] { 114 : 38027 : const int64_t random_integer = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 115 [ + + ]: 38027 : 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 : 10885 : return; 119 : : } 120 : 27142 : script_num -= random_integer; 121 : 38027 : }, 122 : 828723 : [&] { 123 : 39031 : script_num &= fuzzed_data_provider.ConsumeIntegral<int64_t>(); 124 : 39031 : }); 125 : 789692 : (void)script_num.getint(); 126 : 789692 : (void)script_num.getvch(); 127 : 789692 : } 128 : 133 : }