Skip to content

Commit

Permalink
fix: ensure the payload format is valid
Browse files Browse the repository at this point in the history
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.