Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.17] Add new Elements opcodes #495

Merged
merged 10 commits into from
Jan 15, 2019
25 changes: 25 additions & 0 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
break;

case OP_SUBSTR:
case OP_SUBSTR_LAZY:
{
if (stack.size() < 3)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
Expand All @@ -823,6 +824,30 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
CScriptNum start(stacktop(-2), fRequireMinimal);
CScriptNum length(stacktop(-1), fRequireMinimal);

if (opcode == OP_SUBSTR_LAZY) {
if (start < 0)
start = 0;

if (length < 0)
length = 0;

if (start >= vch1.size()) {
popstack(stack);
popstack(stack);
popstack(stack);
stack.push_back(vchZero);
break;
}

if (length > MAX_SCRIPT_ELEMENT_SIZE)
length = MAX_SCRIPT_ELEMENT_SIZE;

// start + length cannot overflow because of the restrictions immediately abo
stevenroose marked this conversation as resolved.
Show resolved Hide resolved
if (start + length > vch1.size()) {
length = CScriptNum(vch1.size()) - start;
}
}

if (length < 0 || start < 0)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);

Expand Down
1 change: 1 addition & 0 deletions src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const char* GetOpName(opcodetype opcode)
// splice ops
case OP_CAT : return "OP_CAT";
case OP_SUBSTR : return "OP_SUBSTR";
case OP_SUBSTR_LAZY : return "OP_SUBSTR_LAZY";
case OP_LEFT : return "OP_LEFT";
case OP_RIGHT : return "OP_RIGHT";
case OP_SIZE : return "OP_SIZE";
Expand Down
3 changes: 2 additions & 1 deletion src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ enum opcodetype
// splice ops
OP_CAT = 0x7e,
OP_SUBSTR = 0x7f,
OP_SUBSTR_LAZY = 0xc3,
OP_LEFT = 0x80,
OP_RIGHT = 0x81,
OP_SIZE = 0x82,
Expand Down Expand Up @@ -195,7 +196,7 @@ enum opcodetype
};

// Maximum value that an opcode can be
static const unsigned int MAX_OPCODE = OP_CHECKSIGFROMSTACKVERIFY;
static const unsigned int MAX_OPCODE = OP_SUBSTR_LAZY; // 0xc3

const char* GetOpName(opcodetype opcode);

Expand Down
1 change: 0 additions & 1 deletion src/test/data/script_tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,6 @@
["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
Expand Down
2 changes: 1 addition & 1 deletion src/test/script_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1474,7 +1474,7 @@ BOOST_AUTO_TEST_CASE(script_HasValidOps)
BOOST_CHECK(script.HasValidOps());
script = ScriptFromHex("ff88ac"); // Script with OP_INVALIDOPCODE explicit
BOOST_CHECK(!script.HasValidOps());
script = ScriptFromHex("88acc3"); // Script with undefined opcode: one higher then MAX_OPCODE
script = ScriptFromHex("88acc4"); // Script with undefined opcode: one higher then MAX_OPCODE
BOOST_CHECK(!script.HasValidOps());
}

Expand Down