diff --git a/src/script/script.cpp b/src/script/script.cpp --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -274,22 +274,32 @@ } // Check for a negative bit - uint8_t msb = data[0] & 0x80; - bool start = false; + uint8_t neg = data[0] & 0x80; + bool pushedRes = false; for (size_t i = 0; i < data.size(); ++i) { uint8_t x = data[i]; if (i == 0 && (x & 0x7f) == 0) { continue; } - if (!start && x == 0) { + if (!pushedRes && x == 0) { continue; } - start = true; + pushedRes = true; res.push_back(x); } - if (res.size() != 0) { - res[0] |= msb; + if (res.size() == 0) { + res.push_back(0); + } + + // If MSB is already set and neg is not zero, add another byte to hold neg + if ((res[0] & 0x80) && neg != 0) { + res.insert(res.begin(), 0x00); + } + res[0] |= neg; + + if (res.size() == 1 && res[0] == 0x80) { + res[0] = 0; } return res; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -415,19 +415,39 @@ } // namespace BOOST_AUTO_TEST_CASE(minimize_big_endian_test) { - std::vector input( - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01}}); - std::vector negInput( - {{0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01}}); + // Empty array case + BOOST_CHECK(MinimalizeBigEndianArray(std::vector()) == std::vector()); + + // Zero arrays of various lengths + std::vector zeroArray({{0x00}}); + std::vector negZeroArray({{0x80}}); + for (int i = 0; i < 16; i++) { + if (i > 0) { + zeroArray.push_back(0x00); + negZeroArray.push_back(0x00); + } - std::vector check({0x01, 0x00, 0x00, 0x01}); - std::vector negCheck({0x81, 0x00, 0x00, 0x01}); + BOOST_CHECK(MinimalizeBigEndianArray(zeroArray) == + std::vector({{0x00}})); - std::vector out = MinimalizeBigEndianArray(input); - std::vector negOut = MinimalizeBigEndianArray(negInput); + // -0 should always evaluate to 0x00 + BOOST_CHECK(MinimalizeBigEndianArray(negZeroArray) == + std::vector({{0x00}})); + } - BOOST_CHECK(out == check); - BOOST_CHECK(negOut == negCheck); + // Shouldn't minimalize this array to a negative number + std::vector notNegArray({{0x00, 0x80}}); + for (int i = 0; i < 16; i++) { + notNegArray.push_back(i); + BOOST_CHECK(MinimalizeBigEndianArray(notNegArray) == notNegArray); + } + + // Shouldn't minimalize these arrays at all + std::vector noMinArray; + for (int i = 0; i < 0x80; i++) { + noMinArray.push_back(i); + BOOST_CHECK(MinimalizeBigEndianArray(noMinArray) == noMinArray); + } } BOOST_AUTO_TEST_CASE(script_build) {