diff --git a/lib/evmone/eof.cpp b/lib/evmone/eof.cpp index 1f918cee02..d126f74109 100644 --- a/lib/evmone/eof.cpp +++ b/lib/evmone/eof.cpp @@ -225,7 +225,7 @@ EOFValidationError validate_instructions( else if (op == OP_DATALOADN) { const auto index = read_uint16_be(&code[i + 1]); - if (index >= header.data_size / 32) + if (header.data_size < 32 || index > header.data_size - 32) return EOFValidationError::invalid_dataloadn_index; i += 2; } diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 1d60fc23a0..511778727f 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -946,7 +946,7 @@ inline code_iterator dataloadn(StackTop stack, ExecutionState& state, code_itera { const auto index = read_uint16_be(&pos[1]); - const auto begin = static_cast(index * 32); + const auto begin = static_cast(index); stack.push(intx::be::unsafe::load(&state.data[begin])); return pos + 3; } diff --git a/test/unittests/eof_validation_test.cpp b/test/unittests/eof_validation_test.cpp index 7137d9ed03..c493368f86 100644 --- a/test/unittests/eof_validation_test.cpp +++ b/test/unittests/eof_validation_test.cpp @@ -1256,7 +1256,12 @@ TEST(eof_validation, dataloadn) EOFValidationError::success); // DATALOADN{1} - EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030040 00 00000001 b900015000" + EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030021 00 00000001 b900015000" + "000000000000000011111111111111112222222222222222333333333333333344"), + EOFValidationError::success); + + // DATALOADN{32} + EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030040 00 00000001 b900205000" "0000000000000000111111111111111122222222222222223333333333333333" "0000000000000000111111111111111122222222222222223333333333333333"), EOFValidationError::success); @@ -1266,7 +1271,12 @@ TEST(eof_validation, dataloadn) EOFValidationError::invalid_dataloadn_index); // DATALOADN{1} - out of data section bounds - EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030020 00 00000001 b900015000" + EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030001 00 00000001 b900015000" + "00"), + EOFValidationError::invalid_dataloadn_index); + + // DATALOADN{32} - out of data section bounds + EXPECT_EQ(validate_eof("EF0001 010004 0200010005 030020 00 00000001 b900205000" "0000000000000000111111111111111122222222222222223333333333333333"), EOFValidationError::invalid_dataloadn_index); @@ -1275,9 +1285,8 @@ TEST(eof_validation, dataloadn) "0000000000000000111111111111111122222222222222223333333333333333"), EOFValidationError::invalid_dataloadn_index); - // DATALOADN{2} - truncated word - EXPECT_EQ(validate_eof("EF0001 010004 0200010005 03005f 00 00000001 b900025000" - "0000000000000000111111111111111122222222222222223333333333333333" + // DATALOADN{32} - truncated word + EXPECT_EQ(validate_eof("EF0001 010004 0200010005 03003F 00 00000001 b900205000" "0000000000000000111111111111111122222222222222223333333333333333" "00000000000000001111111111111111222222222222222233333333333333"), EOFValidationError::invalid_dataloadn_index); diff --git a/test/unittests/evm_eof_test.cpp b/test/unittests/evm_eof_test.cpp index 3a6db1c3af..a0563490b4 100644 --- a/test/unittests/evm_eof_test.cpp +++ b/test/unittests/evm_eof_test.cpp @@ -215,6 +215,13 @@ TEST_P(evm, eof1_dataloadn) code = eof1_bytecode(bytecode(OP_DATALOADN) + "0001" + ret_top(), 2, data); execute(code); EXPECT_STATUS(EVMC_SUCCESS); + EXPECT_EQ(bytes_view(result.output_data, result.output_size), + "00000000000000111111111111111122222222222222223333333333333333aa"_hex); + + // DATALOADN{32} + code = eof1_bytecode(bytecode(OP_DATALOADN) + "0020" + ret_top(), 2, data); + execute(code); + EXPECT_STATUS(EVMC_SUCCESS); EXPECT_EQ(bytes_view(result.output_data, result.output_size), "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd"_hex); }