github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/strconv/quote_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package strconv_test 6 7 import ( 8 . "strconv" 9 "testing" 10 "unicode" 11 ) 12 13 // Verify that our IsPrint agrees with unicode.IsPrint. 14 func TestIsPrint(t *testing.T) { 15 n := 0 16 for r := rune(0); r <= unicode.MaxRune; r++ { 17 if IsPrint(r) != unicode.IsPrint(r) { 18 t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r)) 19 n++ 20 if n > 10 { 21 return 22 } 23 } 24 } 25 } 26 27 // Verify that our IsGraphic agrees with unicode.IsGraphic. 28 func TestIsGraphic(t *testing.T) { 29 n := 0 30 for r := rune(0); r <= unicode.MaxRune; r++ { 31 if IsGraphic(r) != unicode.IsGraphic(r) { 32 t.Errorf("IsGraphic(%U)=%t incorrect", r, IsGraphic(r)) 33 n++ 34 if n > 10 { 35 return 36 } 37 } 38 } 39 } 40 41 type quoteTest struct { 42 in string 43 out string 44 ascii string 45 graphic string 46 } 47 48 var quotetests = []quoteTest{ 49 {"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`}, 50 {"\\", `"\\"`, `"\\"`, `"\\"`}, 51 {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`, `"abc\xffdef"`}, 52 {"\u263a", `"☺"`, `"\u263a"`, `"☺"`}, 53 {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`, `"\U0010ffff"`}, 54 {"\x04", `"\x04"`, `"\x04"`, `"\x04"`}, 55 // Some non-printable but graphic runes. Final column is double-quoted. 56 {"!\u00a0!\u2000!\u3000!", `"!\u00a0!\u2000!\u3000!"`, `"!\u00a0!\u2000!\u3000!"`, "\"!\u00a0!\u2000!\u3000!\""}, 57 } 58 59 func TestQuote(t *testing.T) { 60 for _, tt := range quotetests { 61 if out := Quote(tt.in); out != tt.out { 62 t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out) 63 } 64 if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out { 65 t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out) 66 } 67 } 68 } 69 70 func TestQuoteToASCII(t *testing.T) { 71 for _, tt := range quotetests { 72 if out := QuoteToASCII(tt.in); out != tt.ascii { 73 t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii) 74 } 75 if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii { 76 t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii) 77 } 78 } 79 } 80 81 func TestQuoteToGraphic(t *testing.T) { 82 for _, tt := range quotetests { 83 if out := QuoteToGraphic(tt.in); out != tt.graphic { 84 t.Errorf("QuoteToGraphic(%s) = %s, want %s", tt.in, out, tt.graphic) 85 } 86 if out := AppendQuoteToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic { 87 t.Errorf("AppendQuoteToGraphic(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic) 88 } 89 } 90 } 91 92 func BenchmarkQuote(b *testing.B) { 93 for i := 0; i < b.N; i++ { 94 Quote("\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v") 95 } 96 } 97 98 func BenchmarkQuoteRune(b *testing.B) { 99 for i := 0; i < b.N; i++ { 100 QuoteRune('\a') 101 } 102 } 103 104 var benchQuoteBuf []byte 105 106 func BenchmarkAppendQuote(b *testing.B) { 107 for i := 0; i < b.N; i++ { 108 benchQuoteBuf = AppendQuote(benchQuoteBuf[:0], "\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v") 109 } 110 } 111 112 var benchQuoteRuneBuf []byte 113 114 func BenchmarkAppendQuoteRune(b *testing.B) { 115 for i := 0; i < b.N; i++ { 116 benchQuoteRuneBuf = AppendQuoteRune(benchQuoteRuneBuf[:0], '\a') 117 } 118 } 119 120 type quoteRuneTest struct { 121 in rune 122 out string 123 ascii string 124 graphic string 125 } 126 127 var quoterunetests = []quoteRuneTest{ 128 {'a', `'a'`, `'a'`, `'a'`}, 129 {'\a', `'\a'`, `'\a'`, `'\a'`}, 130 {'\\', `'\\'`, `'\\'`, `'\\'`}, 131 {0xFF, `'ÿ'`, `'\u00ff'`, `'ÿ'`}, 132 {0x263a, `'☺'`, `'\u263a'`, `'☺'`}, 133 {0xfffd, `'�'`, `'\ufffd'`, `'�'`}, 134 {0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`, `'\U0010ffff'`}, 135 {0x0010ffff + 1, `'�'`, `'\ufffd'`, `'�'`}, 136 {0x04, `'\x04'`, `'\x04'`, `'\x04'`}, 137 // Some differences between graphic and printable. Note the last column is double-quoted. 138 {'\u00a0', `'\u00a0'`, `'\u00a0'`, "'\u00a0'"}, 139 {'\u2000', `'\u2000'`, `'\u2000'`, "'\u2000'"}, 140 {'\u3000', `'\u3000'`, `'\u3000'`, "'\u3000'"}, 141 } 142 143 func TestQuoteRune(t *testing.T) { 144 for _, tt := range quoterunetests { 145 if out := QuoteRune(tt.in); out != tt.out { 146 t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out) 147 } 148 if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out { 149 t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out) 150 } 151 } 152 } 153 154 func TestQuoteRuneToASCII(t *testing.T) { 155 for _, tt := range quoterunetests { 156 if out := QuoteRuneToASCII(tt.in); out != tt.ascii { 157 t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii) 158 } 159 if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii { 160 t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii) 161 } 162 } 163 } 164 165 func TestQuoteRuneToGraphic(t *testing.T) { 166 for _, tt := range quoterunetests { 167 if out := QuoteRuneToGraphic(tt.in); out != tt.graphic { 168 t.Errorf("QuoteRuneToGraphic(%U) = %s, want %s", tt.in, out, tt.graphic) 169 } 170 if out := AppendQuoteRuneToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic { 171 t.Errorf("AppendQuoteRuneToGraphic(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic) 172 } 173 } 174 } 175 176 type canBackquoteTest struct { 177 in string 178 out bool 179 } 180 181 var canbackquotetests = []canBackquoteTest{ 182 {"`", false}, 183 {string(rune(0)), false}, 184 {string(rune(1)), false}, 185 {string(rune(2)), false}, 186 {string(rune(3)), false}, 187 {string(rune(4)), false}, 188 {string(rune(5)), false}, 189 {string(rune(6)), false}, 190 {string(rune(7)), false}, 191 {string(rune(8)), false}, 192 {string(rune(9)), true}, // \t 193 {string(rune(10)), false}, 194 {string(rune(11)), false}, 195 {string(rune(12)), false}, 196 {string(rune(13)), false}, 197 {string(rune(14)), false}, 198 {string(rune(15)), false}, 199 {string(rune(16)), false}, 200 {string(rune(17)), false}, 201 {string(rune(18)), false}, 202 {string(rune(19)), false}, 203 {string(rune(20)), false}, 204 {string(rune(21)), false}, 205 {string(rune(22)), false}, 206 {string(rune(23)), false}, 207 {string(rune(24)), false}, 208 {string(rune(25)), false}, 209 {string(rune(26)), false}, 210 {string(rune(27)), false}, 211 {string(rune(28)), false}, 212 {string(rune(29)), false}, 213 {string(rune(30)), false}, 214 {string(rune(31)), false}, 215 {string(rune(0x7F)), false}, 216 {`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true}, 217 {`0123456789`, true}, 218 {`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true}, 219 {`abcdefghijklmnopqrstuvwxyz`, true}, 220 {`☺`, true}, 221 {"\x80", false}, 222 {"a\xe0\xa0z", false}, 223 {"\ufeffabc", false}, 224 {"a\ufeffz", false}, 225 } 226 227 func TestCanBackquote(t *testing.T) { 228 for _, tt := range canbackquotetests { 229 if out := CanBackquote(tt.in); out != tt.out { 230 t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out) 231 } 232 } 233 } 234 235 type unQuoteTest struct { 236 in string 237 out string 238 } 239 240 var unquotetests = []unQuoteTest{ 241 {`""`, ""}, 242 {`"a"`, "a"}, 243 {`"abc"`, "abc"}, 244 {`"☺"`, "☺"}, 245 {`"hello world"`, "hello world"}, 246 {`"\xFF"`, "\xFF"}, 247 {`"\377"`, "\377"}, 248 {`"\u1234"`, "\u1234"}, 249 {`"\U00010111"`, "\U00010111"}, 250 {`"\U0001011111"`, "\U0001011111"}, 251 {`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""}, 252 {`"'"`, "'"}, 253 254 {`'a'`, "a"}, 255 {`'☹'`, "☹"}, 256 {`'\a'`, "\a"}, 257 {`'\x10'`, "\x10"}, 258 {`'\377'`, "\377"}, 259 {`'\u1234'`, "\u1234"}, 260 {`'\U00010111'`, "\U00010111"}, 261 {`'\t'`, "\t"}, 262 {`' '`, " "}, 263 {`'\''`, "'"}, 264 {`'"'`, "\""}, 265 266 {"``", ``}, 267 {"`a`", `a`}, 268 {"`abc`", `abc`}, 269 {"`☺`", `☺`}, 270 {"`hello world`", `hello world`}, 271 {"`\\xFF`", `\xFF`}, 272 {"`\\377`", `\377`}, 273 {"`\\`", `\`}, 274 {"`\n`", "\n"}, 275 {"` `", ` `}, 276 {"` `", ` `}, 277 {"`a\rb`", "ab"}, 278 } 279 280 var misquoted = []string{ 281 ``, 282 `"`, 283 `"a`, 284 `"'`, 285 `b"`, 286 `"\"`, 287 `"\9"`, 288 `"\19"`, 289 `"\129"`, 290 `'\'`, 291 `'\9'`, 292 `'\19'`, 293 `'\129'`, 294 `'ab'`, 295 `"\x1!"`, 296 `"\U12345678"`, 297 `"\z"`, 298 "`", 299 "`xxx", 300 "`\"", 301 `"\'"`, 302 `'\"'`, 303 "\"\n\"", 304 "\"\\n\n\"", 305 "'\n'", 306 } 307 308 func TestUnquote(t *testing.T) { 309 for _, tt := range unquotetests { 310 if out, err := Unquote(tt.in); err != nil || out != tt.out { 311 t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out) 312 } 313 } 314 315 // run the quote tests too, backward 316 for _, tt := range quotetests { 317 if in, err := Unquote(tt.out); in != tt.in { 318 t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in) 319 } 320 } 321 322 for _, s := range misquoted { 323 if out, err := Unquote(s); out != "" || err != ErrSyntax { 324 t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax) 325 } 326 } 327 } 328 329 // Issue 23685: invalid UTF-8 should not go through the fast path. 330 func TestUnquoteInvalidUTF8(t *testing.T) { 331 tests := []struct { 332 in string 333 334 // one of: 335 want string 336 wantErr string 337 }{ 338 {in: `"foo"`, want: "foo"}, 339 {in: `"foo`, wantErr: "invalid syntax"}, 340 {in: `"` + "\xc0" + `"`, want: "\xef\xbf\xbd"}, 341 {in: `"a` + "\xc0" + `"`, want: "a\xef\xbf\xbd"}, 342 {in: `"\t` + "\xc0" + `"`, want: "\t\xef\xbf\xbd"}, 343 } 344 for i, tt := range tests { 345 got, err := Unquote(tt.in) 346 var gotErr string 347 if err != nil { 348 gotErr = err.Error() 349 } 350 if gotErr != tt.wantErr { 351 t.Errorf("%d. Unquote(%q) = err %v; want %q", i, tt.in, err, tt.wantErr) 352 } 353 if tt.wantErr == "" && err == nil && got != tt.want { 354 t.Errorf("%d. Unquote(%q) = %02x; want %02x", i, tt.in, []byte(got), []byte(tt.want)) 355 } 356 } 357 } 358 359 func BenchmarkUnquoteEasy(b *testing.B) { 360 for i := 0; i < b.N; i++ { 361 Unquote(`"Give me a rock, paper and scissors and I will move the world."`) 362 } 363 } 364 365 func BenchmarkUnquoteHard(b *testing.B) { 366 for i := 0; i < b.N; i++ { 367 Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`) 368 } 369 }