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)
| 99 | // how many characters were consumed from 'in' and emitted into 'out'. |
| 100 | // If a valid escape sequence does not appear as a prefix of 'in', (-1, -1) to signal the error. |
| 101 | func unescapeToUTF8(in, out []byte) (inLen int, outLen int) { |
| 102 | if len(in) < 2 || in[0] != '\\' { |
| 103 | // Invalid escape due to insufficient characters for any escape or no initial backslash |
| 104 | return -1, -1 |
| 105 | } |
| 106 | |
| 107 | // https://tools.ietf.org/html/rfc7159#section-7 |
| 108 | switch e := in[1]; e { |
| 109 | case '"', '\\', '/', 'b', 'f', 'n', 'r', 't': |
| 110 | // Valid basic 2-character escapes (use lookup table) |
| 111 | out[0] = backslashCharEscapeTable[e] |
| 112 | return 2, 1 |
| 113 | case 'u': |
| 114 | // Unicode escape |
| 115 | if r, inLen := decodeUnicodeEscape(in); inLen == -1 { |
| 116 | // Invalid Unicode escape |
| 117 | return -1, -1 |
| 118 | } else { |
| 119 | // Valid Unicode escape; re-encode as UTF8 |
| 120 | outLen := utf8.EncodeRune(out, r) |
| 121 | return inLen, outLen |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | return -1, -1 |
| 126 | } |
| 127 | |
| 128 | // unescape unescapes the string contained in 'in' and returns it as a slice. |
| 129 | // If 'in' contains no escaped characters: |
searching dependent graphs…