diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java index d8a64c571c..90f1795803 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java @@ -74,12 +74,28 @@ public class JsonRpcRequest { @JsonIgnore public int getParamLength() { - return params.length; + return hasParams() ? params.length : 0; + } + + @JsonIgnore + public boolean hasParams() { + + // Null Object: "params":null + if (params == null) { + return false; + } + + // Null Array: "params":[null] + if (params.length == 0 || params[0] == null) { + return false; + } + + return true; } @JsonSetter("id") protected void setId(final JsonRpcRequestId id) { - // If an id is explicitly set, its not a notification + // If an id is explicitly set, it is not a notification isNotification = false; this.id = id; } diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/parameters/JsonRpcParameter.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/parameters/JsonRpcParameter.java index f5c8a613e4..b2f77b8a75 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/parameters/JsonRpcParameter.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/parameters/JsonRpcParameter.java @@ -57,7 +57,7 @@ public class JsonRpcParameter { @SuppressWarnings("unchecked") public Optional optional( final Object[] params, final int index, final Class paramClass) { - if (params == null || params.length <= index) { + if (params == null || params.length <= index || params[index] == null) { return Optional.empty(); } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminAddPeerTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminAddPeerTest.java index 6082965a2c..1f48fc4944 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminAddPeerTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminAddPeerTest.java @@ -55,6 +55,28 @@ public class AdminAddPeerTest { assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); } + @Test + public void requestHasNullObjectParameter() { + final JsonRpcRequest request = new JsonRpcRequest("2.0", "admin_addPeer", null); + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + + @Test + public void requestHasNullArrayParameter() { + final JsonRpcRequest request = new JsonRpcRequest("2.0", "admin_addPeer", new String[] {null}); + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + @Test public void requestHasInvalidEnode() { final JsonRpcRequest request = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthSendRawTransactionTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthSendRawTransactionTest.java index 69a16de61f..13d9bdca2e 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthSendRawTransactionTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthSendRawTransactionTest.java @@ -64,6 +64,31 @@ public class EthSendRawTransactionTest { assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); } + @Test + public void requestHasNullObjectParameter() { + final JsonRpcRequest request = new JsonRpcRequest("2.0", "eth_sendRawTransaction", null); + + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + + @Test + public void requestHasNullArrayParameter() { + final JsonRpcRequest request = + new JsonRpcRequest("2.0", "eth_sendRawTransaction", new String[] {null}); + + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + @Test public void invalidTransactionRlpDecoding() { final String rawTransaction = "0x00"; diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java index 6780b21a8a..0f3aeebff6 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java @@ -106,6 +106,31 @@ public class EeaSendRawTransactionTest { assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); } + @Test + public void requestHasNullObjectParameter() { + final JsonRpcRequest request = new JsonRpcRequest("2.0", "eea_sendRawTransaction", null); + + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + + @Test + public void requestHasNullArrayParameter() { + final JsonRpcRequest request = + new JsonRpcRequest("2.0", "eea_sendRawTransaction", new String[] {null}); + + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); + + final JsonRpcResponse actualResponse = method.response(request); + + assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + } + @Test public void invalidTransactionRlpDecoding() { final String rawTransaction = "0x00";