Unescape takes a quoted string, unquotes, and unescapes it.
(value string)
| 13 | |
| 14 | // Unescape takes a quoted string, unquotes, and unescapes it. |
| 15 | func unescape(value string) (string, error) { |
| 16 | // All strings normalize newlines to the \n representation. |
| 17 | value = newlineNormalizer.Replace(value) |
| 18 | n := len(value) |
| 19 | |
| 20 | // Nothing to unescape / decode. |
| 21 | if n < 2 { |
| 22 | return value, fmt.Errorf("unable to unescape string") |
| 23 | } |
| 24 | |
| 25 | // Quoted string of some form, must have same first and last char. |
| 26 | if value[0] != value[n-1] || (value[0] != '"' && value[0] != '\'') { |
| 27 | return value, fmt.Errorf("unable to unescape string") |
| 28 | } |
| 29 | |
| 30 | value = value[1 : n-1] |
| 31 | |
| 32 | // The string contains escape characters. |
| 33 | // The following logic is adapted from `strconv/quote.go` |
| 34 | var runeTmp [utf8.UTFMax]byte |
| 35 | size := 3 * uint64(n) / 2 |
| 36 | if size >= math.MaxInt { |
| 37 | return "", fmt.Errorf("too large string") |
| 38 | } |
| 39 | buf := new(strings.Builder) |
| 40 | buf.Grow(int(size)) |
| 41 | for len(value) > 0 { |
| 42 | c, multibyte, rest, err := unescapeChar(value) |
| 43 | if err != nil { |
| 44 | return "", err |
| 45 | } |
| 46 | value = rest |
| 47 | if c < utf8.RuneSelf || !multibyte { |
| 48 | buf.WriteByte(byte(c)) |
| 49 | } else { |
| 50 | n := utf8.EncodeRune(runeTmp[:], c) |
| 51 | buf.Write(runeTmp[:n]) |
| 52 | } |
| 53 | } |
| 54 | return buf.String(), nil |
| 55 | } |
| 56 | |
| 57 | // unescapeBytes takes a quoted string, unquotes, and unescapes it as bytes. |
| 58 | func unescapeBytes(value string) (string, error) { |
no test coverage detected
searching dependent graphs…