diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1123,9 +1123,9 @@ const valtype &data = stacktop(-2); // Make sure the split point is appropriate. - uint64_t position = + int position = CScriptNum(stacktop(-1), fRequireMinimal).getint(); - if (position > data.size()) { + if (position < 0 || position > (int)data.size()) { return set_error(serror, SCRIPT_ERR_INVALID_SPLIT_RANGE); } @@ -1150,8 +1150,12 @@ serror, SCRIPT_ERR_INVALID_STACK_OPERATION); } - uint64_t size = - CScriptNum(stacktop(-1), fRequireMinimal).getint(); + CScriptNum bnSize(stacktop(-1), fRequireMinimal); + if (bnSize < 0) { + return set_error(serror, + SCRIPT_ERR_NEGATIVE_NUMBER); + } + unsigned int size = bnSize.getint(); if (size > MAX_SCRIPT_ELEMENT_SIZE) { return set_error(serror, SCRIPT_ERR_PUSH_SIZE); } diff --git a/src/script/script_error.h b/src/script/script_error.h --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -25,6 +25,7 @@ SCRIPT_ERR_INVALID_NUMBER_RANGE, SCRIPT_ERR_IMPOSSIBLE_ENCODING, SCRIPT_ERR_INVALID_SPLIT_RANGE, + SCRIPT_ERR_NEGATIVE_NUMBER, /* Failed verify operations */ SCRIPT_ERR_VERIFY, diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -45,6 +45,8 @@ return "The requested encoding is impossible to satisfy"; case SCRIPT_ERR_INVALID_SPLIT_RANGE: return "Invalid OP_SPLIT range"; + case SCRIPT_ERR_NEGATIVE_NUMBER: + return "Given operand is a negative number"; case SCRIPT_ERR_BAD_OPCODE: return "Opcode missing or not understood"; case SCRIPT_ERR_DISABLED_OPCODE: diff --git a/src/test/monolith_opcodes_tests.cpp b/src/test/monolith_opcodes_tests.cpp --- a/src/test/monolith_opcodes_tests.cpp +++ b/src/test/monolith_opcodes_tests.cpp @@ -631,9 +631,8 @@ CheckNum2BinError({{}, {0x09, 0x02}}, SCRIPT_ERR_PUSH_SIZE); - // NUM2BIN can't take negative sizes, for which it throws an error - // "Push value size limit exceeded" - CheckNum2BinError({{}, {0x81}}, SCRIPT_ERR_PUSH_SIZE); + // NUM2BIN can't take negative sizes, giving an appropriate error. + CheckNum2BinError({{}, {0x81}}, SCRIPT_ERR_NEGATIVE_NUMBER); // ... except for negative zero of course (without minimaldata flag) CheckTestResult(0, {{0x00, 0x80}, {0x80}}, CScript() << OP_NUM2BIN, {{}}); CheckTestResult(0, {{0x00, 0x80}, {0x00, 0x80}}, CScript() << OP_NUM2BIN,