diff --git a/lib/evmone/eof.cpp b/lib/evmone/eof.cpp index 95e6e68659..0b46a8051a 100644 --- a/lib/evmone/eof.cpp +++ b/lib/evmone/eof.cpp @@ -214,10 +214,8 @@ EOFValidationError validate_instructions(evmc_revision rev, bytes_view code) noe if (i + 1 >= code.size()) return EOFValidationError::truncated_instruction; - const auto count = code[i + 1]; - if (count < 1) - return EOFValidationError::invalid_rjumpv_count; - i += static_cast(1 /* count */ + count * 2 /* tbl */); + const auto count = code[i + 1] + 1; + i += static_cast(1 /* max_index */ + count * 2 /* tbl */); } else i += instr::traits[op].immediate_size; @@ -577,8 +575,6 @@ std::string_view get_error_message(EOFValidationError err) noexcept return "undefined_instruction"; case EOFValidationError::truncated_instruction: return "truncated_instruction"; - case EOFValidationError::invalid_rjumpv_count: - return "invalid_rjumpv_count"; case EOFValidationError::invalid_rjump_destination: return "invalid_rjump_destination"; case EOFValidationError::too_many_code_sections: diff --git a/lib/evmone/eof.hpp b/lib/evmone/eof.hpp index dea647c163..fe149dfa70 100644 --- a/lib/evmone/eof.hpp +++ b/lib/evmone/eof.hpp @@ -75,7 +75,6 @@ enum class EOFValidationError invalid_section_bodies_size, undefined_instruction, truncated_instruction, - invalid_rjumpv_count, invalid_rjump_destination, too_many_code_sections, invalid_type_section_size, diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 1d82e6d3a6..0a359df0a2 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -728,10 +728,10 @@ inline code_iterator rjumpv(StackTop stack, ExecutionState& /*state*/, code_iter constexpr auto REL_OFFSET_SIZE = sizeof(int16_t); const auto case_ = stack.pop(); - const auto count = pc[1]; - const auto pc_post = pc + 1 + 1 /* count */ + count * REL_OFFSET_SIZE /* tbl */; + const auto max_index = pc[1]; + const auto pc_post = pc + 1 + 1 /* max_index */ + (max_index + 1) * REL_OFFSET_SIZE /* tbl */; - if (case_ >= count) + if (case_ > max_index) { return pc_post; } diff --git a/test/unittests/eof_validation_test.cpp b/test/unittests/eof_validation_test.cpp index 39a5dcf41d..9f98f54869 100644 --- a/test/unittests/eof_validation_test.cpp +++ b/test/unittests/eof_validation_test.cpp @@ -480,13 +480,6 @@ TEST(eof_validation, EOF1_rjumpv_truncated) EOFValidationError::truncated_instruction); } -TEST(eof_validation, EOF1_rjumpv_0_count) -{ - auto code = eof1_bytecode(rjumpv({}, 0) + OP_STOP, 1); - - EXPECT_EQ(validate_eof(code), EOFValidationError::invalid_rjumpv_count); -} - TEST(eof_validation, EOF1_rjump_invalid_destination) { // Into header (offset = -5) @@ -662,7 +655,7 @@ TEST(eof_valication, max_arguments_count) } } -TEST(eof_valication, max_stack_heigh) +TEST(eof_valication, max_stack_height) { { auto code = "EF0001 010008 02000200010BFE 030000 00 00000000 000003FF B1" + @@ -719,7 +712,7 @@ TEST(eof_valication, max_stack_heigh) } { - auto code = eof1_bytecode(rjumpv({-4}, 0) + OP_RETF, 1); + auto code = eof1_bytecode(OP_PUSH0 + rjumpv({-4}, 0) + OP_RETF, 1); EXPECT_EQ(validate_eof(code), EOFValidationError::stack_height_mismatch); } diff --git a/test/utils/bytecode.hpp b/test/utils/bytecode.hpp index cab98883b5..0012cd4132 100644 --- a/test/utils/bytecode.hpp +++ b/test/utils/bytecode.hpp @@ -256,7 +256,8 @@ inline bytecode rjumpi(int16_t offset, bytecode condition) inline bytecode rjumpv(const std::initializer_list offsets, bytecode condition) { - bytecode ret = condition + OP_RJUMPV + static_cast(offsets.size()); + assert(offsets.size() > 0); + bytecode ret = condition + OP_RJUMPV + static_cast(offsets.size() - 1); for (const auto offset : offsets) ret += bytecode{big_endian(offset)}; return ret;