@@ -20,6 +20,7 @@ import (
20
20
"bytes"
21
21
"encoding/hex"
22
22
"fmt"
23
+ "unicode/utf16"
23
24
"unicode/utf8"
24
25
25
26
"github.com/google/go-jsonnet/ast"
@@ -67,9 +68,26 @@ func StringUnescape(loc *ast.LocationRange, s string) (string, error) {
67
68
if err != nil {
68
69
return "" , errors .MakeStaticError (fmt .Sprintf ("Unicode escape sequence was malformed: %s" , s [0 :4 ]), * loc )
69
70
}
70
- code := int (codeBytes [0 ])* 256 + int (codeBytes [1 ])
71
- buf .WriteRune (rune (code ))
72
71
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 )
73
91
default :
74
92
return "" , errors .MakeStaticError (fmt .Sprintf ("Unknown escape sequence in string literal: \\ %c" , r2 ), * loc )
75
93
}
0 commit comments