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 : 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 : }