diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java index 82a78cacff2..de9266d880c 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodec.java @@ -44,12 +44,18 @@ public ExecutionRequests decode(final List executionRequests) { if (request.isEmpty()) { throw new IllegalArgumentException("Execution request data must not be empty"); } + final byte requestType = request.get(0); if (requestType <= previousRequestType) { throw new IllegalArgumentException( "Execution requests are not in strictly ascending order"); } + final Bytes requestData = request.slice(1); + if (requestData.isEmpty()) { + throw new IllegalArgumentException("Empty data for request type " + requestType); + } + switch (requestType) { case DepositRequest.REQUEST_TYPE -> executionRequestsBuilder.deposits( diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java index 70b5e0e0aba..0aa99d83bc0 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/versions/electra/ExecutionRequestsDataCodecTest.java @@ -92,12 +92,14 @@ public void decodeExecutionRequestsDataWithOneRequestMissing() { @Test public void decodeExecutionRequestsDataWithInvalidRequestType() { + final Bytes invalidRequestType = Bytes.of(9); + final Bytes invalidTypeEncodedList = Bytes.concatenate(invalidRequestType, Bytes.random(10)); final List invalidExecutionRequestsData = - List.of(depositRequestListEncoded, withdrawalRequestsListEncoded, Bytes.of(9)); + List.of(depositRequestListEncoded, withdrawalRequestsListEncoded, invalidTypeEncodedList); assertThatThrownBy(() -> codec.decode(invalidExecutionRequestsData)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid execution request type: 9"); + .hasMessage("Invalid execution request type: " + invalidRequestType.toInt()); } @Test @@ -126,6 +128,29 @@ public void decodeExecutionRequestDataWithRepeatedRequestsOfSameType() { .hasMessage("Execution requests are not in strictly ascending order"); } + @Test + public void decodeExecutionRequestsDataWithEmptyRequestData() { + // Element containing only the type by but no data + final List invalidEmptyRequestsData = List.of(DepositRequest.REQUEST_TYPE_PREFIX); + + assertThatThrownBy(() -> codec.decode(invalidEmptyRequestsData)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Empty data for request type 0"); + } + + @Test + public void decodeExecutionRequestsDataWithOneInvalidEmptyRequestData() { + final List invalidExecutionRequestsData = + List.of( + depositRequestListEncoded, + withdrawalRequestsListEncoded, + ConsolidationRequest.REQUEST_TYPE_PREFIX); + + assertThatThrownBy(() -> codec.decode(invalidExecutionRequestsData)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Empty data for request type 2"); + } + @Test public void encodeExecutionRequests() { final ExecutionRequests executionRequests =