...

Source file src/archive/tar/strconv_test.go

Documentation: archive/tar

		 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  		{"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