diff --git a/src/core_read.cpp b/src/core_read.cpp --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -27,8 +27,8 @@ if (mapOpNames.empty()) { for (int op = 0; op < FIRST_UNDEFINED_OP_VALUE; op++) { - // ignore all "PUSHDATA" ops, but dont ignore OP_RESERVED - if (op < OP_NOP && op != OP_RESERVED) { + // ignore all "PUSHDATA" ops before PUSHDATA1 + if (op < OP_PUSHDATA1) { continue; } @@ -50,6 +50,8 @@ boost::algorithm::token_compress_on); size_t push_size = 0, next_push_size = 0; + // Deal with PUSHDATA1-4 operation with some more hacks. + bool havePushData = false; for (const auto &w : words) { if (w.empty()) { @@ -94,6 +96,11 @@ next_push_size = raw[0]; } + if (havePushData) { + next_push_size = CScriptNum(raw, false).getint(); + havePushData = false; + } + result.insert(result.end(), raw.begin(), raw.end()); continue; } @@ -115,12 +122,15 @@ switch (op) { case OP_PUSHDATA1: next_push_size = 1; + havePushData = true; break; case OP_PUSHDATA2: next_push_size = 2; + havePushData = true; break; case OP_PUSHDATA4: next_push_size = 4; + havePushData = true; break; default: break; diff --git a/src/test/core_io_tests.cpp b/src/test/core_io_tests.cpp --- a/src/test/core_io_tests.cpp +++ b/src/test/core_io_tests.cpp @@ -31,6 +31,17 @@ BOOST_CHECK_NO_THROW(ParseScript("0x02 0x0101")); BOOST_CHECK_THROW(ParseScript("0x02 0x01"), std::runtime_error); BOOST_CHECK_THROW(ParseScript("0x02 0x010101"), std::runtime_error); + + // Note sizes are LE encoded. + BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA4 0x02000000 0x0101")); + BOOST_CHECK_THROW(ParseScript("PUSHDATA4 0x03000000 0x0101"), + std::runtime_error); + BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA2 0x0200 0x0101")); + BOOST_CHECK_THROW(ParseScript("PUSHDATA2 0x0300 0x0101"), + std::runtime_error); + BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA1 0x02 0x0101")); + BOOST_CHECK_THROW(ParseScript("PUSHDATA1 0x02 0x010101"), + std::runtime_error); } BOOST_AUTO_TEST_SUITE_END()