fix: ensure the payload format is valid

This commit should prevent some NPE issues encountered after the
parsing of the packet.

Related:

- https://github.com/socketio/socket.io-client-java/issues/642
- https://github.com/socketio/socket.io-client-java/issues/609
- https://github.com/socketio/socket.io-client-java/issues/505
This commit is contained in:
Damien Arrachequesne
2021-04-26 23:30:53 +02:00
parent 4885e7d59f
commit e8ffe9d138
4 changed files with 50 additions and 34 deletions

View File

@@ -326,10 +326,14 @@ public class Manager extends Emitter {
@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());
}
}
}));
@@ -353,22 +357,6 @@ public class Manager extends Emitter {
});
}
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);
}

View File

@@ -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;
@@ -183,6 +185,9 @@ final public class IOParser implements Parser {
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)) {
@@ -191,6 +196,26 @@ final public class IOParser implements Parser {
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) {