Compare commits
5 Commits
main
...
swar_20250
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c3ab5ab381 | ||
![]() |
ff47d668df | ||
![]() |
69836ec2f3 | ||
![]() |
17cedf9b85 | ||
![]() |
d6c828e3b1 |
@ -20,7 +20,7 @@ import java.util.UUID;
|
||||
|
||||
import static com.alibaba.fastjson2.JSONFactory.*;
|
||||
import static com.alibaba.fastjson2.JSONWriter.Feature.*;
|
||||
import static com.alibaba.fastjson2.JSONWriterUTF8.containsEscaped;
|
||||
import static com.alibaba.fastjson2.JSONWriterUTF8.noneEscaped;
|
||||
import static com.alibaba.fastjson2.util.IOUtils.*;
|
||||
import static com.alibaba.fastjson2.util.JDKUtils.*;
|
||||
import static com.alibaba.fastjson2.util.TypeUtils.*;
|
||||
@ -75,7 +75,7 @@ class JSONWriterUTF16
|
||||
chars = new char[8192];
|
||||
}
|
||||
this.chars = chars;
|
||||
this.byteVectorQuote = this.useSingleQuote ? 0x2727_2727_2727_2727L : 0x2222_2222_2222_2222L;
|
||||
this.byteVectorQuote = this.useSingleQuote ? ~0x2727_2727_2727_2727L : ~0x2222_2222_2222_2222L;
|
||||
}
|
||||
|
||||
public final void writeNull() {
|
||||
@ -280,12 +280,8 @@ class JSONWriterUTF16
|
||||
int i = 0;
|
||||
final long vecQuote = this.byteVectorQuote;
|
||||
final int upperBound = (value.length - i) & ~7;
|
||||
for (; i < upperBound; i += 8) {
|
||||
long vec64 = getLongLE(value, i);
|
||||
if (containsEscaped(vec64, vecQuote)) {
|
||||
escape = true;
|
||||
break;
|
||||
}
|
||||
long vec64;
|
||||
for (; i < upperBound && noneEscaped(vec64 = getLongLE(value, i), vecQuote); i += 8) {
|
||||
IOUtils.putLongLE(chars, off, expand(vec64));
|
||||
IOUtils.putLongLE(chars, off + 4, expand(vec64 >>> 32));
|
||||
off += 8;
|
||||
@ -372,7 +368,7 @@ class JSONWriterUTF16
|
||||
if (i + 8 < char_len) {
|
||||
long v0 = getLongLE(value, i << 1);
|
||||
long v1 = getLongLE(value, (i + 4) << 1);
|
||||
if (((v0 | v1) & 0xFF00FF00FF00FF00L) == 0 && !containsEscaped((v0 << 8) | v1, vecQuote)) {
|
||||
if (((v0 | v1) & 0xFF00FF00FF00FF00L) == 0 && noneEscaped((v0 << 8) | v1, vecQuote)) {
|
||||
putLongLE(chars, off, v0);
|
||||
putLongLE(chars, off + 4, v1);
|
||||
i += 8;
|
||||
@ -2999,7 +2995,7 @@ class JSONWriterUTF16
|
||||
if (i + 8 < char_len) {
|
||||
long v0 = getLongLE(value, i);
|
||||
long v1 = getLongLE(value, i + 4);
|
||||
if (((v0 | v1) & 0xFF00FF00FF00FF00L) == 0 && !containsEscaped((v0 << 8) | v1, vecQuote)) {
|
||||
if (((v0 | v1) & 0xFF00FF00FF00FF00L) == 0 && noneEscaped((v0 << 8) | v1, vecQuote)) {
|
||||
putLongLE(chars, off, v0);
|
||||
putLongLE(chars, off + 4, v1);
|
||||
i += 8;
|
||||
|
@ -63,7 +63,7 @@ class JSONWriterUTF8
|
||||
bytes = new byte[8192];
|
||||
}
|
||||
this.bytes = bytes;
|
||||
this.byteVectorQuote = this.useSingleQuote ? 0x2727_2727_2727_2727L : 0x2222_2222_2222_2222L;
|
||||
this.byteVectorQuote = this.useSingleQuote ? ~0x2727_2727_2727_2727L : ~0x2222_2222_2222_2222L;
|
||||
}
|
||||
|
||||
public final void writeNull() {
|
||||
@ -468,7 +468,7 @@ class JSONWriterUTF8
|
||||
int i = 0;
|
||||
final int upperBound = (value.length - i) & ~7;
|
||||
for (; i < upperBound; i += 8) {
|
||||
if (containsEscaped(IOUtils.getLongLE(value, i), vecQuote)) {
|
||||
if (!noneEscaped(getLongUnaligned(value, i), vecQuote)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -498,24 +498,20 @@ class JSONWriterUTF8
|
||||
this.off = off + 1;
|
||||
}
|
||||
|
||||
static boolean containsEscaped(long v, long quote) {
|
||||
static boolean noneEscaped(long v, long quote) {
|
||||
/*
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
byte c = (byte) data;
|
||||
if (c == quote || c == '\\' || c < ' ') {
|
||||
return true;
|
||||
if (c == (byte) quote || c == '\\' || c < ' ') {
|
||||
return false;
|
||||
}
|
||||
data >>>= 8;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
*/
|
||||
long x22 = v ^ quote; // " -> 0x22, ' -> 0x27
|
||||
long x5c = v ^ 0x5C5C5C5C5C5C5C5CL;
|
||||
|
||||
x22 = (x22 - 0x0101010101010101L) & ~x22;
|
||||
x5c = (x5c - 0x0101010101010101L) & ~x5c;
|
||||
|
||||
return ((x22 | x5c | (0x7F7F7F7F7F7F7F7FL - v + 0x2020202020202020L) | v) & 0x8080808080808080L) != 0;
|
||||
return ((v + 0x6060606060606060L) & 0x8080808080808080L) == 0x8080808080808080L // all >= 32
|
||||
&& ((v ^ quote) + 0x0101010101010101L & 0x8080808080808080L) == 0x8080808080808080L // != quote
|
||||
&& ((v ^ 0xA3A3A3A3A3A3A3A3L) + 0x0101010101010101L & 0x8080808080808080L) == 0x8080808080808080L; // != '\\'
|
||||
}
|
||||
|
||||
protected final void writeStringLatin1BrowserSecure(byte[] values) {
|
||||
|
@ -1131,14 +1131,95 @@ public class JSONWriterUTF8Test {
|
||||
assertEquals("\\u0001", new String(bytes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecial1() {
|
||||
byte[] buf = new byte[] {'a', 'a', 'a', 'a', 'a', 'a', 'a', 31};
|
||||
assertEquals("\"aaaaaaa\\u001f\"", new String(JSON.toJSONBytes(new String(buf))));
|
||||
static boolean containsEscaped(long v, long quote) {
|
||||
/*
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
byte c = (byte) data;
|
||||
if (c == quote || c == '\\' || c < ' ') {
|
||||
return true;
|
||||
}
|
||||
data >>>= 8;
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
long x22 = v ^ quote; // " -> 0x22, ' -> 0x27
|
||||
long x5c = v ^ 0x5C5C5C5C5C5C5C5CL;
|
||||
|
||||
x22 = (x22 - 0x0101010101010101L) & ~x22;
|
||||
x5c = (x5c - 0x0101010101010101L) & ~x5c;
|
||||
|
||||
return ((x22 | x5c | (0x7F7F7F7F7F7F7F7FL - v + 0x2020202020202020L) | v) & 0x8080808080808080L) != 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecial_false() {
|
||||
long quote = 0x2222_2222_2222_2222L;
|
||||
byte[] escaped = new byte[32 + 2 + 128];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
buf[7] = (byte) i;
|
||||
assertTrue(JSONWriterUTF8.containsEscaped(IOUtils.getLongUnaligned(buf, 0), 0x2222_2222_2222_2222L));
|
||||
escaped[i] = (byte) i;
|
||||
}
|
||||
escaped[32] = (byte) quote;
|
||||
escaped[33] = '\\';
|
||||
for (int i = 0; i < 128; i++) {
|
||||
escaped[i + 32 + 2] = (byte) (i + 128);
|
||||
}
|
||||
|
||||
byte[] buf = new byte[8];
|
||||
for (byte c : escaped) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Arrays.fill(buf, (byte) 'a');
|
||||
buf[i] = c;
|
||||
long v = IOUtils.getLongUnaligned(buf, 0);
|
||||
assertTrue(containsEscaped(v, quote));
|
||||
assertFalse(JSONWriterUTF8.noneEscaped(v, ~quote));
|
||||
}
|
||||
}
|
||||
|
||||
quote = 0x2727_2727_2727_2727L;
|
||||
escaped[32] = (byte) quote;
|
||||
|
||||
for (byte c : escaped) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Arrays.fill(buf, (byte) 'a');
|
||||
buf[i] = c;
|
||||
long v = IOUtils.getLongUnaligned(buf, 0);
|
||||
assertTrue(containsEscaped(v, quote));
|
||||
assertFalse(JSONWriterUTF8.noneEscaped(v, ~quote));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecial_true() {
|
||||
long vectorQuote = 0x2222_2222_2222_2222L;
|
||||
byte quote = (byte) vectorQuote;
|
||||
byte[] buf = new byte[8];
|
||||
|
||||
for (int i = 33; i < 128; i++) {
|
||||
if (i == quote || i == '\\') {
|
||||
continue;
|
||||
}
|
||||
Arrays.fill(buf, (byte) i);
|
||||
long v = IOUtils.getLongUnaligned(buf, 0);
|
||||
assertTrue(JSONWriterUTF8.noneEscaped(v, ~vectorQuote));
|
||||
assertFalse(containsEscaped(v, vectorQuote));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecial_true_singleQuote() {
|
||||
long vectorQuote = 0x2727_2727_2727_2727L;
|
||||
byte quote = (byte) vectorQuote;
|
||||
byte[] buf = new byte[8];
|
||||
|
||||
for (int i = 33; i < 128; i++) {
|
||||
if (i == quote || i == '\\') {
|
||||
continue;
|
||||
}
|
||||
Arrays.fill(buf, (byte) i);
|
||||
long v = IOUtils.getLongUnaligned(buf, 0);
|
||||
assertTrue(JSONWriterUTF8.noneEscaped(v, ~vectorQuote));
|
||||
assertFalse(containsEscaped(v, vectorQuote));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user