handle utf8 decode errors
This commit is contained in:
@@ -2,6 +2,7 @@ package com.github.nkzawa.engineio.parser;
|
|||||||
|
|
||||||
|
|
||||||
import com.github.nkzawa.utf8.UTF8;
|
import com.github.nkzawa.utf8.UTF8;
|
||||||
|
import com.github.nkzawa.utf8.UTF8Exception;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -73,7 +74,11 @@ public class Parser {
|
|||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
type = -1;
|
type = -1;
|
||||||
}
|
}
|
||||||
data = UTF8.decode(data);
|
try {
|
||||||
|
data = UTF8.decode(data);
|
||||||
|
} catch (UTF8Exception e) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (type < 0 || type >= packetslist.size()) {
|
if (type < 0 || type >= packetslist.size()) {
|
||||||
return err;
|
return err;
|
||||||
@@ -164,7 +169,6 @@ public class Parser {
|
|||||||
|
|
||||||
if (msg.length() != 0) {
|
if (msg.length() != 0) {
|
||||||
Packet<String> packet = decodePacket(msg);
|
Packet<String> packet = decodePacket(msg);
|
||||||
|
|
||||||
if (err.type.equals(packet.type) && err.data.equals(packet.data)) {
|
if (err.type.equals(packet.type) && err.data.equals(packet.data)) {
|
||||||
callback.call(err, 0, 1);
|
callback.call(err, 0, 1);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class UTF8 {
|
|||||||
return byteString.toString();
|
return byteString.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String decode(String byteString) {
|
public static String decode(String byteString) throws UTF8Exception {
|
||||||
byteArray = uc2decode(byteString);
|
byteArray = uc2decode(byteString);
|
||||||
byteCount = byteArray.length;
|
byteCount = byteArray.length;
|
||||||
byteIndex = 0;
|
byteIndex = 0;
|
||||||
@@ -74,7 +74,7 @@ public class UTF8 {
|
|||||||
return Character.toChars(((codePoint >> shift) & 0x3F) | 0x80);
|
return Character.toChars(((codePoint >> shift) & 0x3F) | 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int decodeSymbol() {
|
private static int decodeSymbol() throws UTF8Exception {
|
||||||
int byte1;
|
int byte1;
|
||||||
int byte2;
|
int byte2;
|
||||||
int byte3;
|
int byte3;
|
||||||
@@ -82,7 +82,7 @@ public class UTF8 {
|
|||||||
int codePoint;
|
int codePoint;
|
||||||
|
|
||||||
if (byteIndex > byteCount) {
|
if (byteIndex > byteCount) {
|
||||||
throw new RuntimeException("Invalid byte index");
|
throw new UTF8Exception("Invalid byte index");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byteIndex == byteCount) {
|
if (byteIndex == byteCount) {
|
||||||
@@ -102,7 +102,7 @@ public class UTF8 {
|
|||||||
if (codePoint >= 0x80) {
|
if (codePoint >= 0x80) {
|
||||||
return codePoint;
|
return codePoint;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Invalid continuation byte");
|
throw new UTF8Exception("Invalid continuation byte");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ public class UTF8 {
|
|||||||
if (codePoint >= 0x0800) {
|
if (codePoint >= 0x0800) {
|
||||||
return codePoint;
|
return codePoint;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Invalid continuation byte");
|
throw new UTF8Exception("Invalid continuation byte");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +127,12 @@ public class UTF8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("Invalid continuation byte");
|
throw new UTF8Exception("Invalid continuation byte");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int readContinuationByte() {
|
private static int readContinuationByte() throws UTF8Exception {
|
||||||
if (byteIndex >= byteCount) {
|
if (byteIndex >= byteCount) {
|
||||||
throw new RuntimeException("Invalid byte index");
|
throw new UTF8Exception("Invalid byte index");
|
||||||
}
|
}
|
||||||
|
|
||||||
int continuationByte = byteArray[byteIndex] & 0xFF;
|
int continuationByte = byteArray[byteIndex] & 0xFF;
|
||||||
@@ -142,7 +142,7 @@ public class UTF8 {
|
|||||||
return continuationByte & 0x3F;
|
return continuationByte & 0x3F;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("Invalid continuation byte");
|
throw new UTF8Exception("Invalid continuation byte");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String ucs2encode(int[] array) {
|
private static String ucs2encode(int[] array) {
|
||||||
|
|||||||
24
src/main/java/com/github/nkzawa/utf8/UTF8Exception.java
Normal file
24
src/main/java/com/github/nkzawa/utf8/UTF8Exception.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.github.nkzawa.utf8;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UTF8Exception extends IOException {
|
||||||
|
|
||||||
|
public String data;
|
||||||
|
|
||||||
|
public UTF8Exception() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UTF8Exception(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UTF8Exception(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UTF8Exception(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -169,6 +169,13 @@ public class ParserTest {
|
|||||||
assertThat(p.data, is(ERROR_DATA));
|
assertThat(p.data, is(ERROR_DATA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decodeInvalidUTF8() {
|
||||||
|
Packet<String> p = decodePacket("4\uffff");
|
||||||
|
assertThat(p.type, is(Packet.ERROR));
|
||||||
|
assertThat(p.data, is(ERROR_DATA));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void encodePayloads() {
|
public void encodePayloads() {
|
||||||
encodePayload(new Packet[]{new Packet(Packet.PING), new Packet(Packet.PONG)}, new EncodeCallback<byte[]>() {
|
encodePayload(new Packet[]{new Packet(Packet.PING), new Packet(Packet.PONG)}, new EncodeCallback<byte[]>() {
|
||||||
@@ -313,6 +320,20 @@ public class ParserTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decodePayloadInvalidUTF8() {
|
||||||
|
decodePayload("2:4\uffff", new DecodePayloadCallback<String>() {
|
||||||
|
@Override
|
||||||
|
public boolean call(Packet<String> packet, int index, int total) {
|
||||||
|
boolean isLast = index + 1 == total;
|
||||||
|
assertThat(packet.type, is(Packet.ERROR));
|
||||||
|
assertThat(packet.data, is(ERROR_DATA));
|
||||||
|
assertThat(isLast, is(true));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void encodeBinaryMessage() {
|
public void encodeBinaryMessage() {
|
||||||
final byte[] data = new byte[5];
|
final byte[] data = new byte[5];
|
||||||
|
|||||||
@@ -55,23 +55,23 @@ public class UTF8Test {
|
|||||||
public ExpectedException exception = ExpectedException.none();
|
public ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void encodeAndDecode() {
|
public void encodeAndDecode() throws UTF8Exception {
|
||||||
for (Data data : DATA) {
|
for (Data data : DATA) {
|
||||||
String reason = data.description != null? data.description : "U+" + Integer.toHexString(data.codePoint).toUpperCase();
|
String reason = data.description != null? data.description : "U+" + Integer.toHexString(data.codePoint).toUpperCase();
|
||||||
assertThat("Encoding: " + reason, data.encoded, is(UTF8.encode(data.decoded)));
|
assertThat("Encoding: " + reason, data.encoded, is(UTF8.encode(data.decoded)));
|
||||||
assertThat("Decoding: " + reason, data.decoded, is(UTF8.decode(data.encoded)));
|
assertThat("Decoding: " + reason, data.decoded, is(UTF8.decode(data.encoded)));
|
||||||
}
|
}
|
||||||
|
|
||||||
exception.expect(RuntimeException.class);
|
exception.expect(UTF8Exception.class);
|
||||||
UTF8.decode("\uFFFF");
|
UTF8.decode("\uFFFF");
|
||||||
|
|
||||||
exception.expect(RuntimeException.class);
|
exception.expect(UTF8Exception.class);
|
||||||
UTF8.decode("\u00E9\u0000\u0000");
|
UTF8.decode("\u00E9\u0000\u0000");
|
||||||
|
|
||||||
exception.expect(RuntimeException.class);
|
exception.expect(UTF8Exception.class);
|
||||||
UTF8.decode("\u00C2\uFFFF");
|
UTF8.decode("\u00C2\uFFFF");
|
||||||
|
|
||||||
exception.expect(RuntimeException.class);
|
exception.expect(UTF8Exception.class);
|
||||||
UTF8.decode("\u00F0\u009D");
|
UTF8.decode("\u00F0\u009D");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user