Skip to content

Instantly share code, notes, and snippets.

@jl2012
Last active November 23, 2018 22:55
Show Gist options
  • Save jl2012/976d8af9adb10f7247b5cc898752d872 to your computer and use it in GitHub Desktop.
Save jl2012/976d8af9adb10f7247b5cc898752d872 to your computer and use it in GitHub Desktop.
int FindAndMaskPush(CScript& script)
{
int masked = 0;
bool skip_next = false;
CScript result;
CScript::const_iterator pc = script.begin(), pc2 = script.begin();
opcodetype opcode;
while (script.GetOp(pc, opcode)) {
if (skip_next) {
if (opcode > OP_16 || opcode == OP_RESERVED)
return -1;
result.insert(result.end(), (unsigned char)OP_VERIF);
++masked;
skip_next = false;
pc2 = pc;
}
if (opcode == OP_MASK) {
result.insert(result.end(), pc2, pc);
skip_next = true;
pc2 = pc;
}
}
if (skip_next)
return -1;
if (masked > 0) {
result.insert(result.end(), pc2, static_cast<CScript::const_iterator>(script.end()));
script = std::move(result);
}
return masked;
}
BOOST_AUTO_TEST_CASE(script_op_mask)
{
// Exercise the FindAndMaskPush functionality
CScript s;
CScript e;
s = CScript() << OP_1 << OP_2 << OP_3;
e = s;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 0);
BOOST_CHECK(s == e);
s = ScriptFromHex("5101bd02febd");
e = s;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 0);
BOOST_CHECK(s == e);
s = ScriptFromHex("5101bd02bd"); // invalid: incomplete push
e = s;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 0);
BOOST_CHECK(s == e);
e = CScript() << OP_1 << OP_MASK << OP_VERIF;
s = CScript() << OP_1 << OP_MASK << OP_2;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd02feed");
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd01bd");
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed");
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed01bd02bdbd");
e = ScriptFromHex("51bd6501bd02bdbd");
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed02bd"); // invalid: incomplete push
e = ScriptFromHex("51bd6502bd");
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 1);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_IF << OP_MASK << OP_8 << OP_ELSE << OP_MASK << OP_9 << OP_ENDIF;
e = CScript() << OP_1 << OP_IF << OP_MASK << OP_VERIF << OP_ELSE << OP_MASK << OP_VERIF << OP_ENDIF;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), 2);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_MASK << OP_MASK << OP_3;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK << OP_MASK;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK << OP_DUP;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
s = CScript() << OP_1 << OP_2 << OP_MASK << OP_RESERVED << OP_3;
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
s = ScriptFromHex("51bd02fe"); // invalid: incomplete push
BOOST_CHECK_EQUAL(FindAndMaskPush(s), -1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment