Source file
src/archive/tar/strconv_test.go
1
2
3
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
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
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
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
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},
277 {"98765﹒43210", time.Time{}, false},
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 {"0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319", "0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319", "mtime", "1432668921.098285006", false},
372 {"06 k=v\n", "06 k=v\n", "", "", false},
373 {"00006 k=v\n", "00006 k=v\n", "", "", false},
374 {"000006 k=v\n", "000006 k=v\n", "", "", false},
375 {"000000 k=v\n", "000000 k=v\n", "", "", false},
376 {"0 k=v\n", "0 k=v\n", "", "", false},
377 {"+0000005 x=\n", "+0000005 x=\n", "", "", false},
378 }
379
380 for _, v := range vectors {
381 key, val, res, err := parsePAXRecord(v.in)
382 ok := (err == nil)
383 if ok != v.ok {
384 if v.ok {
385 t.Errorf("parsePAXRecord(%q): got parsing failure, want success", v.in)
386 } else {
387 t.Errorf("parsePAXRecord(%q): got parsing success, want failure", v.in)
388 }
389 }
390 if v.ok && (key != v.wantKey || val != v.wantVal) {
391 t.Errorf("parsePAXRecord(%q): got (%q: %q), want (%q: %q)",
392 v.in, key, val, v.wantKey, v.wantVal)
393 }
394 if res != v.wantRes {
395 t.Errorf("parsePAXRecord(%q): got residual %q, want residual %q",
396 v.in, res, v.wantRes)
397 }
398 }
399 }
400
401 func TestFormatPAXRecord(t *testing.T) {
402 medName := strings.Repeat("CD", 50)
403 longName := strings.Repeat("AB", 100)
404
405 vectors := []struct {
406 inKey string
407 inVal string
408 want string
409 ok bool
410 }{
411 {"k", "v", "6 k=v\n", true},
412 {"path", "/etc/hosts", "19 path=/etc/hosts\n", true},
413 {"path", longName, "210 path=" + longName + "\n", true},
414 {"path", medName, "110 path=" + medName + "\n", true},
415 {"foo", "ba", "9 foo=ba\n", true},
416 {"foo", "bar", "11 foo=bar\n", true},
417 {"foo", "b=\nar=\n==\x00", "18 foo=b=\nar=\n==\x00\n", true},
418 {"foo", "hello9 foo=ba\nworld", "27 foo=hello9 foo=ba\nworld\n", true},
419 {"☺☻☹", "日a本b語ç", "27 ☺☻☹=日a本b語ç\n", true},
420 {"xhello", "\x00world", "17 xhello=\x00world\n", true},
421 {"path", "null\x00", "", false},
422 {"null\x00", "value", "", false},
423 {paxSchilyXattr + "key", "null\x00", "26 SCHILY.xattr.key=null\x00\n", true},
424 }
425
426 for _, v := range vectors {
427 got, err := formatPAXRecord(v.inKey, v.inVal)
428 ok := (err == nil)
429 if ok != v.ok {
430 if v.ok {
431 t.Errorf("formatPAXRecord(%q, %q): got format failure, want success", v.inKey, v.inVal)
432 } else {
433 t.Errorf("formatPAXRecord(%q, %q): got format success, want failure", v.inKey, v.inVal)
434 }
435 }
436 if got != v.want {
437 t.Errorf("formatPAXRecord(%q, %q): got %q, want %q",
438 v.inKey, v.inVal, got, v.want)
439 }
440 }
441 }
442
View as plain text