Skip to content

Commit

Permalink
Change RJUMPV immediate argument to mean max_index
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed May 9, 2023
1 parent 409f71d commit e5ad909
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 42 deletions.
18 changes: 7 additions & 11 deletions lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<size_t>(1 /* count */ + count * 2 /* tbl */);
const auto count = code[i + 1] + 1;
i += static_cast<size_t>(1 /* max_index */ + count * 2 /* tbl */);
}
else
i += instr::traits[op].immediate_size;
Expand Down Expand Up @@ -264,8 +262,8 @@ bool validate_rjump_destinations(bytes_view code) noexcept
}
else if (op == OP_RJUMPV)
{
const auto count = code[i + 1];
imm_size += size_t{1} /* count */ + count * REL_OFFSET_SIZE /* tbl */;
const auto count = static_cast<size_t>(code[i + 1] + 1);
imm_size += size_t{1} /* max_index */ + count * REL_OFFSET_SIZE /* tbl */;
const size_t post_pos = i + 1 + imm_size;

for (size_t k = 0; k < count * REL_OFFSET_SIZE; k += REL_OFFSET_SIZE)
Expand Down Expand Up @@ -337,7 +335,7 @@ std::variant<EOFValidationError, int32_t> validate_max_stack_height(

// Determine size of immediate, including the special case of RJUMPV.
const size_t imm_size = (opcode == OP_RJUMPV) ?
(1 + /*count*/ size_t{code[i + 1]} * REL_OFFSET_SIZE) :
(1 + /*count*/ (size_t{code[i + 1]} + 1) * REL_OFFSET_SIZE) :
instr::traits[opcode].immediate_size;

// Mark immediate locations.
Expand Down Expand Up @@ -378,10 +376,10 @@ std::variant<EOFValidationError, int32_t> validate_max_stack_height(
}
else if (opcode == OP_RJUMPV)
{
const auto count = code[i + 1];
const auto max_index = code[i + 1];

// Insert all jump targets.
for (size_t k = 0; k < count; ++k)
for (size_t k = 0; k <= max_index; ++k)
{
const auto target_rel_offset = read_int16_be(&code[i + k * REL_OFFSET_SIZE + 2]);
const auto target = static_cast<int32_t>(next) + target_rel_offset;
Expand Down Expand Up @@ -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:
Expand Down
1 change: 0 additions & 1 deletion lib/evmone/eof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions lib/evmone/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
45 changes: 19 additions & 26 deletions test/unittests/eof_validation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,22 @@ TEST(eof_validation, EOF1_valid_rjumpi)
TEST(eof_validation, EOF1_valid_rjumpv)
{
// table = [0] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 030000 00 00000001 60005E010000600100"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 030000 00 00000001 60005E000000600100"),
EOFValidationError::success);

// table = [0,3] case = 0
EXPECT_EQ(
validate_eof("EF0001 010004 020001000E 030000 00 00000001 60005E0200000003600100600200"),
validate_eof("EF0001 010004 020001000E 030000 00 00000001 60005E0100000003600100600200"),
EOFValidationError::success);

// table = [0,3] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000E 030000 00 00000001 60025E0200000003600100600200"),
validate_eof("EF0001 010004 020001000E 030000 00 00000001 60025E0100000003600100600200"),
EOFValidationError::success);

// table = [0,3,-10] case = 2
EXPECT_EQ(validate_eof(
"EF0001 010004 0200010010 030000 00 00000001 60025E0300000003FFF6600100600200"),
"EF0001 010004 0200010010 030000 00 00000001 60025E0200000003FFF6600100600200"),
EOFValidationError::success);
}

Expand All @@ -464,29 +464,22 @@ TEST(eof_validation, EOF1_rjumpi_truncated)
TEST(eof_validation, EOF1_rjumpv_truncated)
{
// table = [0] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030000 00 00000000 60005E0100"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030000 00 00000000 60005E0000"),
EOFValidationError::truncated_instruction);

// table = [0,3] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010007 030000 00 00000000 60005E02000000"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010007 030000 00 00000000 60005E01000000"),
EOFValidationError::truncated_instruction);

// table = [0,3] case = 2
EXPECT_EQ(validate_eof("EF0001 010004 0200010006 030000 00 00000000 60025E020000"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010006 030000 00 00000000 60025E010000"),
EOFValidationError::truncated_instruction);

// table = [0,3,-10] case = 2
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 030000 00 00000000 60025E0300000003FF"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 030000 00 00000000 60025E0200000003FF"),
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)
Expand Down Expand Up @@ -544,49 +537,49 @@ TEST(eof_validation, EOF1_rjumpi_invalid_destination)
TEST(eof_validation, EOF1_rjumpv_invalid_destination)
{
// table = [-23] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E01FFE96001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E00FFE96001"),
EOFValidationError::invalid_rjump_destination);

// table = [-8] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E01FFF86001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E00FFF86001"),
EOFValidationError::invalid_rjump_destination);

// table = [-1] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E01FFFF6001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E00FFFF6001"),
EOFValidationError::invalid_rjump_destination);

// table = [2] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E0100026001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E0000026001"),
EOFValidationError::invalid_rjump_destination);

// table = [3] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E0100036001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 030000 00 00000000 60005E0000036001"),
EOFValidationError::invalid_rjump_destination);


// table = [0,3,-27] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0300000003FFE56001006002"),
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0200000003FFE56001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,-12] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0300000003FFF46001006002"),
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0200000003FFF46001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,-1] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0300000003FFFF6001006002"),
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E0200000003FFFF6001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,5] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E030000000300056001006002"),
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E020000000300056001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,6] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E030000000300066001006002"),
validate_eof("EF0001 010004 020001000F 030000 00 00000000 60025E020000000300066001006002"),
EOFValidationError::invalid_rjump_destination);
}

Expand Down Expand Up @@ -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" +
Expand Down
3 changes: 2 additions & 1 deletion test/utils/bytecode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ inline bytecode rjumpi(int16_t offset, bytecode condition)

inline bytecode rjumpv(const std::initializer_list<int16_t> offsets, bytecode condition)
{
bytecode ret = condition + OP_RJUMPV + static_cast<Opcode>(offsets.size());
assert(offsets.size() > 0);
bytecode ret = condition + OP_RJUMPV + static_cast<Opcode>(offsets.size() - 1);
for (const auto offset : offsets)
ret += bytecode{big_endian(offset)};
return ret;
Expand Down

0 comments on commit e5ad909

Please sign in to comment.