From 9ab14e4d21c73d16d8d782f1576fe29e659e2a70 Mon Sep 17 00:00:00 2001 From: pierrenn Date: Tue, 24 Mar 2020 16:17:58 +0900 Subject: [PATCH] Limit decimal range of numbers ParseScript accepts --- Makefile.am | 2 ++ src/core_read.cpp | 8 +++++++ src/test/data/script_tests.json | 26 ++++++++++---------- src/test/data/tx_invalid.json | 2 +- src/test/data/tx_valid.json | 6 ++--- test/util/data/bitcoin-util-test.json | 34 +++++++++++++++++++++++++++ test/util/data/txcreatescript5.hex | 1 + test/util/data/txcreatescript6.hex | 1 + 8 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 test/util/data/txcreatescript5.hex create mode 100644 test/util/data/txcreatescript6.hex diff --git a/Makefile.am b/Makefile.am index bd41c5ae27196..01281338101f6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -301,6 +301,8 @@ EXTRA_DIST += \ test/util/data/txcreatescript3.json \ test/util/data/txcreatescript4.hex \ test/util/data/txcreatescript4.json \ + test/util/data/txcreatescript5.hex \ + test/util/data/txcreatescript6.hex \ test/util/data/txcreatesignv1.hex \ test/util/data/txcreatesignv1.json \ test/util/data/txcreatesignv2.hex \ diff --git a/src/core_read.cpp b/src/core_read.cpp index 9a65b02585c7e..d0369556411b6 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -59,6 +59,14 @@ CScript ParseScript(const std::string& s) { // Number int64_t n = atoi64(*w); + + //limit the range of numbers ParseScript accepts in decimal + //since numbers outside -0xFFFFFFFF...0xFFFFFFFF are illegal in scripts + if (n > int64_t{0xffffffff} || n < -1 * int64_t{0xffffffff}) { + throw std::runtime_error("script parse error: decimal numeric value only allowed in the " + "range -0xFFFFFFFF...0xFFFFFFFF"); + } + result << n; } else if (w->substr(0,2) == "0x" && w->size() > 2 && IsHex(std::string(w->begin()+2, w->end()))) diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 3241f32f5683d..c01ef307b7fe3 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -121,9 +121,9 @@ ["8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], ["2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], ["2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], -["549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], -["549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], -["9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], +["0x05ffffffff7f", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["0x06000000008000", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], +["0x08ffffffffffffff7f", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], ["-1", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], ["-127", "SIZE 1 EQUAL", "P2SH,STRICTENC", "OK"], ["-128", "SIZE 2 EQUAL", "P2SH,STRICTENC", "OK"], @@ -133,9 +133,9 @@ ["-8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], ["-2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC", "OK"], ["-2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], -["-549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], -["-549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], -["-9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], +["0x05ffffffffff", "SIZE 5 EQUAL", "P2SH,STRICTENC", "OK"], +["0x06000000008080", "SIZE 6 EQUAL", "P2SH,STRICTENC", "OK"], +["0x08ffffffffffffffff", "SIZE 8 EQUAL", "P2SH,STRICTENC", "OK"], ["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL", "P2SH,STRICTENC", "OK"], ["42", "SIZE 1 EQUALVERIFY 42 EQUAL", "P2SH,STRICTENC", "OK", "SIZE does not consume argument"], @@ -360,9 +360,9 @@ ["8388608", "0x04 0x00008000 EQUAL", "P2SH,STRICTENC", "OK"], ["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC", "OK"], -["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], -["549755813888", "0x06 0x000000008000 EQUAL", "P2SH,STRICTENC", "OK"], -["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["0x05ffffffff7f", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["0x06000000008000", "0x06 0x000000008000 EQUAL", "P2SH,STRICTENC", "OK"], +["0x08ffffffffffffff7f", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "OK", "Numbers are little-endian with the MSB being a sign bit"], ["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC", "OK"], ["-128", "0x02 0x8080 EQUAL", "P2SH,STRICTENC", "OK"], @@ -373,9 +373,9 @@ ["-2147483647", "0x04 0xFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], ["-2147483648", "0x05 0x0000008080 EQUAL", "P2SH,STRICTENC", "OK"], ["-4294967295", "0x05 0xFFFFFFFF80 EQUAL", "P2SH,STRICTENC", "OK"], -["-549755813887", "0x05 0xFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], -["-549755813888", "0x06 0x000000008080 EQUAL", "P2SH,STRICTENC", "OK"], -["-9223372036854775807", "0x08 0xFFFFFFFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["0x05ffffffffff", "0x05 0xFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], +["0x06000000008080", "0x06 0x000000008080 EQUAL", "P2SH,STRICTENC", "OK"], +["0x08ffffffffffffffff", "0x08 0xFFFFFFFFFFFFFFFF EQUAL", "P2SH,STRICTENC", "OK"], ["2147483647", "1ADD 2147483648 EQUAL", "P2SH,STRICTENC", "OK", "We can do math on 4-byte integers, and compare 5-byte ones"], ["2147483647", "1ADD 1", "P2SH,STRICTENC", "OK"], @@ -2521,7 +2521,7 @@ ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], -["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", +["0x050000000001", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], ["MINIMALIF tests"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index d22175d6603d0..3b1db449b26c1 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -174,7 +174,7 @@ "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument 2^32 with nLockTime=2^32-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x050000000001 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Same, but with nLockTime=2^31-1"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 4a1c77166d1dc..11634c90f0843 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -292,11 +292,11 @@ "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["Argument 3<<31 with various nSequence"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x050000008001 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x050000008001 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x050000008001 CHECKSEQUENCEVERIFY 1"]], "020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], ["5 byte non-minimally-encoded operandss are valid"], diff --git a/test/util/data/bitcoin-util-test.json b/test/util/data/bitcoin-util-test.json index 761923a8180ae..16dfa8d77f2d1 100644 --- a/test/util/data/bitcoin-util-test.json +++ b/test/util/data/bitcoin-util-test.json @@ -258,6 +258,40 @@ "output_cmp": "txcreatescript4.json", "description": "Create a new transaction with a single output script (OP_DROP) in a P2SH, wrapped in a P2SH (output as json)" }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:9999999999"], + "return_code": 1, + "error_txt": "error: script parse error: decimal numeric value only allowed in the range -0xFFFFFFFF...0xFFFFFFFF", + "description": "Try to parse an output script with a decimal number above the allowed range" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:4294967296"], + "return_code": 1, + "error_txt": "error: script parse error: decimal numeric value only allowed in the range -0xFFFFFFFF...0xFFFFFFFF", + "description": "Try to parse an output script with a decimal number just above the allowed range" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:4294967295"], + "output_cmp": "txcreatescript5.hex", + "description": "Try to parse an output script with a decimal number at the upper limit of the allowed range" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:-9999999999"], + "return_code": 1, + "error_txt": "error: script parse error: decimal numeric value only allowed in the range -0xFFFFFFFF...0xFFFFFFFF", + "description": "Try to parse an output script with a decimal number below the allowed range" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:-4294967296"], + "return_code": 1, + "error_txt": "error: script parse error: decimal numeric value only allowed in the range -0xFFFFFFFF...0xFFFFFFFF", + "description": "Try to parse an output script with a decimal number just below the allowed range" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:-4294967295"], + "output_cmp": "txcreatescript6.hex", + "description": "Try to parse an output script with a decimal number at the lower limit of the allowed range" + }, { "exec": "./bitcoin-tx", "args": ["-create", "nversion=1", diff --git a/test/util/data/txcreatescript5.hex b/test/util/data/txcreatescript5.hex new file mode 100644 index 0000000000000..48e0a12b0c6c6 --- /dev/null +++ b/test/util/data/txcreatescript5.hex @@ -0,0 +1 @@ +02000000000100000000000000000605ffffffff0000000000 diff --git a/test/util/data/txcreatescript6.hex b/test/util/data/txcreatescript6.hex new file mode 100644 index 0000000000000..b98293813d8c2 --- /dev/null +++ b/test/util/data/txcreatescript6.hex @@ -0,0 +1 @@ +02000000000100000000000000000605ffffffff8000000000