Skip to content

Commit dfd2806

Browse files
committed
test(jsonrpc): drop request body cases already covered by the byte check
- Remove the UTF-32 decoding test; its bodies contain NUL bytes and are rejected before parsing, like the other UTF-16 and UTF-32 cases. - Merge the UTF-16 test with a byte order mark into the UTF-16/UTF-32 rejection test and add a U+00E9 request to it. - Drop stubs for methods that the rejection tests never reach. - Use Guava Bytes.concat instead of local helpers.
1 parent c2ea817 commit dfd2806

2 files changed

Lines changed: 12 additions & 62 deletions

File tree

‎framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletJettyTest.java‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package org.tron.core.services.jsonrpc;
22

3+
import static com.google.common.primitives.Bytes.concat;
4+
35
import com.fasterxml.jackson.databind.JsonNode;
46
import com.fasterxml.jackson.databind.ObjectMapper;
57
import com.googlecode.jsonrpc4j.JsonRpcMethod;
68
import com.googlecode.jsonrpc4j.JsonRpcServer;
7-
import java.io.ByteArrayOutputStream;
89
import java.io.IOException;
910
import java.lang.reflect.Field;
1011
import java.net.SocketException;
@@ -233,14 +234,6 @@ private void assertParseErrorOverHttp(URI endpoint, byte[] body) throws IOExcept
233234
}
234235
}
235236

236-
private static byte[] concat(byte[]... parts) {
237-
ByteArrayOutputStream out = new ByteArrayOutputStream();
238-
for (byte[] part : parts) {
239-
out.write(part, 0, part.length);
240-
}
241-
return out.toByteArray();
242-
}
243-
244237
public interface FatalService {
245238

246239
@JsonRpcMethod("test_fatal")

‎framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletTest.java‎

Lines changed: 10 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.tron.core.services.jsonrpc;
22

3+
import static com.google.common.primitives.Bytes.concat;
34
import static org.junit.Assert.assertArrayEquals;
45
import static org.junit.Assert.assertEquals;
56
import static org.junit.Assert.assertFalse;
@@ -34,7 +35,6 @@
3435
import com.fasterxml.jackson.databind.node.ObjectNode;
3536
import com.googlecode.jsonrpc4j.JsonRpcMethod;
3637
import com.googlecode.jsonrpc4j.JsonRpcServer;
37-
import java.io.ByteArrayOutputStream;
3838
import java.io.IOException;
3939
import java.io.InputStream;
4040
import java.io.OutputStream;
@@ -110,7 +110,6 @@ public void emptyBody_returnsParseError() throws Exception {
110110
@Test
111111
public void malformedUtf8_isRejectedBeforeDispatch() throws Exception {
112112
TronJsonRpc rpc = useRealRpcServer();
113-
when(rpc.web3ClientVersion()).thenReturn("client");
114113
// Each sequence replaces the leading 'w' of web3_clientVersion. The overlong forms decode
115114
// to 'w' in a lenient parser, so they reach the real method unless rejected up front.
116115
byte[][] sequences = {
@@ -165,15 +164,22 @@ public void utf8ByteOrderMark_isAccepted() throws Exception {
165164
}
166165

167166
@Test
168-
public void utf16AndUtf32WithoutByteOrderMark_areRejected() throws Exception {
167+
public void utf16AndUtf32Bodies_areRejected() throws Exception {
169168
TronJsonRpc rpc = useRealRpcServer();
170169
String request = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"id\":1}";
171170
String chinese = "{\"jsonrpc\":\"2.0\",\"method\":\"web3_sha3\",\"params\":[\"中\"],\"id\":1}";
171+
String accented = "{\"jsonrpc\":\"2.0\",\"method\":\"web3_sha3\",\"params\":[\"é\"],\"id\":1}";
172172
for (String charset : Arrays.asList("UTF-16LE", "UTF-16BE", "UTF-32LE", "UTF-32BE")) {
173-
for (String body : Arrays.asList(request, chinese)) {
173+
for (String body : Arrays.asList(request, chinese, accented)) {
174174
assertParseError(charset + " " + body, doPost(body.getBytes(Charset.forName(charset))));
175175
}
176176
}
177+
List<byte[]> withByteOrderMark = Arrays.asList(
178+
request.getBytes(StandardCharsets.UTF_16),
179+
concat(new byte[] {(byte) 0xFF, (byte) 0xFE}, request.getBytes(StandardCharsets.UTF_16LE)));
180+
for (byte[] body : withByteOrderMark) {
181+
assertParseError(Arrays.toString(body), doPost(body));
182+
}
177183
verify(realRpcServer, never()).handleRequest(any(InputStream.class), any(OutputStream.class));
178184
verify(rpc, never()).getLatestBlockNum();
179185
verify(rpc, never()).web3Sha3(any());
@@ -208,25 +214,6 @@ public void escapedNulCharacter_isDispatched() throws Exception {
208214
verify(rpc).web3Sha3("a" + (char) 0 + "b");
209215
}
210216

211-
@Test
212-
public void utf16BodyThatIsNotWellFormedUtf8_isRejected() throws Exception {
213-
TronJsonRpc rpc = useRealRpcServer();
214-
when(rpc.web3Sha3(any())).thenReturn("0x1");
215-
String request = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"id\":1}";
216-
String nonAscii = "{\"jsonrpc\":\"2.0\",\"method\":\"web3_sha3\",\"params\":[\"é\"],\"id\":1}";
217-
List<byte[]> bodies = Arrays.asList(
218-
request.getBytes(StandardCharsets.UTF_16),
219-
concat(new byte[] {(byte) 0xFF, (byte) 0xFE}, request.getBytes(StandardCharsets.UTF_16LE)),
220-
nonAscii.getBytes(StandardCharsets.UTF_16LE),
221-
nonAscii.getBytes(StandardCharsets.UTF_16BE));
222-
for (byte[] body : bodies) {
223-
assertParseError(Arrays.toString(body), doPost(body));
224-
}
225-
verify(realRpcServer, never()).handleRequest(any(InputStream.class), any(OutputStream.class));
226-
verify(rpc, never()).getLatestBlockNum();
227-
verify(rpc, never()).web3Sha3(any());
228-
}
229-
230217
@Test
231218
public void trailingContent_isRejectedBeforeDispatch() throws Exception {
232219
TronJsonRpc rpc = useRealRpcServer();
@@ -270,28 +257,6 @@ public void trailingWhitespace_isAccepted() throws Exception {
270257
verify(rpc, times(7)).getLatestBlockNum();
271258
}
272259

273-
@Test
274-
public void undecodableUtf32Body_returnsParseError() throws Exception {
275-
TronJsonRpc rpc = useRealRpcServer();
276-
byte[] request = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"id\":1}"
277-
.getBytes(Charset.forName("UTF-32BE"));
278-
byte[] padding = new byte[4096];
279-
for (int i = 3; i < padding.length; i += 4) {
280-
padding[i] = ' ';
281-
}
282-
// Jackson's UTF-32 decoder reports these as a CharConversionException, an IOException that
283-
// is not a JsonProcessingException.
284-
List<byte[]> bodies = Arrays.asList(
285-
concat(request, new byte[] {'\n'}),
286-
concat(request, new byte[] {0, 0, ' '}),
287-
concat(request, padding, new byte[] {0, 0x11, 0, 0}));
288-
for (byte[] body : bodies) {
289-
assertParseError(Arrays.toString(body), doPost(body));
290-
}
291-
verify(realRpcServer, never()).handleRequest(any(InputStream.class), any(OutputStream.class));
292-
verify(rpc, never()).getLatestBlockNum();
293-
}
294-
295260
// --- batch size limit ---
296261

297262
@Test
@@ -2073,14 +2038,6 @@ private static byte[] utf8(String text) {
20732038
return text.getBytes(StandardCharsets.UTF_8);
20742039
}
20752040

2076-
private static byte[] concat(byte[]... parts) {
2077-
ByteArrayOutputStream out = new ByteArrayOutputStream();
2078-
for (byte[] part : parts) {
2079-
out.write(part, 0, part.length);
2080-
}
2081-
return out.toByteArray();
2082-
}
2083-
20842041
private void assertCleanupFailureDoesNotReplaceFatal(HttpServletResponse response)
20852042
throws Exception {
20862043
StackOverflowError fatal = new StackOverflowError("original-fatal-marker");

0 commit comments

Comments
 (0)