diff --git a/json.go b/json.go index 274a89a8..07f5680c 100644 --- a/json.go +++ b/json.go @@ -329,7 +329,7 @@ func compactUnicodeEscape(input, output []byte, index int) ([]byte, int) { // Otherwise the character only needs escaping if it is a QUOTE '"' or BACKSLASH '\\'. output = append(output, '\\', byte(c)) } else if utf16.IsSurrogate(c) { - if input[index] != '\\' && input[index+1] != 'u' { + if input[index] != '\\' || input[index+1] != 'u' { return output, index } index += 2 // skip the \u" diff --git a/json_test.go b/json_test.go index 74be24dc..202d7c4b 100644 --- a/json_test.go +++ b/json_test.go @@ -125,6 +125,26 @@ func TestCompactUnicodeEscapeWithUTF16Surrogate(t *testing.T) { } } +func TestCompactUnicodeEscapeWithBadUTF16Surrogate(t *testing.T) { + input := []byte(`\ud83d\zdc08`) + output, n := compactUnicodeEscape(input[2:], nil, 0) + if n != 4 { + t.Fatalf("should have consumed 4 bytes but consumed %d bytes", n) + } + if string(output) != "" { + t.Fatalf("expected output to be empty") + } + + input = []byte(`\ud83d udc08`) + output, n = compactUnicodeEscape(input[2:], nil, 0) + if n != 4 { + t.Fatalf("should have consumed 4 bytes but consumed %d bytes", n) + } + if string(output) != "" { + t.Fatalf("expected output to be empty") + } +} + func testReadHex(t *testing.T, input string, want rune) { got := readHexDigits([]byte(input)) if want != got {