Skip to content
Permalink
Browse files Browse the repository at this point in the history
fix: ensure the payload format is valid
This commit should prevent some NPE issues encountered after the
parsing of the packet.

Related:

- #642
- #609
- #505
  • Loading branch information
darrachequesne committed Apr 26, 2021
1 parent 4885e7d commit e8ffe9d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 34 deletions.
28 changes: 8 additions & 20 deletions src/main/java/io/socket/client/Manager.java
Expand Up @@ -326,10 +326,14 @@ private void onopen() {
@Override
public void call(Object... objects) {
Object data = objects[0];
if (data instanceof String) {
Manager.this.ondata((String)data);
} else if (data instanceof byte[]) {
Manager.this.ondata((byte[])data);
try {
if (data instanceof String) {
Manager.this.decoder.add((String) data);
} else if (data instanceof byte[]) {
Manager.this.decoder.add((byte[]) data);
}
} catch (DecodingException e) {
logger.fine("error while decoding the packet: " + e.getMessage());
}
}
}));
Expand All @@ -353,22 +357,6 @@ public void call (Packet packet) {
});
}

private void ondata(String data) {
try {
this.decoder.add(data);
} catch (DecodingException e) {
this.onerror(e);
}
}

private void ondata(byte[] data) {
try {
this.decoder.add(data);
} catch (DecodingException e) {
this.onerror(e);
}
}

private void ondecoded(Packet packet) {
this.emit(EVENT_PACKET, packet);
}
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/io/socket/parser/IOParser.java
@@ -1,7 +1,9 @@
package io.socket.parser;

import io.socket.hasbinary.HasBinary;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.util.ArrayList;
Expand Down Expand Up @@ -183,6 +185,9 @@ private static Packet decodeString(String str) {
logger.log(Level.WARNING, "An error occured while retrieving data from JSONTokener", e);
throw new DecodingException("invalid payload");
}
if (!isPayloadValid(p.type, p.data)) {
throw new DecodingException("invalid payload");
}
}

if (logger.isLoggable(Level.FINE)) {
Expand All @@ -191,6 +196,26 @@ private static Packet decodeString(String str) {
return p;
}

private static boolean isPayloadValid(int type, Object payload) {
switch (type) {
case Parser.CONNECT:
case Parser.CONNECT_ERROR:
return payload instanceof JSONObject;
case Parser.DISCONNECT:
return payload == null;
case Parser.EVENT:
case Parser.BINARY_EVENT:
return payload instanceof JSONArray
&& ((JSONArray) payload).length() > 0
&& !((JSONArray) payload).isNull(0);
case Parser.ACK:
case Parser.BINARY_ACK:
return payload instanceof JSONArray;
default:
return false;
}
}

@Override
public void destroy() {
if (this.reconstructor != null) {
Expand Down
28 changes: 14 additions & 14 deletions src/test/java/io/socket/parser/ByteArrayTest.java
@@ -1,15 +1,15 @@
package io.socket.parser;

import io.socket.emitter.Emitter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

Expand All @@ -19,30 +19,30 @@ public class ByteArrayTest {
private static Parser.Encoder encoder = new IOParser.Encoder();

@Test
public void encodeByteArray() {
Packet<byte[]> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = "abc".getBytes(Charset.forName("UTF-8"));
public void encodeByteArray() throws JSONException {
Packet<JSONArray> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = new JSONArray(asList("abc", "abc".getBytes(StandardCharsets.UTF_8)));
packet.id = 23;
packet.nsp = "/cool";
Helpers.testBin(packet);
}

@Test
public void encodeByteArray2() {
Packet<byte[]> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = new byte[2];
Packet<JSONArray> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = new JSONArray(asList("2", new byte[] { 0, 1 }));
packet.id = 0;
packet.nsp = "/";
Helpers.testBin(packet);
}

@Test
public void encodeByteArrayDeepInJson() throws JSONException {
JSONObject data = new JSONObject("{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}");
data.getJSONObject("b").put("why", new byte[3]);
data.getJSONObject("c").getJSONObject("b").put("a", new byte[6]);
JSONArray data = new JSONArray("[{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}]");
data.getJSONObject(0).getJSONObject("b").put("why", new byte[3]);
data.getJSONObject(0).getJSONObject("c").getJSONObject("b").put("a", new byte[6]);

Packet<JSONObject> packet = new Packet<>(Parser.BINARY_EVENT);
Packet<JSONArray> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = data;
packet.id = 999;
packet.nsp = "/deep";
Expand All @@ -51,10 +51,10 @@ public void encodeByteArrayDeepInJson() throws JSONException {

@Test
public void encodeDeepBinaryJSONWithNullValue() throws JSONException {
JSONObject data = new JSONObject("{a: \"b\", c: 4, e: {g: null}, h: null}");
data.put("h", new byte[9]);
JSONArray data = new JSONArray("[{a: \"b\", c: 4, e: {g: null}, h: null}]");
data.getJSONObject(0).put("h", new byte[9]);

Packet<JSONObject> packet = new Packet<>(Parser.BINARY_EVENT);
Packet<JSONArray> packet = new Packet<>(Parser.BINARY_EVENT);
packet.data = data;
packet.nsp = "/";
packet.id = 600;
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/socket/parser/ParserTest.java
Expand Up @@ -63,5 +63,8 @@ public void decodeInError() throws JSONException {
Helpers.testDecodeError(Parser.EVENT + "2sd");
// event with invalid json data
Helpers.testDecodeError(Parser.EVENT + "2[\"a\",1,{asdf}]");
Helpers.testDecodeError(Parser.EVENT + "2{}");
Helpers.testDecodeError(Parser.EVENT + "2[]");
Helpers.testDecodeError(Parser.EVENT + "2[null]");
}
}

0 comments on commit e8ffe9d

Please sign in to comment.