check lone surrogate (compatible with utf8.js v2.1.0)
This commit is contained in:
@@ -5,6 +5,7 @@ import io.socket.emitter.Emitter;
|
||||
import io.socket.engineio.parser.Packet;
|
||||
import io.socket.engineio.parser.Parser;
|
||||
import io.socket.thread.EventThread;
|
||||
import io.socket.utf8.UTF8Exception;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -98,7 +99,11 @@ public abstract class Transport extends Emitter {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Transport.this.readyState == ReadyState.OPEN) {
|
||||
Transport.this.write(packets);
|
||||
try {
|
||||
Transport.this.write(packets);
|
||||
} catch (UTF8Exception err) {
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Transport not open");
|
||||
}
|
||||
@@ -129,7 +134,7 @@ public abstract class Transport extends Emitter {
|
||||
this.emit(EVENT_CLOSE);
|
||||
}
|
||||
|
||||
abstract protected void write(Packet[] packets);
|
||||
abstract protected void write(Packet[] packets) throws UTF8Exception;
|
||||
|
||||
abstract protected void doOpen();
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.socket.engineio.parser.Parser;
|
||||
import io.socket.parseqs.ParseQS;
|
||||
import io.socket.thread.EventThread;
|
||||
import io.socket.emitter.Emitter;
|
||||
import io.socket.utf8.UTF8Exception;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -152,7 +153,11 @@ abstract public class Polling extends Transport {
|
||||
@Override
|
||||
public void call(Object... args) {
|
||||
logger.fine("writing close packet");
|
||||
self.write(new Packet[] {new Packet(Packet.CLOSE)});
|
||||
try {
|
||||
self.write(new Packet[]{new Packet(Packet.CLOSE)});
|
||||
} catch (UTF8Exception err) {
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -167,7 +172,7 @@ abstract public class Polling extends Transport {
|
||||
}
|
||||
}
|
||||
|
||||
protected void write(Packet[] packets) {
|
||||
protected void write(Packet[] packets) throws UTF8Exception {
|
||||
final Polling self = this;
|
||||
this.writable = false;
|
||||
final Runnable callbackfn = new Runnable() {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.squareup.okhttp.Response;
|
||||
import com.squareup.okhttp.ws.WebSocket.PayloadType;
|
||||
import com.squareup.okhttp.ws.WebSocketCall;
|
||||
import com.squareup.okhttp.ws.WebSocketListener;
|
||||
import io.socket.utf8.UTF8Exception;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
|
||||
@@ -142,7 +143,7 @@ public class WebSocket extends Transport {
|
||||
client.getDispatcher().getExecutorService().shutdown();
|
||||
}
|
||||
|
||||
protected void write(Packet[] packets) {
|
||||
protected void write(Packet[] packets) throws UTF8Exception {
|
||||
final WebSocket self = this;
|
||||
this.writable = false;
|
||||
for (Packet packet : packets) {
|
||||
|
||||
@@ -38,11 +38,11 @@ public class Parser {
|
||||
|
||||
private Parser() {}
|
||||
|
||||
public static void encodePacket(Packet packet, EncodeCallback callback) {
|
||||
public static void encodePacket(Packet packet, EncodeCallback callback) throws UTF8Exception {
|
||||
encodePacket(packet, false, callback);
|
||||
}
|
||||
|
||||
public static void encodePacket(Packet packet, boolean utf8encode, EncodeCallback callback) {
|
||||
public static void encodePacket(Packet packet, boolean utf8encode, EncodeCallback callback) throws UTF8Exception {
|
||||
if (packet.data instanceof byte[]) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Packet<byte[]> _packet = packet;
|
||||
@@ -109,7 +109,7 @@ public class Parser {
|
||||
return new Packet<byte[]>(packetslist.get(type), intArray);
|
||||
}
|
||||
|
||||
public static void encodePayload(Packet[] packets, EncodeCallback<byte[]> callback) {
|
||||
public static void encodePayload(Packet[] packets, EncodeCallback<byte[]> callback) throws UTF8Exception {
|
||||
if (packets.length == 0) {
|
||||
callback.call(new byte[0]);
|
||||
return;
|
||||
|
||||
@@ -14,8 +14,8 @@ public class UTF8 {
|
||||
private static int byteCount;
|
||||
private static int byteIndex;
|
||||
|
||||
public static String encode(String string) {
|
||||
int[] codePoints = uc2decode(string);
|
||||
public static String encode(String string) throws UTF8Exception {
|
||||
int[] codePoints = ucs2decode(string);
|
||||
int length = codePoints.length;
|
||||
int index = -1;
|
||||
int codePoint;
|
||||
@@ -28,7 +28,7 @@ public class UTF8 {
|
||||
}
|
||||
|
||||
public static String decode(String byteString) throws UTF8Exception {
|
||||
byteArray = uc2decode(byteString);
|
||||
byteArray = ucs2decode(byteString);
|
||||
byteCount = byteArray.length;
|
||||
byteIndex = 0;
|
||||
List<Integer> codePoints = new ArrayList<Integer>();
|
||||
@@ -39,7 +39,7 @@ public class UTF8 {
|
||||
return ucs2encode(listToArray(codePoints));
|
||||
}
|
||||
|
||||
private static int[] uc2decode(String string) {
|
||||
private static int[] ucs2decode(String string) {
|
||||
int length = string.length();
|
||||
int[] output = new int[string.codePointCount(0, length)];
|
||||
int counter = 0;
|
||||
@@ -51,7 +51,7 @@ public class UTF8 {
|
||||
return output;
|
||||
}
|
||||
|
||||
private static String encodeCodePoint(int codePoint) {
|
||||
private static String encodeCodePoint(int codePoint) throws UTF8Exception {
|
||||
StringBuilder symbol = new StringBuilder();
|
||||
if ((codePoint & 0xFFFFFF80) == 0) {
|
||||
return symbol.append(Character.toChars(codePoint)).toString();
|
||||
@@ -59,6 +59,7 @@ public class UTF8 {
|
||||
if ((codePoint & 0xFFFFF800) == 0) {
|
||||
symbol.append(Character.toChars(((codePoint >> 6) & 0x1F) | 0xC0));
|
||||
} else if ((codePoint & 0xFFFF0000) == 0) {
|
||||
checkScalarValue(codePoint);
|
||||
symbol.append(Character.toChars(((codePoint >> 12) & 0x0F) | 0xE0));
|
||||
symbol.append(createByte(codePoint, 6));
|
||||
} else if ((codePoint & 0xFFE00000) == 0) {
|
||||
@@ -111,6 +112,7 @@ public class UTF8 {
|
||||
byte3 = readContinuationByte();
|
||||
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
|
||||
if (codePoint >= 0x0800) {
|
||||
checkScalarValue(codePoint);
|
||||
return codePoint;
|
||||
} else {
|
||||
throw new UTF8Exception("Invalid continuation byte");
|
||||
@@ -153,6 +155,15 @@ public class UTF8 {
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private static void checkScalarValue(int codePoint) throws UTF8Exception {
|
||||
if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
|
||||
throw new UTF8Exception(
|
||||
"Lone surrogate U+" + Integer.toHexString(codePoint).toUpperCase() +
|
||||
" is not a scalar value"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] listToArray(List<Integer> list) {
|
||||
int size = list.size();
|
||||
int[] array = new int[size];
|
||||
|
||||
Reference in New Issue
Block a user