Changeset View
Changeset View
Standalone View
Standalone View
src/test/op_reversebytes_tests.cpp
Show All 36 Lines | static void CheckPassWithFlags(const uint32_t flags, | ||||
stacktype stack{original_stack}; | stacktype stack{original_stack}; | ||||
bool r = EvalScript(stack, script, flags, sigchecker, &err); | bool r = EvalScript(stack, script, flags, sigchecker, &err); | ||||
BOOST_CHECK(r); | BOOST_CHECK(r); | ||||
BOOST_CHECK(err == ScriptError::OK); | BOOST_CHECK(err == ScriptError::OK); | ||||
BOOST_CHECK(stack == expected); | BOOST_CHECK(stack == expected); | ||||
} | } | ||||
/** | /** | ||||
* Verifies that the given error occurs with OP_REVERSEBYTES enabled | |||||
* and that BAD_OPCODE occurs if disabled. | |||||
*/ | |||||
static void CheckErrorIfEnabled(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const ScriptError expected) { | |||||
CheckErrorWithFlags(flags | SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack, | |||||
script, expected); | |||||
CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack, | |||||
script, ScriptError::BAD_OPCODE); | |||||
} | |||||
/** | |||||
* Verifies that the given stack results with OP_REVERSEBYTES enabled | |||||
* and that BAD_OPCODE occurs if disabled. | |||||
*/ | |||||
static void CheckPassIfEnabled(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const stacktype &expected) { | |||||
CheckPassWithFlags(flags | SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack, | |||||
script, expected); | |||||
CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_REVERSEBYTES, original_stack, | |||||
script, ScriptError::BAD_OPCODE); | |||||
} | |||||
/** | |||||
* Verifies the different combinations of a given test case. | * Verifies the different combinations of a given test case. | ||||
* Checks if | * Checks if | ||||
* - <item> OP_REVERSEBYTES results in <reversed_item>, | * - <item> OP_REVERSEBYTES results in <reversed_item>, | ||||
* - <reversed_item> OP_REVERSEBYTES results in <item>, | * - <reversed_item> OP_REVERSEBYTES results in <item>, | ||||
* - <item> {OP_REVERSEBYTES} x 2 results in <item> and | * - <item> {OP_REVERSEBYTES} x 2 results in <item> and | ||||
* - <reversed_item> {OP_REVERSEBYTES} x 2 results in <reversed_item>. | * - <reversed_item> {OP_REVERSEBYTES} x 2 results in <reversed_item>. | ||||
*/ | */ | ||||
static void CheckPassForCombinations(const uint32_t flags, const valtype &item, | static void CheckPassForCombinations(const uint32_t flags, const valtype &item, | ||||
const valtype &reversed_item) { | const valtype &reversed_item) { | ||||
CheckPassIfEnabled(flags, {item}, CScript() << OP_REVERSEBYTES, | CheckPassWithFlags(flags, {item}, CScript() << OP_REVERSEBYTES, | ||||
{reversed_item}); | {reversed_item}); | ||||
CheckPassIfEnabled(flags, {reversed_item}, CScript() << OP_REVERSEBYTES, | CheckPassWithFlags(flags, {reversed_item}, CScript() << OP_REVERSEBYTES, | ||||
{item}); | {item}); | ||||
CheckPassIfEnabled(flags, {item}, | CheckPassWithFlags(flags, {item}, | ||||
CScript() << OP_REVERSEBYTES << OP_REVERSEBYTES, {item}); | CScript() << OP_REVERSEBYTES << OP_REVERSEBYTES, {item}); | ||||
CheckPassIfEnabled(flags, {reversed_item}, | CheckPassWithFlags(flags, {reversed_item}, | ||||
CScript() << OP_REVERSEBYTES << OP_REVERSEBYTES, | CScript() << OP_REVERSEBYTES << OP_REVERSEBYTES, | ||||
{reversed_item}); | {reversed_item}); | ||||
} | } | ||||
// Test a few simple manual cases with random flags (proxy for exhaustive | // Test a few simple manual cases with random flags (proxy for exhaustive | ||||
// testing). | // testing). | ||||
BOOST_AUTO_TEST_CASE(op_reversebytes_manual_random_flags) { | BOOST_AUTO_TEST_CASE(op_reversebytes_manual_random_flags) { | ||||
MMIXLinearCongruentialGenerator lcg; | MMIXLinearCongruentialGenerator lcg; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | for (uint32_t datasize = 0; datasize < MAX_SCRIPT_ELEMENT_SIZE; | ||||
palindrome.emplace_back( | palindrome.emplace_back( | ||||
(item < (datasize + 1) / 2 ? item : datasize - item - 1) % 256); | (item < (datasize + 1) / 2 ? item : datasize - item - 1) % 256); | ||||
} | } | ||||
for (const uint32_t flags : flaglist) { | for (const uint32_t flags : flaglist) { | ||||
// Verify random data passes. | // Verify random data passes. | ||||
CheckPassForCombinations(flags, random_data, random_data_reversed); | CheckPassForCombinations(flags, random_data, random_data_reversed); | ||||
// Verify palindrome check passes. | // Verify palindrome check passes. | ||||
CheckPassIfEnabled(flags, {palindrome}, | CheckPassWithFlags(flags, {palindrome}, | ||||
CScript() << OP_REVERSEBYTES, {palindrome}); | CScript() << OP_REVERSEBYTES, {palindrome}); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(op_reversebytes_failures) { | BOOST_AUTO_TEST_CASE(op_reversebytes_failures) { | ||||
MMIXLinearCongruentialGenerator lcg; | MMIXLinearCongruentialGenerator lcg; | ||||
// Test for random flags (proxy for exhaustive testing). | // Test for random flags (proxy for exhaustive testing). | ||||
for (size_t i = 0; i < 4096; i++) { | for (size_t i = 0; i < 4096; i++) { | ||||
uint32_t flags = lcg.next(); | uint32_t flags = lcg.next(); | ||||
// Verify non-palindrome fails. | // Verify non-palindrome fails. | ||||
CheckErrorIfEnabled(flags, {{0x01, 0x02, 0x03, 0x02, 0x02}}, | CheckErrorWithFlags(flags, {{0x01, 0x02, 0x03, 0x02, 0x02}}, | ||||
CScript() | CScript() | ||||
<< OP_DUP << OP_REVERSEBYTES << OP_EQUALVERIFY, | << OP_DUP << OP_REVERSEBYTES << OP_EQUALVERIFY, | ||||
ScriptError::EQUALVERIFY); | ScriptError::EQUALVERIFY); | ||||
// Test empty stack results in INVALID_STACK_OPERATION. | // Test empty stack results in INVALID_STACK_OPERATION. | ||||
CheckErrorIfEnabled(flags, {}, CScript() << OP_REVERSEBYTES, | CheckErrorWithFlags(flags, {}, CScript() << OP_REVERSEBYTES, | ||||
ScriptError::INVALID_STACK_OPERATION); | ScriptError::INVALID_STACK_OPERATION); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |