MCPcopy Create free account
hub / github.com/buger/jsonparser / decodeUnicodeEscape

Function decodeUnicodeEscape

escape.go:115–155  ·  view source on GitHub ↗
(in []byte)

Source from the content-addressed store, hash-verified

113}
114
115func decodeUnicodeEscape(in []byte) (rune, int) {
116 if r, ok := decodeSingleUnicodeEscape(in); !ok {
117 // Invalid Unicode escape
118 return utf8.RuneError, -1
119 } else if !isUTF16EncodedRune(r) {
120 // Valid Unicode escape in Basic Multilingual Plane.
121 // Note: a single \uXXXX escape produces r in [0, 0xFFFF], so r is always
122 // within the BMP. The former r <= basicMultilingualPlaneOffset guard was
123 // tautological and has been removed — the real discriminator is whether r
124 // falls in the UTF-16 surrogate range.
125 return r, 6
126 } else if r >= lowSurrogateOffset {
127 // Lone low surrogate (0xDC00-0xDFFF) with no preceding high surrogate.
128 // Per RFC 8259/WHATWG a lone surrogate in a JSON string is malformed;
129 // match encoding/json by substituting U+FFFD and consuming only the 6
130 // bytes of this escape.
131 return utf8.RuneError, 6
132 } else if len(in) < 8 || in[6] != '\\' || in[7] != 'u' {
133 // Lone high surrogate (0xD800-0xDBFF): the high-surrogate escape is not
134 // followed by a "\u" low-surrogate escape. decodeSingleUnicodeEscape
135 // assumes the \u prefix and reads hex at fixed offsets, so without this
136 // guard it would misread whatever bytes follow (e.g. the literal "A7FA"
137 // after "\uDB29") as a low surrogate and synthesize a bogus code point
138 // (DEFECT-260727-SNGT). Substitute U+FFFD and consume only the 6 bytes
139 // of the high surrogate, matching encoding/json.
140 return utf8.RuneError, 6
141 } else if r2, ok := decodeSingleUnicodeEscape(in[6:]); !ok {
142 // A "\u" follows the high surrogate but the low-surrogate escape is
143 // itself malformed (truncated / bad hex) — the whole escape is broken.
144 return utf8.RuneError, -1
145 } else if r2 < lowSurrogateOffset || r2 > basicMultilingualPlaneReservedOffset {
146 // The following "\uXXXX" is not a valid low surrogate (0xDC00-0xDFFF):
147 // e.g. a BMP codepoint or another high surrogate. Treat the first escape
148 // as a lone high surrogate → U+FFFD, consuming 6 bytes; the following
149 // escape is reprocessed by the caller.
150 return utf8.RuneError, 6
151 } else {
152 // Valid UTF16 surrogate pair
153 return combineUTF16Surrogates(r, r2), 12
154 }
155}
156
157// backslashCharEscapeTable: when '\X' is found for some byte X, it is to be replaced with backslashCharEscapeTable[X]
158var backslashCharEscapeTable = [...]byte{

Calls 3

isUTF16EncodedRuneFunction · 0.85
combineUTF16SurrogatesFunction · 0.85