Skip to content

Commit

Permalink
Merge pull request #217 from ethereum/fix_jumpdest_overflow
Browse files Browse the repository at this point in the history
Fix jumpdest offset overflow
  • Loading branch information
chfast authored Nov 28, 2019
2 parents 284f4bf + 53a5808 commit 264e395
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 5 deletions.
4 changes: 2 additions & 2 deletions lib/evmone/analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size)
{
// The JUMPDEST is always the first instruction in the block.
// We don't have to insert anything to the instruction table.
analysis.jumpdest_offsets.emplace_back(static_cast<int16_t>(code_pos - code - 1));
analysis.jumpdest_offsets.emplace_back(static_cast<int32_t>(code_pos - code - 1));
analysis.jumpdest_targets.emplace_back(
static_cast<int16_t>(analysis.instrs.size() - 1));
static_cast<int32_t>(analysis.instrs.size() - 1));
}
else
analysis.instrs.emplace_back(opcode_info.fn);
Expand Down
4 changes: 2 additions & 2 deletions lib/evmone/analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ struct code_analysis
/// The offsets of JUMPDESTs in the original code.
/// These are values that JUMP/JUMPI receives as an argument.
/// The elements are sorted.
std::vector<int16_t> jumpdest_offsets;
std::vector<int32_t> jumpdest_offsets;

/// The indexes of the instructions in the generated instruction table
/// matching the elements from jumdest_offsets.
/// This is value to which the next instruction pointer must be set in JUMP/JUMPI.
std::vector<int16_t> jumpdest_targets;
std::vector<int32_t> jumpdest_targets;
};

inline int find_jumpdest(const code_analysis& analysis, int offset) noexcept
Expand Down
13 changes: 13 additions & 0 deletions test/unittests/evm_other_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/// - evmone's internal tests.

#include "evm_fixture.hpp"

#include <evmone/limits.hpp>

using evm_other = evm;
Expand Down Expand Up @@ -56,3 +57,15 @@ TEST_F(evm_other, loop_full_of_jumpdests)
execute(code);
EXPECT_GAS_USED(EVMC_SUCCESS, 7987882);
}

TEST_F(evm_other, jumpdest_with_high_offset)
{
for (auto offset : {3u, 16383u, 16384u, 32767u, 32768u, 65535u, 65536u})
{
auto code = push(offset) + OP_JUMP;
code.resize(offset, OP_INVALID);
code.push_back(OP_JUMPDEST);
execute(code);
EXPECT_EQ(result.status_code, EVMC_SUCCESS) << "JUMPDEST at " << offset;
}
}
2 changes: 1 addition & 1 deletion test/utils/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void dump(const evmone::code_analysis& analysis)
if (static_cast<size_t>(analysis.jumpdest_targets[t]) == index)
return analysis.jumpdest_offsets[t];
}
return int16_t{-1};
return int32_t{-1};
};

std::cout << "";
Expand Down

0 comments on commit 264e395

Please sign in to comment.