Skip to content

Commit ab961f1

Browse files
committed
More efficient validation of encoding of JSON strings
1 parent e1e1c97 commit ab961f1

File tree

3 files changed

+31
-31
lines changed
  • jsoniter-scala-core

3 files changed

+31
-31
lines changed

jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3549,7 +3549,7 @@ final class JsonReader private[jsoniter_scala](
35493549
} else if (remaining > 5) {
35503550
val ch1 = readEscapedUnicode(pos + 2, buf)
35513551
charBuf(i) = ch1
3552-
if (ch1 < 0xD800 || ch1 > 0xDFFF) parseEncodedString(i + 1, lim, charBuf, pos + 6)
3552+
if ((ch1 & 0xF800) != 0xD800) parseEncodedString(i + 1, lim, charBuf, pos + 6)
35533553
else if (remaining > 11) {
35543554
if (buf(pos + 6) != '\\') escapeSequenceError(pos + 6)
35553555
if (buf(pos + 7) != 'u') escapeSequenceError(pos + 7)
@@ -3560,24 +3560,24 @@ final class JsonReader private[jsoniter_scala](
35603560
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
35613561
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
35623562
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
3563-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
3563+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
35643564
if (remaining > 1) {
35653565
val b2 = buf(pos + 1)
35663566
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
35673567
charBuf(i) = (b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
35683568
parseEncodedString(i + 1, lim, charBuf, pos + 2)
35693569
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
3570-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
3570+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
35713571
if (remaining > 2) {
35723572
val b2 = buf(pos + 1)
35733573
val b3 = buf(pos + 2)
35743574
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
35753575
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
3576-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
3576+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
35773577
charBuf(i) = ch
35783578
parseEncodedString(i + 1, lim, charBuf, pos + 3)
35793579
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
3580-
} else if ((b1 >> 3) == -2) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
3580+
} else if ((b1 & 0xF8) == 0xF0) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
35813581
if (remaining > 3) {
35823582
val b2 = buf(pos + 1)
35833583
val b3 = buf(pos + 2)
@@ -3600,7 +3600,7 @@ final class JsonReader private[jsoniter_scala](
36003600
if (remaining > 0) {
36013601
val b1 = buf(pos)
36023602
if (b1 >= 0) {
3603-
if (b1 == '"') decodeError("illegal character", pos)
3603+
if (b1 == '"') characterError(pos)
36043604
else if (b1 != '\\') { // 0aaaaaaa (UTF-8 byte) -> 000000000aaaaaaa (UTF-16 char)
36053605
if (b1 < ' ') unescapedControlCharacterError(pos)
36063606
head = pos + 1
@@ -3622,29 +3622,29 @@ final class JsonReader private[jsoniter_scala](
36223622
}
36233623
} else if (remaining > 5) {
36243624
val ch = readEscapedUnicode(pos + 2, buf)
3625-
if (ch >= 0xD800 && ch <= 0xDFFF) surrogateCharacterError(pos + 5)
3625+
if ((ch & 0xF800) == 0xD800) surrogateCharacterError(pos + 5)
36263626
head = pos + 6
36273627
ch
36283628
} else parseChar(loadMoreOrError(pos))
36293629
} else parseChar(loadMoreOrError(pos))
3630-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
3630+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
36313631
if (remaining > 1) {
36323632
val b2 = buf(pos + 1)
36333633
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
36343634
head = pos + 2
36353635
(b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
36363636
} else parseChar(loadMoreOrError(pos))
3637-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
3637+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
36383638
if (remaining > 2) {
36393639
val b2 = buf(pos + 1)
36403640
val b3 = buf(pos + 2)
36413641
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
36423642
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
3643-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
3643+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
36443644
head = pos + 3
36453645
ch
36463646
} else parseChar(loadMoreOrError(pos))
3647-
} else if ((b1 >> 3) == -2) surrogateCharacterError(pos + 3)
3647+
} else if ((b1 & 0xF8) == 0xF0) surrogateCharacterError(pos + 3)
36483648
else malformedBytesError(b1, pos)
36493649
} else parseChar(loadMoreOrError(pos))
36503650
}

jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4025,7 +4025,7 @@ final class JsonReader private[jsoniter_scala](
40254025
} else if (remaining > 5) {
40264026
val ch1 = readEscapedUnicode(pos + 2, buf)
40274027
charBuf(i) = ch1
4028-
if (ch1 < 0xD800 || ch1 > 0xDFFF) parseEncodedString(i + 1, lim, charBuf, pos + 6)
4028+
if ((ch1 & 0xF800) != 0xD800) parseEncodedString(i + 1, lim, charBuf, pos + 6)
40294029
else if (remaining > 11) {
40304030
if (buf(pos + 6) != '\\') escapeSequenceError(pos + 6)
40314031
if (buf(pos + 7) != 'u') escapeSequenceError(pos + 7)
@@ -4036,24 +4036,24 @@ final class JsonReader private[jsoniter_scala](
40364036
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
40374037
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
40384038
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4039-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
4039+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
40404040
if (remaining > 1) {
40414041
val b2 = buf(pos + 1)
40424042
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
40434043
charBuf(i) = (b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
40444044
parseEncodedString(i + 1, lim, charBuf, pos + 2)
40454045
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4046-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
4046+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
40474047
if (remaining > 2) {
40484048
val b2 = buf(pos + 1)
40494049
val b3 = buf(pos + 2)
40504050
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
40514051
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
4052-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
4052+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
40534053
charBuf(i) = ch
40544054
parseEncodedString(i + 1, lim, charBuf, pos + 3)
40554055
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4056-
} else if ((b1 >> 3) == -2) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
4056+
} else if ((b1 & 0xF8) == 0xF0) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
40574057
if (remaining > 3) {
40584058
val b2 = buf(pos + 1)
40594059
val b3 = buf(pos + 2)
@@ -4098,29 +4098,29 @@ final class JsonReader private[jsoniter_scala](
40984098
}
40994099
} else if (remaining > 5) {
41004100
val ch = readEscapedUnicode(pos + 2, buf)
4101-
if (ch >= 0xD800 && ch <= 0xDFFF) surrogateCharacterError(pos + 5)
4101+
if ((ch & 0xF800) == 0xD800) surrogateCharacterError(pos + 5)
41024102
head = pos + 6
41034103
ch
41044104
} else parseChar(loadMoreOrError(pos))
41054105
} else parseChar(loadMoreOrError(pos))
4106-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
4106+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
41074107
if (remaining > 1) {
41084108
val b2 = buf(pos + 1)
41094109
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
41104110
head = pos + 2
41114111
(b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
41124112
} else parseChar(loadMoreOrError(pos))
4113-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
4113+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
41144114
if (remaining > 2) {
41154115
val b2 = buf(pos + 1)
41164116
val b3 = buf(pos + 2)
41174117
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
41184118
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
4119-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
4119+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
41204120
head = pos + 3
41214121
ch
41224122
} else parseChar(loadMoreOrError(pos))
4123-
} else if ((b1 >> 3) == -2) surrogateCharacterError(pos + 3)
4123+
} else if ((b1 & 0xF8) == 0xF0) surrogateCharacterError(pos + 3)
41244124
else malformedBytesError(b1, pos)
41254125
} else parseChar(loadMoreOrError(pos))
41264126
}

jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4021,7 +4021,7 @@ final class JsonReader private[jsoniter_scala](
40214021
} else if (remaining > 5) {
40224022
val ch1 = readEscapedUnicode(pos + 2, buf)
40234023
charBuf(i) = ch1
4024-
if (ch1 < 0xD800 || ch1 > 0xDFFF) parseEncodedString(i + 1, lim, charBuf, pos + 6)
4024+
if ((ch1 & 0xF800) != 0xD800) parseEncodedString(i + 1, lim, charBuf, pos + 6)
40254025
else if (remaining > 11) {
40264026
if (buf(pos + 6) != '\\') escapeSequenceError(pos + 6)
40274027
if (buf(pos + 7) != 'u') escapeSequenceError(pos + 7)
@@ -4032,24 +4032,24 @@ final class JsonReader private[jsoniter_scala](
40324032
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
40334033
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
40344034
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4035-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
4035+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
40364036
if (remaining > 1) {
40374037
val b2 = buf(pos + 1)
40384038
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
40394039
charBuf(i) = (b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
40404040
parseEncodedString(i + 1, lim, charBuf, pos + 2)
40414041
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4042-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
4042+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
40434043
if (remaining > 2) {
40444044
val b2 = buf(pos + 1)
40454045
val b3 = buf(pos + 2)
40464046
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
40474047
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
4048-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
4048+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
40494049
charBuf(i) = ch
40504050
parseEncodedString(i + 1, lim, charBuf, pos + 3)
40514051
} else parseEncodedString(i, lim, charBuf, loadMoreOrError(pos))
4052-
} else if ((b1 >> 3) == -2) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
4052+
} else if ((b1 & 0xF8) == 0xF0) { // 11110ddd 10ddcccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> 110110uuuuccccbb 110111bbbbaaaaaa (UTF-16 chars), where uuuu = ddddd - 1
40534053
if (remaining > 3) {
40544054
val b2 = buf(pos + 1)
40554055
val b3 = buf(pos + 2)
@@ -4094,29 +4094,29 @@ final class JsonReader private[jsoniter_scala](
40944094
}
40954095
} else if (remaining > 5) {
40964096
val ch = readEscapedUnicode(pos + 2, buf)
4097-
if (ch >= 0xD800 && ch <= 0xDFFF) surrogateCharacterError(pos + 5)
4097+
if ((ch & 0xF800) == 0xD800) surrogateCharacterError(pos + 5)
40984098
head = pos + 6
40994099
ch
41004100
} else parseChar(loadMoreOrError(pos))
41014101
} else parseChar(loadMoreOrError(pos))
4102-
} else if ((b1 >> 5) == -2) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
4102+
} else if ((b1 & 0xE0) == 0xC0) { // 110bbbbb 10aaaaaa (UTF-8 bytes) -> 00000bbbbbaaaaaa (UTF-16 char)
41034103
if (remaining > 1) {
41044104
val b2 = buf(pos + 1)
41054105
if ((b1 & 0x1E) == 0 || (b2 & 0xC0) != 0x80) malformedBytesError(b1, b2, pos)
41064106
head = pos + 2
41074107
(b1 << 6 ^ b2 ^ 0xF80).toChar // 0xF80 == 0xC0.toByte << 6 ^ 0x80.toByte
41084108
} else parseChar(loadMoreOrError(pos))
4109-
} else if ((b1 >> 4) == -2) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
4109+
} else if ((b1 & 0xF0) == 0xE0) { // 1110cccc 10bbbbbb 10aaaaaa (UTF-8 bytes) -> ccccbbbbbbaaaaaa (UTF-16 char)
41104110
if (remaining > 2) {
41114111
val b2 = buf(pos + 1)
41124112
val b3 = buf(pos + 2)
41134113
val ch = (b1 << 12 ^ b2 << 6 ^ b3 ^ 0xFFFE1F80).toChar // 0xFFFE1F80 == 0xE0.toByte << 12 ^ 0x80.toByte << 6 ^ 0x80.toByte
41144114
if ((b1 == -32 && (b2 & 0xE0) == 0x80) || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 ||
4115-
(ch >= 0xD800 && ch <= 0xDFFF)) malformedBytesError(b1, b2, b3, pos)
4115+
(ch & 0xF800) == 0xD800) malformedBytesError(b1, b2, b3, pos)
41164116
head = pos + 3
41174117
ch
41184118
} else parseChar(loadMoreOrError(pos))
4119-
} else if ((b1 >> 3) == -2) surrogateCharacterError(pos + 3)
4119+
} else if ((b1 & 0xF8) == 0xF0) surrogateCharacterError(pos + 3)
41204120
else malformedBytesError(b1, pos)
41214121
} else parseChar(loadMoreOrError(pos))
41224122
}

0 commit comments

Comments
 (0)