unescapeBytes takes a quoted string, unquotes, and unescapes it as bytes.
(value string)
| 56 | |
| 57 | // unescapeBytes takes a quoted string, unquotes, and unescapes it as bytes. |
| 58 | func unescapeBytes(value string) (string, error) { |
| 59 | // All strings normalize newlines to the \n representation. |
| 60 | value = newlineNormalizer.Replace(value) |
| 61 | n := len(value) |
| 62 | |
| 63 | // Nothing to unescape / decode. |
| 64 | if n < 2 { |
| 65 | return value, fmt.Errorf("unable to unescape string") |
| 66 | } |
| 67 | |
| 68 | // Quoted string of some form, must have same first and last char. |
| 69 | if value[0] != value[n-1] || (value[0] != '"' && value[0] != '\'') { |
| 70 | return value, fmt.Errorf("unable to unescape string") |
| 71 | } |
| 72 | |
| 73 | value = value[1 : n-1] |
| 74 | |
| 75 | // The string contains escape characters. |
| 76 | // The following logic is adapted from `strconv/quote.go` |
| 77 | var runeTmp [utf8.UTFMax]byte |
| 78 | size := 3 * uint64(n) / 2 |
| 79 | if size >= math.MaxInt { |
| 80 | return "", fmt.Errorf("too large string") |
| 81 | } |
| 82 | buf := new(strings.Builder) |
| 83 | buf.Grow(int(size)) |
| 84 | for len(value) > 0 { |
| 85 | c, multibyte, rest, err := unescapeByteChar(value) |
| 86 | if err != nil { |
| 87 | return "", err |
| 88 | } |
| 89 | value = rest |
| 90 | if c < utf8.RuneSelf || !multibyte { |
| 91 | buf.WriteByte(byte(c)) |
| 92 | } else { |
| 93 | n := utf8.EncodeRune(runeTmp[:], c) |
| 94 | buf.Write(runeTmp[:n]) |
| 95 | } |
| 96 | } |
| 97 | return buf.String(), nil |
| 98 | } |
| 99 | |
| 100 | // unescapeChar takes a string input and returns the following info: |
| 101 | // |
no test coverage detected
searching dependent graphs…