Changeset View
Changeset View
Standalone View
Standalone View
src/script/interpreter.cpp
Show First 20 Lines • Show All 329 Lines • ▼ Show 20 Lines | try { | ||||
return set_error(serror, SCRIPT_ERR_PUSH_SIZE); | return set_error(serror, SCRIPT_ERR_PUSH_SIZE); | ||||
} | } | ||||
// Note how OP_RESERVED does not count towards the opcode limit. | // Note how OP_RESERVED does not count towards the opcode limit. | ||||
if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) { | if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) { | ||||
return set_error(serror, SCRIPT_ERR_OP_COUNT); | return set_error(serror, SCRIPT_ERR_OP_COUNT); | ||||
} | } | ||||
if (opcode == OP_SUBSTR || opcode == OP_LEFT || opcode == OP_RIGHT || | if (opcode == OP_LEFT || opcode == OP_RIGHT || opcode == OP_INVERT || | ||||
opcode == OP_INVERT || opcode == OP_2MUL || opcode == OP_2DIV || | opcode == OP_2MUL || opcode == OP_2DIV || opcode == OP_MUL || | ||||
opcode == OP_MUL || opcode == OP_LSHIFT || opcode == OP_RSHIFT) { | opcode == OP_LSHIFT || opcode == OP_RSHIFT) { | ||||
// Disabled opcodes. | // Disabled opcodes. | ||||
return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); | return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); | ||||
} | } | ||||
if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { | if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { | ||||
if (fRequireMinimal && | if (fRequireMinimal && | ||||
!CheckMinimalPush(vchPushValue, opcode)) { | !CheckMinimalPush(vchPushValue, opcode)) { | ||||
return set_error(serror, SCRIPT_ERR_MINIMALDATA); | return set_error(serror, SCRIPT_ERR_MINIMALDATA); | ||||
▲ Show 20 Lines • Show All 897 Lines • ▼ Show 20 Lines | try { | ||||
valtype& vch2 = stacktop(-1); | valtype& vch2 = stacktop(-1); | ||||
if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE) { | if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE) { | ||||
return set_error(serror, SCRIPT_ERR_PUSH_SIZE); | return set_error(serror, SCRIPT_ERR_PUSH_SIZE); | ||||
} | } | ||||
vch1.insert(vch1.end(), vch2.begin(), vch2.end()); | vch1.insert(vch1.end(), vch2.begin(), vch2.end()); | ||||
stack.pop_back(); | stack.pop_back(); | ||||
} break; | } break; | ||||
case OP_SPLIT: { | |||||
// (in position -- x1 x2) | |||||
if (stack.size() < 2) { | |||||
return set_error( | |||||
serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | |||||
} | |||||
valtype vch = stacktop(-2); | |||||
int64_t nPosition = CScriptNum(stacktop(-1), fRequireMinimal).getint(); | |||||
// if nPosition is less than 0 or is larger than the input then throw error | |||||
if (nPosition < 0 || static_cast<size_t>(nPosition) > vch.size()) { | |||||
return set_error( | |||||
serror, SCRIPT_ERR_INVALID_SPLIT_RANGE); | |||||
} | |||||
stack.pop_back(); | |||||
stack.pop_back(); | |||||
// initialize outputs | |||||
if (nPosition == 0) { | |||||
stack.push_back(valtype()); | |||||
stack.push_back(vch); | |||||
} | |||||
else if (static_cast<size_t>(nPosition) == vch.size()) { | |||||
stack.push_back(vch); | |||||
stack.push_back(valtype()); | |||||
} | |||||
else { | |||||
valtype vchOut1, vchOut2; | |||||
vchOut1.insert(vchOut1.end(), vch.begin(), vch.begin() + nPosition); | |||||
vchOut2.insert(vchOut2.end(), vch.begin() + nPosition, vch.end()); | |||||
stack.emplace_back(move(vchOut1)); | |||||
stack.emplace_back(move(vchOut2)); | |||||
} | |||||
} break; | |||||
default: | default: | ||||
return set_error(serror, SCRIPT_ERR_BAD_OPCODE); | return set_error(serror, SCRIPT_ERR_BAD_OPCODE); | ||||
} | } | ||||
// Size limits | // Size limits | ||||
if (stack.size() + altstack.size() > 1000) { | if (stack.size() + altstack.size() > 1000) { | ||||
return set_error(serror, SCRIPT_ERR_STACK_SIZE); | return set_error(serror, SCRIPT_ERR_STACK_SIZE); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 437 Lines • Show Last 20 Lines |