unescapeToUTF8 unescapes the single escape sequence starting at 'in' into 'out' and returns how many characters were consumed from 'in' and emitted into 'out'. If a valid escape sequence does not appear as a prefix of 'in', (-1, -1) to signal the error.
(in, out []byte)
| 170 | // how many characters were consumed from 'in' and emitted into 'out'. |
| 171 | // If a valid escape sequence does not appear as a prefix of 'in', (-1, -1) to signal the error. |
| 172 | func unescapeToUTF8(in, out []byte) (inLen int, outLen int) { |
| 173 | if len(in) < 2 || in[0] != '\\' { |
| 174 | // Invalid escape due to insufficient characters for any escape or no initial backslash |
| 175 | return -1, -1 |
| 176 | } |
| 177 | |
| 178 | // https://tools.ietf.org/html/rfc7159#section-7 |
| 179 | switch e := in[1]; e { |
| 180 | case '"', '\\', '/', 'b', 'f', 'n', 'r', 't': |
| 181 | // Valid basic 2-character escapes (use lookup table) |
| 182 | out[0] = backslashCharEscapeTable[e] |
| 183 | return 2, 1 |
| 184 | case 'u': |
| 185 | // Unicode escape |
| 186 | if r, inLen := decodeUnicodeEscape(in); inLen == -1 { |
| 187 | // Invalid Unicode escape |
| 188 | return -1, -1 |
| 189 | } else { |
| 190 | // Valid Unicode escape; re-encode as UTF8 |
| 191 | outLen := utf8.EncodeRune(out, r) |
| 192 | return inLen, outLen |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | return -1, -1 |
| 197 | } |
| 198 | |
| 199 | // unescape unescapes the string contained in 'in' and returns it as a slice. |
| 200 | // If 'in' contains no escaped characters: |