github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/archive/tar/strconv_test.go (about) 1 // Copyright 2016 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 tar 6 7 import ( 8 "math" 9 "strings" 10 "testing" 11 "time" 12 ) 13 14 func TestFitsInBase256(t *testing.T) { 15 vectors := []struct { 16 in int64 17 width int 18 ok bool 19 }{ 20 {+1, 8, true}, 21 {0, 8, true}, 22 {-1, 8, true}, 23 {1 << 56, 8, false}, 24 {(1 << 56) - 1, 8, true}, 25 {-1 << 56, 8, true}, 26 {(-1 << 56) - 1, 8, false}, 27 {121654, 8, true}, 28 {-9849849, 8, true}, 29 {math.MaxInt64, 9, true}, 30 {0, 9, true}, 31 {math.MinInt64, 9, true}, 32 {math.MaxInt64, 12, true}, 33 {0, 12, true}, 34 {math.MinInt64, 12, true}, 35 } 36 37 for _, v := range vectors { 38 ok := fitsInBase256(v.width, v.in) 39 if ok != v.ok { 40 t.Errorf("fitsInBase256(%d, %d): got %v, want %v", v.in, v.width, ok, v.ok) 41 } 42 } 43 } 44 45 func TestParseNumeric(t *testing.T) { 46 vectors := []struct { 47 in string 48 want int64 49 ok bool 50 }{ 51 // Test base-256 (binary) encoded values. 52 {"", 0, true}, 53 {"\x80", 0, true}, 54 {"\x80\x00", 0, true}, 55 {"\x80\x00\x00", 0, true}, 56 {"\xbf", (1 << 6) - 1, true}, 57 {"\xbf\xff", (1 << 14) - 1, true}, 58 {"\xbf\xff\xff", (1 << 22) - 1, true}, 59 {"\xff", -1, true}, 60 {"\xff\xff", -1, true}, 61 {"\xff\xff\xff", -1, true}, 62 {"\xc0", -1 * (1 << 6), true}, 63 {"\xc0\x00", -1 * (1 << 14), true}, 64 {"\xc0\x00\x00", -1 * (1 << 22), true}, 65 {"\x87\x76\xa2\x22\xeb\x8a\x72\x61", 537795476381659745, true}, 66 {"\x80\x00\x00\x00\x07\x76\xa2\x22\xeb\x8a\x72\x61", 537795476381659745, true}, 67 {"\xf7\x76\xa2\x22\xeb\x8a\x72\x61", -615126028225187231, true}, 68 {"\xff\xff\xff\xff\xf7\x76\xa2\x22\xeb\x8a\x72\x61", -615126028225187231, true}, 69 {"\x80\x7f\xff\xff\xff\xff\xff\xff\xff", math.MaxInt64, true}, 70 {"\x80\x80\x00\x00\x00\x00\x00\x00\x00", 0, false}, 71 {"\xff\x80\x00\x00\x00\x00\x00\x00\x00", math.MinInt64, true}, 72 {"\xff\x7f\xff\xff\xff\xff\xff\xff\xff", 0, false}, 73 {"\xf5\xec\xd1\xc7\x7e\x5f\x26\x48\x81\x9f\x8f\x9b", 0, false}, 74 75 // Test base-8 (octal) encoded values. 76 {"0000000\x00", 0, true}, 77 {" \x0000000\x00", 0, true}, 78 {" \x0000003\x00", 3, true}, 79 {"00000000227\x00", 0227, true}, 80 {"032033\x00 ", 032033, true}, 81 {"320330\x00 ", 0320330, true}, 82 {"0000660\x00 ", 0660, true}, 83 {"\x00 0000660\x00 ", 0660, true}, 84 {"0123456789abcdef", 0, false}, 85 {"0123456789\x00abcdef", 0, false}, 86 {"01234567\x0089abcdef", 342391, true}, 87 {"0123\x7e\x5f\x264123", 0, false}, 88 } 89 90 for _, v := range vectors { 91 var p parser 92 got := p.parseNumeric([]byte(v.in)) 93 ok := (p.err == nil) 94 if ok != v.ok { 95 if v.ok { 96 t.Errorf("parseNumeric(%q): got parsing failure, want success", v.in) 97 } else { 98 t.Errorf("parseNumeric(%q): got parsing success, want failure", v.in) 99 } 100 } 101 if ok && got != v.want { 102 t.Errorf("parseNumeric(%q): got %d, want %d", v.in, got, v.want) 103 } 104 } 105 } 106 107 func TestFormatNumeric(t *testing.T) { 108 vectors := []struct { 109 in int64 110 want string 111 ok bool 112 }{ 113 // Test base-8 (octal) encoded values. 114 {0, "0\x00", true}, 115 {7, "7\x00", true}, 116 {8, "\x80\x08", true}, 117 {077, "77\x00", true}, 118 {0100, "\x80\x00\x40", true}, 119 {0, "0000000\x00", true}, 120 {0123, "0000123\x00", true}, 121 {07654321, "7654321\x00", true}, 122 {07777777, "7777777\x00", true}, 123 {010000000, "\x80\x00\x00\x00\x00\x20\x00\x00", true}, 124 {0, "00000000000\x00", true}, 125 {000001234567, "00001234567\x00", true}, 126 {076543210321, "76543210321\x00", true}, 127 {012345670123, "12345670123\x00", true}, 128 {077777777777, "77777777777\x00", true}, 129 {0100000000000, "\x80\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00", true}, 130 {math.MaxInt64, "777777777777777777777\x00", true}, 131 132 // Test base-256 (binary) encoded values. 133 {-1, "\xff", true}, 134 {-1, "\xff\xff", true}, 135 {-1, "\xff\xff\xff", true}, 136 {(1 << 0), "0", false}, 137 {(1 << 8) - 1, "\x80\xff", true}, 138 {(1 << 8), "0\x00", false}, 139 {(1 << 16) - 1, "\x80\xff\xff", true}, 140 {(1 << 16), "00\x00", false}, 141 {-1 * (1 << 0), "\xff", true}, 142 {-1*(1<<0) - 1, "0", false}, 143 {-1 * (1 << 8), "\xff\x00", true}, 144 {-1*(1<<8) - 1, "0\x00", false}, 145 {-1 * (1 << 16), "\xff\x00\x00", true}, 146 {-1*(1<<16) - 1, "00\x00", false}, 147 {537795476381659745, "0000000\x00", false}, 148 {537795476381659745, "\x80\x00\x00\x00\x07\x76\xa2\x22\xeb\x8a\x72\x61", true}, 149 {-615126028225187231, "0000000\x00", false}, 150 {-615126028225187231, "\xff\xff\xff\xff\xf7\x76\xa2\x22\xeb\x8a\x72\x61", true}, 151 {math.MaxInt64, "0000000\x00", false}, 152 {math.MaxInt64, "\x80\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff", true}, 153 {math.MinInt64, "0000000\x00", false}, 154 {math.MinInt64, "\xff\xff\xff\xff\x80\x00\x00\x00\x00\x00\x00\x00", true}, 155 {math.MaxInt64, "\x80\x7f\xff\xff\xff\xff\xff\xff\xff", true}, 156 {math.MinInt64, "\xff\x80\x00\x00\x00\x00\x00\x00\x00", true}, 157 } 158 159 for _, v := range vectors { 160 var f formatter 161 got := make([]byte, len(v.want)) 162 f.formatNumeric(got, v.in) 163 ok := (f.err == nil) 164 if ok != v.ok { 165 if v.ok { 166 t.Errorf("formatNumeric(%d): got formatting failure, want success", v.in) 167 } else { 168 t.Errorf("formatNumeric(%d): got formatting success, want failure", v.in) 169 } 170 } 171 if string(got) != v.want { 172 t.Errorf("formatNumeric(%d): got %q, want %q", v.in, got, v.want) 173 } 174 } 175 } 176 177 func TestFitsInOctal(t *testing.T) { 178 vectors := []struct { 179 input int64 180 width int 181 ok bool 182 }{ 183 {-1, 1, false}, 184 {-1, 2, false}, 185 {-1, 3, false}, 186 {0, 1, true}, 187 {0 + 1, 1, false}, 188 {0, 2, true}, 189 {07, 2, true}, 190 {07 + 1, 2, false}, 191 {0, 4, true}, 192 {0777, 4, true}, 193 {0777 + 1, 4, false}, 194 {0, 8, true}, 195 {07777777, 8, true}, 196 {07777777 + 1, 8, false}, 197 {0, 12, true}, 198 {077777777777, 12, true}, 199 {077777777777 + 1, 12, false}, 200 {math.MaxInt64, 22, true}, 201 {012345670123, 12, true}, 202 {01564164, 12, true}, 203 {-012345670123, 12, false}, 204 {-01564164, 12, false}, 205 {-1564164, 30, false}, 206 } 207 208 for _, v := range vectors { 209 ok := fitsInOctal(v.width, v.input) 210 if ok != v.ok { 211 t.Errorf("checkOctal(%d, %d): got %v, want %v", v.input, v.width, ok, v.ok) 212 } 213 } 214 } 215 216 func TestParsePAXTime(t *testing.T) { 217 vectors := []struct { 218 in string 219 want time.Time 220 ok bool 221 }{ 222 {"1350244992.023960108", time.Unix(1350244992, 23960108), true}, 223 {"1350244992.02396010", time.Unix(1350244992, 23960100), true}, 224 {"1350244992.0239601089", time.Unix(1350244992, 23960108), true}, 225 {"1350244992.3", time.Unix(1350244992, 300000000), true}, 226 {"1350244992", time.Unix(1350244992, 0), true}, 227 {"-1.000000001", time.Unix(-1, -1e0+0e0), true}, 228 {"-1.000001", time.Unix(-1, -1e3+0e0), true}, 229 {"-1.001000", time.Unix(-1, -1e6+0e0), true}, 230 {"-1", time.Unix(-1, -0e0+0e0), true}, 231 {"-1.999000", time.Unix(-1, -1e9+1e6), true}, 232 {"-1.999999", time.Unix(-1, -1e9+1e3), true}, 233 {"-1.999999999", time.Unix(-1, -1e9+1e0), true}, 234 {"0.000000001", time.Unix(0, 1e0+0e0), true}, 235 {"0.000001", time.Unix(0, 1e3+0e0), true}, 236 {"0.001000", time.Unix(0, 1e6+0e0), true}, 237 {"0", time.Unix(0, 0e0), true}, 238 {"0.999000", time.Unix(0, 1e9-1e6), true}, 239 {"0.999999", time.Unix(0, 1e9-1e3), true}, 240 {"0.999999999", time.Unix(0, 1e9-1e0), true}, 241 {"1.000000001", time.Unix(+1, +1e0-0e0), true}, 242 {"1.000001", time.Unix(+1, +1e3-0e0), true}, 243 {"1.001000", time.Unix(+1, +1e6-0e0), true}, 244 {"1", time.Unix(+1, +0e0-0e0), true}, 245 {"1.999000", time.Unix(+1, +1e9-1e6), true}, 246 {"1.999999", time.Unix(+1, +1e9-1e3), true}, 247 {"1.999999999", time.Unix(+1, +1e9-1e0), true}, 248 {"-1350244992.023960108", time.Unix(-1350244992, -23960108), true}, 249 {"-1350244992.02396010", time.Unix(-1350244992, -23960100), true}, 250 {"-1350244992.0239601089", time.Unix(-1350244992, -23960108), true}, 251 {"-1350244992.3", time.Unix(-1350244992, -300000000), true}, 252 {"-1350244992", time.Unix(-1350244992, 0), true}, 253 {"", time.Time{}, false}, 254 {"0", time.Unix(0, 0), true}, 255 {"1.", time.Unix(1, 0), true}, 256 {"0.0", time.Unix(0, 0), true}, 257 {".5", time.Time{}, false}, 258 {"-1.3", time.Unix(-1, -3e8), true}, 259 {"-1.0", time.Unix(-1, -0e0), true}, 260 {"-0.0", time.Unix(-0, -0e0), true}, 261 {"-0.1", time.Unix(-0, -1e8), true}, 262 {"-0.01", time.Unix(-0, -1e7), true}, 263 {"-0.99", time.Unix(-0, -99e7), true}, 264 {"-0.98", time.Unix(-0, -98e7), true}, 265 {"-1.1", time.Unix(-1, -1e8), true}, 266 {"-1.01", time.Unix(-1, -1e7), true}, 267 {"-2.99", time.Unix(-2, -99e7), true}, 268 {"-5.98", time.Unix(-5, -98e7), true}, 269 {"-", time.Time{}, false}, 270 {"+", time.Time{}, false}, 271 {"-1.-1", time.Time{}, false}, 272 {"99999999999999999999999999999999999999999999999", time.Time{}, false}, 273 {"0.123456789abcdef", time.Time{}, false}, 274 {"foo", time.Time{}, false}, 275 {"\x00", time.Time{}, false}, 276 {"𝟵𝟴𝟳𝟲𝟱.𝟰𝟯𝟮𝟭𝟬", time.Time{}, false}, // Unicode numbers (U+1D7EC to U+1D7F5) 277 {"98765﹒43210", time.Time{}, false}, // Unicode period (U+FE52) 278 } 279 280 for _, v := range vectors { 281 ts, err := parsePAXTime(v.in) 282 ok := (err == nil) 283 if v.ok != ok { 284 if v.ok { 285 t.Errorf("parsePAXTime(%q): got parsing failure, want success", v.in) 286 } else { 287 t.Errorf("parsePAXTime(%q): got parsing success, want failure", v.in) 288 } 289 } 290 if ok && !ts.Equal(v.want) { 291 t.Errorf("parsePAXTime(%q): got (%ds %dns), want (%ds %dns)", 292 v.in, ts.Unix(), ts.Nanosecond(), v.want.Unix(), v.want.Nanosecond()) 293 } 294 } 295 } 296 297 func TestFormatPAXTime(t *testing.T) { 298 vectors := []struct { 299 sec, nsec int64 300 want string 301 }{ 302 {1350244992, 0, "1350244992"}, 303 {1350244992, 300000000, "1350244992.3"}, 304 {1350244992, 23960100, "1350244992.0239601"}, 305 {1350244992, 23960108, "1350244992.023960108"}, 306 {+1, +1E9 - 1E0, "1.999999999"}, 307 {+1, +1E9 - 1E3, "1.999999"}, 308 {+1, +1E9 - 1E6, "1.999"}, 309 {+1, +0E0 - 0E0, "1"}, 310 {+1, +1E6 - 0E0, "1.001"}, 311 {+1, +1E3 - 0E0, "1.000001"}, 312 {+1, +1E0 - 0E0, "1.000000001"}, 313 {0, 1E9 - 1E0, "0.999999999"}, 314 {0, 1E9 - 1E3, "0.999999"}, 315 {0, 1E9 - 1E6, "0.999"}, 316 {0, 0E0, "0"}, 317 {0, 1E6 + 0E0, "0.001"}, 318 {0, 1E3 + 0E0, "0.000001"}, 319 {0, 1E0 + 0E0, "0.000000001"}, 320 {-1, -1E9 + 1E0, "-1.999999999"}, 321 {-1, -1E9 + 1E3, "-1.999999"}, 322 {-1, -1E9 + 1E6, "-1.999"}, 323 {-1, -0E0 + 0E0, "-1"}, 324 {-1, -1E6 + 0E0, "-1.001"}, 325 {-1, -1E3 + 0E0, "-1.000001"}, 326 {-1, -1E0 + 0E0, "-1.000000001"}, 327 {-1350244992, 0, "-1350244992"}, 328 {-1350244992, -300000000, "-1350244992.3"}, 329 {-1350244992, -23960100, "-1350244992.0239601"}, 330 {-1350244992, -23960108, "-1350244992.023960108"}, 331 } 332 333 for _, v := range vectors { 334 got := formatPAXTime(time.Unix(v.sec, v.nsec)) 335 if got != v.want { 336 t.Errorf("formatPAXTime(%ds, %dns): got %q, want %q", 337 v.sec, v.nsec, got, v.want) 338 } 339 } 340 } 341 342 func TestParsePAXRecord(t *testing.T) { 343 medName := strings.Repeat("CD", 50) 344 longName := strings.Repeat("AB", 100) 345 346 vectors := []struct { 347 in string 348 wantRes string 349 wantKey string 350 wantVal string 351 ok bool 352 }{ 353 {"6 k=v\n\n", "\n", "k", "v", true}, 354 {"19 path=/etc/hosts\n", "", "path", "/etc/hosts", true}, 355 {"210 path=" + longName + "\nabc", "abc", "path", longName, true}, 356 {"110 path=" + medName + "\n", "", "path", medName, true}, 357 {"9 foo=ba\n", "", "foo", "ba", true}, 358 {"11 foo=bar\n\x00", "\x00", "foo", "bar", true}, 359 {"18 foo=b=\nar=\n==\x00\n", "", "foo", "b=\nar=\n==\x00", true}, 360 {"27 foo=hello9 foo=ba\nworld\n", "", "foo", "hello9 foo=ba\nworld", true}, 361 {"27 ☺☻☹=日a本b語ç\nmeow mix", "meow mix", "☺☻☹", "日a本b語ç", true}, 362 {"17 \x00hello=\x00world\n", "17 \x00hello=\x00world\n", "", "", false}, 363 {"1 k=1\n", "1 k=1\n", "", "", false}, 364 {"6 k~1\n", "6 k~1\n", "", "", false}, 365 {"6_k=1\n", "6_k=1\n", "", "", false}, 366 {"6 k=1 ", "6 k=1 ", "", "", false}, 367 {"632 k=1\n", "632 k=1\n", "", "", false}, 368 {"16 longkeyname=hahaha\n", "16 longkeyname=hahaha\n", "", "", false}, 369 {"3 somelongkey=\n", "3 somelongkey=\n", "", "", false}, 370 {"50 tooshort=\n", "50 tooshort=\n", "", "", false}, 371 } 372 373 for _, v := range vectors { 374 key, val, res, err := parsePAXRecord(v.in) 375 ok := (err == nil) 376 if ok != v.ok { 377 if v.ok { 378 t.Errorf("parsePAXRecord(%q): got parsing failure, want success", v.in) 379 } else { 380 t.Errorf("parsePAXRecord(%q): got parsing success, want failure", v.in) 381 } 382 } 383 if v.ok && (key != v.wantKey || val != v.wantVal) { 384 t.Errorf("parsePAXRecord(%q): got (%q: %q), want (%q: %q)", 385 v.in, key, val, v.wantKey, v.wantVal) 386 } 387 if res != v.wantRes { 388 t.Errorf("parsePAXRecord(%q): got residual %q, want residual %q", 389 v.in, res, v.wantRes) 390 } 391 } 392 } 393 394 func TestFormatPAXRecord(t *testing.T) { 395 medName := strings.Repeat("CD", 50) 396 longName := strings.Repeat("AB", 100) 397 398 vectors := []struct { 399 inKey string 400 inVal string 401 want string 402 ok bool 403 }{ 404 {"k", "v", "6 k=v\n", true}, 405 {"path", "/etc/hosts", "19 path=/etc/hosts\n", true}, 406 {"path", longName, "210 path=" + longName + "\n", true}, 407 {"path", medName, "110 path=" + medName + "\n", true}, 408 {"foo", "ba", "9 foo=ba\n", true}, 409 {"foo", "bar", "11 foo=bar\n", true}, 410 {"foo", "b=\nar=\n==\x00", "18 foo=b=\nar=\n==\x00\n", true}, 411 {"foo", "hello9 foo=ba\nworld", "27 foo=hello9 foo=ba\nworld\n", true}, 412 {"☺☻☹", "日a本b語ç", "27 ☺☻☹=日a本b語ç\n", true}, 413 {"xhello", "\x00world", "17 xhello=\x00world\n", true}, 414 {"path", "null\x00", "", false}, 415 {"null\x00", "value", "", false}, 416 {paxSchilyXattr + "key", "null\x00", "26 SCHILY.xattr.key=null\x00\n", true}, 417 } 418 419 for _, v := range vectors { 420 got, err := formatPAXRecord(v.inKey, v.inVal) 421 ok := (err == nil) 422 if ok != v.ok { 423 if v.ok { 424 t.Errorf("formatPAXRecord(%q, %q): got format failure, want success", v.inKey, v.inVal) 425 } else { 426 t.Errorf("formatPAXRecord(%q, %q): got format success, want failure", v.inKey, v.inVal) 427 } 428 } 429 if got != v.want { 430 t.Errorf("formatPAXRecord(%q, %q): got %q, want %q", 431 v.inKey, v.inVal, got, v.want) 432 } 433 } 434 }