SanitizeUTF8String returns a copy of the string s with each run of invalid or unprintable UTF-8 byte sequences replaced by its hexadecimal representation string.
(s string)
| 179 | // SanitizeUTF8String returns a copy of the string s with each run of invalid or unprintable UTF-8 byte sequences |
| 180 | // replaced by its hexadecimal representation string. |
| 181 | func SanitizeUTF8String(s string) string { |
| 182 | var b strings.Builder |
| 183 | |
| 184 | for i, c := range s { |
| 185 | if c != utf8.RuneError { |
| 186 | continue |
| 187 | } |
| 188 | |
| 189 | _, wid := utf8.DecodeRuneInString(s[i:]) |
| 190 | if wid == 1 { |
| 191 | b.Grow(len(s)) |
| 192 | _, _ = b.WriteString(s[:i]) |
| 193 | s = s[i:] |
| 194 | break |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | // Fast path for unchanged input |
| 199 | if b.Cap() == 0 { // didn't call b.Grow above |
| 200 | return s |
| 201 | } |
| 202 | |
| 203 | for i := 0; i < len(s); { |
| 204 | c := s[i] |
| 205 | // U+0000-U+0019 are control characters |
| 206 | if 0x20 <= c && c < utf8.RuneSelf { |
| 207 | i++ |
| 208 | _ = b.WriteByte(c) |
| 209 | continue |
| 210 | } |
| 211 | _, wid := utf8.DecodeRuneInString(s[i:]) |
| 212 | if wid == 1 { |
| 213 | i++ |
| 214 | _, _ = fmt.Fprintf(&b, "\\x%02x", c) |
| 215 | continue |
| 216 | } |
| 217 | _, _ = b.WriteString(s[i : i+wid]) |
| 218 | i += wid |
| 219 | } |
| 220 | |
| 221 | return b.String() |
| 222 | } |
| 223 | |
| 224 | func FormatMaximumSQLResultSizeMessage(limit int64) string { |
| 225 | return fmt.Sprintf("Output of query exceeds max allowed output size of %dMB", limit/1024/1024) |