Skip to content

Commit 41497b7

Browse files
authored
Fix canonical json utf-16 surrogate pair detection logic (#423)
1 parent 2aa5890 commit 41497b7

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

json.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ func compactUnicodeEscape(input, output []byte, index int) ([]byte, int) {
329329
// Otherwise the character only needs escaping if it is a QUOTE '"' or BACKSLASH '\\'.
330330
output = append(output, '\\', byte(c))
331331
} else if utf16.IsSurrogate(c) {
332-
if input[index] != '\\' && input[index+1] != 'u' {
332+
if input[index] != '\\' || input[index+1] != 'u' {
333333
return output, index
334334
}
335335
index += 2 // skip the \u"

json_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ func TestCompactUnicodeEscapeWithUTF16Surrogate(t *testing.T) {
125125
}
126126
}
127127

128+
func TestCompactUnicodeEscapeWithBadUTF16Surrogate(t *testing.T) {
129+
input := []byte(`\ud83d\zdc08`)
130+
output, n := compactUnicodeEscape(input[2:], nil, 0)
131+
if n != 4 {
132+
t.Fatalf("should have consumed 4 bytes but consumed %d bytes", n)
133+
}
134+
if string(output) != "" {
135+
t.Fatalf("expected output to be empty")
136+
}
137+
138+
input = []byte(`\ud83d udc08`)
139+
output, n = compactUnicodeEscape(input[2:], nil, 0)
140+
if n != 4 {
141+
t.Fatalf("should have consumed 4 bytes but consumed %d bytes", n)
142+
}
143+
if string(output) != "" {
144+
t.Fatalf("expected output to be empty")
145+
}
146+
}
147+
128148
func testReadHex(t *testing.T, input string, want rune) {
129149
got := readHexDigits([]byte(input))
130150
if want != got {

0 commit comments

Comments
 (0)