Skip to content

Commit 5c4247b

Browse files
committed
Equivalent change to google/jsonnet#898
1 parent bd9f761 commit 5c4247b

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

internal/parser/string_util.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"bytes"
2121
"encoding/hex"
2222
"fmt"
23+
"unicode/utf16"
2324
"unicode/utf8"
2425

2526
"github.com/google/go-jsonnet/ast"
@@ -67,9 +68,26 @@ func StringUnescape(loc *ast.LocationRange, s string) (string, error) {
6768
if err != nil {
6869
return "", errors.MakeStaticError(fmt.Sprintf("Unicode escape sequence was malformed: %s", s[0:4]), *loc)
6970
}
70-
code := int(codeBytes[0])*256 + int(codeBytes[1])
71-
buf.WriteRune(rune(code))
7271
i += 4
72+
code := rune(int(codeBytes[0])*256 + int(codeBytes[1]))
73+
if utf16.IsSurrogate(code) {
74+
highSurrogate := code
75+
if i+6 /*\uXXXX*/ > len(s) {
76+
return "", errors.MakeStaticError("Truncated unicode surrogate pair escape sequence in string literal.", *loc)
77+
}
78+
if s[i:i+2] != "\\u" {
79+
return "", errors.MakeStaticError("Unicode surrogate pair escape sequence missing low surrogate in string literal.", *loc)
80+
}
81+
i += 2
82+
codeBytes, err := hex.DecodeString(s[i : i+4])
83+
if err != nil {
84+
return "", errors.MakeStaticError(fmt.Sprintf("Unicode low surrogate escape sequence was malformed: %s", s[0:4]), *loc)
85+
}
86+
i += 4
87+
lowSurrogate := rune(int(codeBytes[0])*256 + int(codeBytes[1]))
88+
code = utf16.DecodeRune(highSurrogate, lowSurrogate)
89+
}
90+
buf.WriteRune(code)
7391
default:
7492
return "", errors.MakeStaticError(fmt.Sprintf("Unknown escape sequence in string literal: \\%c", r2), *loc)
7593
}

0 commit comments

Comments
 (0)