RJumpV overflow (#4985)

Address an RJumpV overflow discovered by reference tests.

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/4993/head
Danno Ferrin 2 years ago committed by GitHub
parent 617c14a520
commit 602147411e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java
  2. 81
      evm/src/test/java/org/hyperledger/besu/evm/operations/RelativeJumpOperationTest.java

@ -41,7 +41,15 @@ public class RelativeJumpVectorOperation extends AbstractFixedCostOperation {
@Override
protected OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) {
final Bytes code = frame.getCode().getBytes();
final int offsetCase = frame.popStackItem().toInt();
int offsetCase;
try {
offsetCase = frame.popStackItem().toInt();
if (offsetCase < 0) {
offsetCase = Integer.MAX_VALUE;
}
} catch (ArithmeticException | IllegalArgumentException ae) {
offsetCase = Integer.MAX_VALUE;
}
final int vectorSize = getVectorSize(code, frame.getPC() + 1);
return new OperationResult(
gasCost,

@ -129,6 +129,87 @@ class RelativeJumpOperationTest {
assertThat(rjumpResult.getPcIncrement()).isEqualTo(1 + 2 * jumpVectorSize + 1);
}
@ParameterizedTest
@ValueSource(
strings = {
"0xff",
"0x5f5f",
"0xf5f5",
"0x7fff",
"0xffff",
"0x5f5f5f5f",
"0xf5f5f5f5",
"0x7fffffff",
"0xffffffff",
"0x5f5f5f5f5f5f5f5f",
"0xf5f5f5f5f5f5f5f5",
"0x7fffffffffffffff",
"0xffffffffffffffff",
"0x5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f",
"0xf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5",
"0x7fffffffffffffffffffffffffffffff",
"0xffffffffffffffffffffffffffffffff",
"0x5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f",
"0xf5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5",
"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
})
void rjumpvOverflowOperation(final String stackValue) {
final GasCalculator gasCalculator = mock(GasCalculator.class);
final Code mockCode = mock(Code.class);
final int rjumpOperationIndex = 3;
final int jumpVectorSize = 255;
final int jumpLength = 400;
final Bytes code =
Bytes.fromHexString(
"00".repeat(rjumpOperationIndex)
+ String.format("5e%02x", jumpVectorSize)
+ String.format("%04x", jumpLength).repeat(jumpVectorSize));
when(mockCode.getBytes()).thenReturn(code);
RelativeJumpVectorOperation rjumpv = new RelativeJumpVectorOperation(gasCalculator);
MessageFrame messageFrame =
new TestMessageFrameBuilder()
.code(mockCode)
.pc(rjumpOperationIndex)
.initialGas(5L)
.pushStackItem(Bytes.fromHexString(stackValue))
.build();
Operation.OperationResult rjumpResult = rjumpv.execute(messageFrame, null);
assertThat(rjumpResult.getPcIncrement()).isEqualTo(1 + 2 * jumpVectorSize + 1);
}
@ParameterizedTest
@ValueSource(strings = {"0x7f", "0xf5", "0x5f", "0xfe"})
void rjumpvIndexOperation(final String stackValue) {
final GasCalculator gasCalculator = mock(GasCalculator.class);
final Code mockCode = mock(Code.class);
final int rjumpOperationIndex = 3;
final int jumpVectorSize = 255;
final int jumpLength = 400;
final Bytes code =
Bytes.fromHexString(
"00".repeat(rjumpOperationIndex)
+ String.format("5e%02x", jumpVectorSize)
+ String.format("%04x", jumpLength).repeat(jumpVectorSize));
when(mockCode.getBytes()).thenReturn(code);
RelativeJumpVectorOperation rjumpv = new RelativeJumpVectorOperation(gasCalculator);
MessageFrame messageFrame =
new TestMessageFrameBuilder()
.code(mockCode)
.pc(rjumpOperationIndex)
.initialGas(5L)
.pushStackItem(Bytes.fromHexString(stackValue))
.build();
Operation.OperationResult rjumpResult = rjumpv.execute(messageFrame, null);
assertThat(rjumpResult.getPcIncrement()).isEqualTo(2 + 2 * jumpVectorSize + jumpLength);
}
@Test
void rjumpvHitOperation() {
final GasCalculator gasCalculator = mock(GasCalculator.class);

Loading…
Cancel
Save