Branch data Line data Source code
# 1 : : // Copyright (c) 2012-2020 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/scriptnum10.h>
# 7 : : #include <test/util/setup_common.h>
# 8 : :
# 9 : : #include <boost/test/unit_test.hpp>
# 10 : : #include <limits.h>
# 11 : : #include <stdint.h>
# 12 : :
# 13 : : BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
# 14 : :
# 15 : : /** A selection of numbers that do not trigger int64_t overflow
# 16 : : * when added/subtracted. */
# 17 : : static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 };
# 18 : :
# 19 : : static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000};
# 20 : :
# 21 : : static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum)
# 22 : 27090 : {
# 23 [ + - ][ + - ]: 27090 : return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint();
# 24 : 27090 : }
# 25 : :
# 26 : : static void CheckCreateVch(const int64_t& num)
# 27 : 702 : {
# 28 : 702 : CScriptNum10 bignum(num);
# 29 : 702 : CScriptNum scriptnum(num);
# 30 : 702 : BOOST_CHECK(verify(bignum, scriptnum));
# 31 : :
# 32 : 702 : CScriptNum10 bignum2(bignum.getvch(), false);
# 33 : 702 : CScriptNum scriptnum2(scriptnum.getvch(), false);
# 34 : 702 : BOOST_CHECK(verify(bignum2, scriptnum2));
# 35 : :
# 36 : 702 : CScriptNum10 bignum3(scriptnum2.getvch(), false);
# 37 : 702 : CScriptNum scriptnum3(bignum2.getvch(), false);
# 38 : 702 : BOOST_CHECK(verify(bignum3, scriptnum3));
# 39 : 702 : }
# 40 : :
# 41 : : static void CheckCreateInt(const int64_t& num)
# 42 : 702 : {
# 43 : 702 : CScriptNum10 bignum(num);
# 44 : 702 : CScriptNum scriptnum(num);
# 45 : 702 : BOOST_CHECK(verify(bignum, scriptnum));
# 46 : 702 : BOOST_CHECK(verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint())));
# 47 : 702 : BOOST_CHECK(verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint())));
# 48 : 702 : BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()), CScriptNum(CScriptNum(bignum.getint()).getint())));
# 49 : 702 : }
# 50 : :
# 51 : :
# 52 : : static void CheckAdd(const int64_t& num1, const int64_t& num2)
# 53 : 2808 : {
# 54 : 2808 : const CScriptNum10 bignum1(num1);
# 55 : 2808 : const CScriptNum10 bignum2(num2);
# 56 : 2808 : const CScriptNum scriptnum1(num1);
# 57 : 2808 : const CScriptNum scriptnum2(num2);
# 58 : 2808 : CScriptNum10 bignum3(num1);
# 59 : 2808 : CScriptNum10 bignum4(num1);
# 60 : 2808 : CScriptNum scriptnum3(num1);
# 61 : 2808 : CScriptNum scriptnum4(num1);
# 62 : :
# 63 : : // int64_t overflow is undefined.
# 64 [ + + ][ - + ]: 2808 : bool invalid = (((num2 > 0) && (num1 > (std::numeric_limits<int64_t>::max() - num2))) ||
# 65 [ + + ][ - + ]: 2808 : ((num2 < 0) && (num1 < (std::numeric_limits<int64_t>::min() - num2))));
# 66 [ + - ]: 2808 : if (!invalid)
# 67 : 2808 : {
# 68 : 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2));
# 69 : 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2));
# 70 : 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1));
# 71 : 2808 : }
# 72 : 2808 : }
# 73 : :
# 74 : : static void CheckNegate(const int64_t& num)
# 75 : 2808 : {
# 76 : 2808 : const CScriptNum10 bignum(num);
# 77 : 2808 : const CScriptNum scriptnum(num);
# 78 : :
# 79 : : // -INT64_MIN is undefined
# 80 [ + - ]: 2808 : if (num != std::numeric_limits<int64_t>::min())
# 81 : 2808 : BOOST_CHECK(verify(-bignum, -scriptnum));
# 82 : 2808 : }
# 83 : :
# 84 : : static void CheckSubtract(const int64_t& num1, const int64_t& num2)
# 85 : 2808 : {
# 86 : 2808 : const CScriptNum10 bignum1(num1);
# 87 : 2808 : const CScriptNum10 bignum2(num2);
# 88 : 2808 : const CScriptNum scriptnum1(num1);
# 89 : 2808 : const CScriptNum scriptnum2(num2);
# 90 : :
# 91 : : // int64_t overflow is undefined.
# 92 [ + + ][ - + ]: 2808 : bool invalid = ((num2 > 0 && num1 < std::numeric_limits<int64_t>::min() + num2) ||
# 93 [ + + ][ - + ]: 2808 : (num2 < 0 && num1 > std::numeric_limits<int64_t>::max() + num2));
# 94 [ + - ]: 2808 : if (!invalid)
# 95 : 2808 : {
# 96 : 2808 : BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2));
# 97 : 2808 : BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2));
# 98 : 2808 : }
# 99 : :
# 100 [ + + ][ - + ]: 2808 : invalid = ((num1 > 0 && num2 < std::numeric_limits<int64_t>::min() + num1) ||
# 101 [ + + ][ - + ]: 2808 : (num1 < 0 && num2 > std::numeric_limits<int64_t>::max() + num1));
# 102 [ + - ]: 2808 : if (!invalid)
# 103 : 2808 : {
# 104 : 2808 : BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1));
# 105 : 2808 : BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1));
# 106 : 2808 : }
# 107 : 2808 : }
# 108 : :
# 109 : : static void CheckCompare(const int64_t& num1, const int64_t& num2)
# 110 : 2808 : {
# 111 : 2808 : const CScriptNum10 bignum1(num1);
# 112 : 2808 : const CScriptNum10 bignum2(num2);
# 113 : 2808 : const CScriptNum scriptnum1(num1);
# 114 : 2808 : const CScriptNum scriptnum2(num2);
# 115 : :
# 116 : 2808 : BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1));
# 117 : 2808 : BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1));
# 118 : 2808 : BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1));
# 119 : 2808 : BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1));
# 120 : 2808 : BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1));
# 121 : 2808 : BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1));
# 122 : :
# 123 : 2808 : BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1));
# 124 : 2808 : BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1));
# 125 : 2808 : BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1));
# 126 : 2808 : BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1));
# 127 : 2808 : BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1));
# 128 : 2808 : BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1));
# 129 : :
# 130 : 2808 : BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2));
# 131 : 2808 : BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2));
# 132 : 2808 : BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2));
# 133 : 2808 : BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2));
# 134 : 2808 : BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2));
# 135 : 2808 : BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2));
# 136 : :
# 137 : 2808 : BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2));
# 138 : 2808 : BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2));
# 139 : 2808 : BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2));
# 140 : 2808 : BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2));
# 141 : 2808 : BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2));
# 142 : 2808 : BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2));
# 143 : 2808 : }
# 144 : :
# 145 : : static void RunCreate(const int64_t& num)
# 146 : 702 : {
# 147 : 702 : CheckCreateInt(num);
# 148 : 702 : CScriptNum scriptnum(num);
# 149 [ + + ]: 702 : if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize)
# 150 : 558 : CheckCreateVch(num);
# 151 : 144 : else
# 152 : 144 : {
# 153 : 144 : BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum10_error);
# 154 : 144 : }
# 155 : 702 : }
# 156 : :
# 157 : : static void RunOperators(const int64_t& num1, const int64_t& num2)
# 158 : 2808 : {
# 159 : 2808 : CheckAdd(num1, num2);
# 160 : 2808 : CheckSubtract(num1, num2);
# 161 : 2808 : CheckNegate(num1);
# 162 : 2808 : CheckCompare(num1, num2);
# 163 : 2808 : }
# 164 : :
# 165 : : BOOST_AUTO_TEST_CASE(creation)
# 166 : 2 : {
# 167 [ + + ]: 28 : for(size_t i = 0; i < std::size(values); ++i)
# 168 : 26 : {
# 169 [ + + ]: 260 : for(size_t j = 0; j < std::size(offsets); ++j)
# 170 : 234 : {
# 171 : 234 : RunCreate(values[i]);
# 172 : 234 : RunCreate(values[i] + offsets[j]);
# 173 : 234 : RunCreate(values[i] - offsets[j]);
# 174 : 234 : }
# 175 : 26 : }
# 176 : 2 : }
# 177 : :
# 178 : : BOOST_AUTO_TEST_CASE(operators)
# 179 : 2 : {
# 180 [ + + ]: 28 : for(size_t i = 0; i < std::size(values); ++i)
# 181 : 26 : {
# 182 [ + + ]: 260 : for(size_t j = 0; j < std::size(offsets); ++j)
# 183 : 234 : {
# 184 : 234 : RunOperators(values[i], values[i]);
# 185 : 234 : RunOperators(values[i], -values[i]);
# 186 : 234 : RunOperators(values[i], values[j]);
# 187 : 234 : RunOperators(values[i], -values[j]);
# 188 : 234 : RunOperators(values[i] + values[j], values[j]);
# 189 : 234 : RunOperators(values[i] + values[j], -values[j]);
# 190 : 234 : RunOperators(values[i] - values[j], values[j]);
# 191 : 234 : RunOperators(values[i] - values[j], -values[j]);
# 192 : 234 : RunOperators(values[i] + values[j], values[i] + values[j]);
# 193 : 234 : RunOperators(values[i] + values[j], values[i] - values[j]);
# 194 : 234 : RunOperators(values[i] - values[j], values[i] + values[j]);
# 195 : 234 : RunOperators(values[i] - values[j], values[i] - values[j]);
# 196 : 234 : }
# 197 : 26 : }
# 198 : 2 : }
# 199 : :
# 200 : : BOOST_AUTO_TEST_SUITE_END()
|