Source file
src/archive/zip/reader_test.go
1
2
3
4
5 package zip
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "encoding/hex"
11 "internal/obscuretestdata"
12 "io"
13 "io/fs"
14 "os"
15 "path/filepath"
16 "regexp"
17 "strings"
18 "testing"
19 "testing/fstest"
20 "time"
21 )
22
23 type ZipTest struct {
24 Name string
25 Source func() (r io.ReaderAt, size int64)
26 Comment string
27 File []ZipTestFile
28 Obscured bool
29 Error error
30 }
31
32 type ZipTestFile struct {
33 Name string
34 Mode fs.FileMode
35 NonUTF8 bool
36 ModTime time.Time
37 Modified time.Time
38
39
40
41
42
43
44
45
46
47
48
49 ContentErr error
50 Content []byte
51 File string
52 Size uint64
53 }
54
55 var tests = []ZipTest{
56 {
57 Name: "test.zip",
58 Comment: "This is a zipfile comment.",
59 File: []ZipTestFile{
60 {
61 Name: "test.txt",
62 Content: []byte("This is a test text file.\n"),
63 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
64 Mode: 0644,
65 },
66 {
67 Name: "gophercolor16x16.png",
68 File: "gophercolor16x16.png",
69 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
70 Mode: 0644,
71 },
72 },
73 },
74 {
75 Name: "test-trailing-junk.zip",
76 Comment: "This is a zipfile comment.",
77 File: []ZipTestFile{
78 {
79 Name: "test.txt",
80 Content: []byte("This is a test text file.\n"),
81 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
82 Mode: 0644,
83 },
84 {
85 Name: "gophercolor16x16.png",
86 File: "gophercolor16x16.png",
87 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
88 Mode: 0644,
89 },
90 },
91 },
92 {
93 Name: "r.zip",
94 Source: returnRecursiveZip,
95 File: []ZipTestFile{
96 {
97 Name: "r/r.zip",
98 Content: rZipBytes(),
99 Modified: time.Date(2010, 3, 4, 0, 24, 16, 0, time.UTC),
100 Mode: 0666,
101 },
102 },
103 },
104 {
105 Name: "symlink.zip",
106 File: []ZipTestFile{
107 {
108 Name: "symlink",
109 Content: []byte("../target"),
110 Modified: time.Date(2012, 2, 3, 19, 56, 48, 0, timeZone(-2*time.Hour)),
111 Mode: 0777 | fs.ModeSymlink,
112 },
113 },
114 },
115 {
116 Name: "readme.zip",
117 },
118 {
119 Name: "readme.notzip",
120 Error: ErrFormat,
121 },
122 {
123 Name: "dd.zip",
124 File: []ZipTestFile{
125 {
126 Name: "filename",
127 Content: []byte("This is a test textfile.\n"),
128 Modified: time.Date(2011, 2, 2, 13, 6, 20, 0, time.UTC),
129 Mode: 0666,
130 },
131 },
132 },
133 {
134
135 Name: "winxp.zip",
136 File: []ZipTestFile{
137 {
138 Name: "hello",
139 Content: []byte("world \r\n"),
140 Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, time.UTC),
141 Mode: 0666,
142 },
143 {
144 Name: "dir/bar",
145 Content: []byte("foo \r\n"),
146 Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, time.UTC),
147 Mode: 0666,
148 },
149 {
150 Name: "dir/empty/",
151 Content: []byte{},
152 Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, time.UTC),
153 Mode: fs.ModeDir | 0777,
154 },
155 {
156 Name: "readonly",
157 Content: []byte("important \r\n"),
158 Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, time.UTC),
159 Mode: 0444,
160 },
161 },
162 },
163 {
164
165 Name: "unix.zip",
166 File: []ZipTestFile{
167 {
168 Name: "hello",
169 Content: []byte("world \r\n"),
170 Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, timeZone(0)),
171 Mode: 0666,
172 },
173 {
174 Name: "dir/bar",
175 Content: []byte("foo \r\n"),
176 Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, timeZone(0)),
177 Mode: 0666,
178 },
179 {
180 Name: "dir/empty/",
181 Content: []byte{},
182 Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, timeZone(0)),
183 Mode: fs.ModeDir | 0777,
184 },
185 {
186 Name: "readonly",
187 Content: []byte("important \r\n"),
188 Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, timeZone(0)),
189 Mode: 0444,
190 },
191 },
192 },
193 {
194
195
196
197
198
199 Name: "go-no-datadesc-sig.zip.base64",
200 Obscured: true,
201 File: []ZipTestFile{
202 {
203 Name: "foo.txt",
204 Content: []byte("foo\n"),
205 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
206 Mode: 0644,
207 },
208 {
209 Name: "bar.txt",
210 Content: []byte("bar\n"),
211 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
212 Mode: 0644,
213 },
214 },
215 },
216 {
217
218
219 Name: "go-with-datadesc-sig.zip",
220 File: []ZipTestFile{
221 {
222 Name: "foo.txt",
223 Content: []byte("foo\n"),
224 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
225 Mode: 0666,
226 },
227 {
228 Name: "bar.txt",
229 Content: []byte("bar\n"),
230 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
231 Mode: 0666,
232 },
233 },
234 },
235 {
236 Name: "Bad-CRC32-in-data-descriptor",
237 Source: returnCorruptCRC32Zip,
238 File: []ZipTestFile{
239 {
240 Name: "foo.txt",
241 Content: []byte("foo\n"),
242 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
243 Mode: 0666,
244 ContentErr: ErrChecksum,
245 },
246 {
247 Name: "bar.txt",
248 Content: []byte("bar\n"),
249 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
250 Mode: 0666,
251 },
252 },
253 },
254
255
256 {
257 Name: "crc32-not-streamed.zip",
258 File: []ZipTestFile{
259 {
260 Name: "foo.txt",
261 Content: []byte("foo\n"),
262 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
263 Mode: 0644,
264 },
265 {
266 Name: "bar.txt",
267 Content: []byte("bar\n"),
268 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
269 Mode: 0644,
270 },
271 },
272 },
273
274
275 {
276 Name: "crc32-not-streamed.zip",
277 Source: returnCorruptNotStreamedZip,
278 File: []ZipTestFile{
279 {
280 Name: "foo.txt",
281 Content: []byte("foo\n"),
282 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
283 Mode: 0644,
284 ContentErr: ErrChecksum,
285 },
286 {
287 Name: "bar.txt",
288 Content: []byte("bar\n"),
289 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
290 Mode: 0644,
291 },
292 },
293 },
294 {
295 Name: "zip64.zip",
296 File: []ZipTestFile{
297 {
298 Name: "README",
299 Content: []byte("This small file is in ZIP64 format.\n"),
300 Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, time.UTC),
301 Mode: 0644,
302 },
303 },
304 },
305
306 {
307 Name: "zip64-2.zip",
308 File: []ZipTestFile{
309 {
310 Name: "README",
311 Content: []byte("This small file is in ZIP64 format.\n"),
312 Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, timeZone(-4*time.Hour)),
313 Mode: 0644,
314 },
315 },
316 },
317
318 {
319 Name: "big.zip",
320 Source: returnBigZipBytes,
321 File: []ZipTestFile{
322 {
323 Name: "big.file",
324 Content: nil,
325 Size: 1<<32 - 1,
326 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
327 Mode: 0666,
328 },
329 },
330 },
331 {
332 Name: "utf8-7zip.zip",
333 File: []ZipTestFile{
334 {
335 Name: "世界",
336 Content: []byte{},
337 Mode: 0666,
338 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
339 },
340 },
341 },
342 {
343 Name: "utf8-infozip.zip",
344 File: []ZipTestFile{
345 {
346 Name: "世界",
347 Content: []byte{},
348 Mode: 0644,
349
350
351
352
353 NonUTF8: true,
354 Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
355 },
356 },
357 },
358 {
359 Name: "utf8-osx.zip",
360 File: []ZipTestFile{
361 {
362 Name: "世界",
363 Content: []byte{},
364 Mode: 0644,
365
366 NonUTF8: true,
367 Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
368 },
369 },
370 },
371 {
372 Name: "utf8-winrar.zip",
373 File: []ZipTestFile{
374 {
375 Name: "世界",
376 Content: []byte{},
377 Mode: 0666,
378 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
379 },
380 },
381 },
382 {
383 Name: "utf8-winzip.zip",
384 File: []ZipTestFile{
385 {
386 Name: "世界",
387 Content: []byte{},
388 Mode: 0666,
389 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867000000, timeZone(-8*time.Hour)),
390 },
391 },
392 },
393 {
394 Name: "time-7zip.zip",
395 File: []ZipTestFile{
396 {
397 Name: "test.txt",
398 Content: []byte{},
399 Size: 1<<32 - 1,
400 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
401 Mode: 0666,
402 },
403 },
404 },
405 {
406 Name: "time-infozip.zip",
407 File: []ZipTestFile{
408 {
409 Name: "test.txt",
410 Content: []byte{},
411 Size: 1<<32 - 1,
412 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
413 Mode: 0644,
414 },
415 },
416 },
417 {
418 Name: "time-osx.zip",
419 File: []ZipTestFile{
420 {
421 Name: "test.txt",
422 Content: []byte{},
423 Size: 1<<32 - 1,
424 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
425 Mode: 0644,
426 },
427 },
428 },
429 {
430 Name: "time-win7.zip",
431 File: []ZipTestFile{
432 {
433 Name: "test.txt",
434 Content: []byte{},
435 Size: 1<<32 - 1,
436 Modified: time.Date(2017, 10, 31, 21, 11, 58, 0, time.UTC),
437 Mode: 0666,
438 },
439 },
440 },
441 {
442 Name: "time-winrar.zip",
443 File: []ZipTestFile{
444 {
445 Name: "test.txt",
446 Content: []byte{},
447 Size: 1<<32 - 1,
448 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
449 Mode: 0666,
450 },
451 },
452 },
453 {
454 Name: "time-winzip.zip",
455 File: []ZipTestFile{
456 {
457 Name: "test.txt",
458 Content: []byte{},
459 Size: 1<<32 - 1,
460 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244000000, timeZone(-7*time.Hour)),
461 Mode: 0666,
462 },
463 },
464 },
465 {
466 Name: "time-go.zip",
467 File: []ZipTestFile{
468 {
469 Name: "test.txt",
470 Content: []byte{},
471 Size: 1<<32 - 1,
472 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
473 Mode: 0666,
474 },
475 },
476 },
477 {
478 Name: "time-22738.zip",
479 File: []ZipTestFile{
480 {
481 Name: "file",
482 Content: []byte{},
483 Mode: 0666,
484 Modified: time.Date(1999, 12, 31, 19, 0, 0, 0, timeZone(-5*time.Hour)),
485 ModTime: time.Date(1999, 12, 31, 19, 0, 0, 0, time.UTC),
486 },
487 },
488 },
489 }
490
491 func TestReader(t *testing.T) {
492 for _, zt := range tests {
493 t.Run(zt.Name, func(t *testing.T) {
494 readTestZip(t, zt)
495 })
496 }
497 }
498
499 func readTestZip(t *testing.T, zt ZipTest) {
500 var z *Reader
501 var err error
502 var raw []byte
503 if zt.Source != nil {
504 rat, size := zt.Source()
505 z, err = NewReader(rat, size)
506 raw = make([]byte, size)
507 if _, err := rat.ReadAt(raw, 0); err != nil {
508 t.Errorf("ReadAt error=%v", err)
509 return
510 }
511 } else {
512 path := filepath.Join("testdata", zt.Name)
513 if zt.Obscured {
514 tf, err := obscuretestdata.DecodeToTempFile(path)
515 if err != nil {
516 t.Errorf("obscuretestdata.DecodeToTempFile(%s): %v", path, err)
517 return
518 }
519 defer os.Remove(tf)
520 path = tf
521 }
522 var rc *ReadCloser
523 rc, err = OpenReader(path)
524 if err == nil {
525 defer rc.Close()
526 z = &rc.Reader
527 }
528 var err2 error
529 raw, err2 = os.ReadFile(path)
530 if err2 != nil {
531 t.Errorf("ReadFile(%s) error=%v", path, err2)
532 return
533 }
534 }
535 if err != zt.Error {
536 t.Errorf("error=%v, want %v", err, zt.Error)
537 return
538 }
539
540
541 if err == ErrFormat {
542 return
543 }
544
545
546
547 if zt.File == nil {
548 return
549 }
550
551 if z.Comment != zt.Comment {
552 t.Errorf("comment=%q, want %q", z.Comment, zt.Comment)
553 }
554 if len(z.File) != len(zt.File) {
555 t.Fatalf("file count=%d, want %d", len(z.File), len(zt.File))
556 }
557
558
559 for i, ft := range zt.File {
560 readTestFile(t, zt, ft, z.File[i], raw)
561 }
562 if t.Failed() {
563 return
564 }
565
566
567 n := 0
568 done := make(chan bool)
569 for i := 0; i < 5; i++ {
570 for j, ft := range zt.File {
571 go func(j int, ft ZipTestFile) {
572 readTestFile(t, zt, ft, z.File[j], raw)
573 done <- true
574 }(j, ft)
575 n++
576 }
577 }
578 for ; n > 0; n-- {
579 <-done
580 }
581 }
582
583 func equalTimeAndZone(t1, t2 time.Time) bool {
584 name1, offset1 := t1.Zone()
585 name2, offset2 := t2.Zone()
586 return t1.Equal(t2) && name1 == name2 && offset1 == offset2
587 }
588
589 func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File, raw []byte) {
590 if f.Name != ft.Name {
591 t.Errorf("name=%q, want %q", f.Name, ft.Name)
592 }
593 if !ft.Modified.IsZero() && !equalTimeAndZone(f.Modified, ft.Modified) {
594 t.Errorf("%s: Modified=%s, want %s", f.Name, f.Modified, ft.Modified)
595 }
596 if !ft.ModTime.IsZero() && !equalTimeAndZone(f.ModTime(), ft.ModTime) {
597 t.Errorf("%s: ModTime=%s, want %s", f.Name, f.ModTime(), ft.ModTime)
598 }
599
600 testFileMode(t, f, ft.Mode)
601
602 size := uint64(f.UncompressedSize)
603 if size == uint32max {
604 size = f.UncompressedSize64
605 } else if size != f.UncompressedSize64 {
606 t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
607 }
608
609
610 rw, err := f.OpenRaw()
611 if err != nil {
612 t.Errorf("%v: OpenRaw error=%v", f.Name, err)
613 return
614 }
615 start, err := f.DataOffset()
616 if err != nil {
617 t.Errorf("%v: DataOffset error=%v", f.Name, err)
618 return
619 }
620 got, err := io.ReadAll(rw)
621 if err != nil {
622 t.Errorf("%v: OpenRaw ReadAll error=%v", f.Name, err)
623 return
624 }
625 end := uint64(start) + f.CompressedSize64
626 want := raw[start:end]
627 if !bytes.Equal(got, want) {
628 t.Logf("got %q", got)
629 t.Logf("want %q", want)
630 t.Errorf("%v: OpenRaw returned unexpected bytes", f.Name)
631 return
632 }
633
634 r, err := f.Open()
635 if err != nil {
636 t.Errorf("%v", err)
637 return
638 }
639
640
641
642
643 if ft.Content == nil && ft.File == "" && ft.Size > 0 {
644 if size != ft.Size {
645 t.Errorf("%v: uncompressed size %#x, want %#x", ft.Name, size, ft.Size)
646 }
647 r.Close()
648 return
649 }
650
651 var b bytes.Buffer
652 _, err = io.Copy(&b, r)
653 if err != ft.ContentErr {
654 t.Errorf("copying contents: %v (want %v)", err, ft.ContentErr)
655 }
656 if err != nil {
657 return
658 }
659 r.Close()
660
661 if g := uint64(b.Len()); g != size {
662 t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
663 }
664
665 var c []byte
666 if ft.Content != nil {
667 c = ft.Content
668 } else if c, err = os.ReadFile("testdata/" + ft.File); err != nil {
669 t.Error(err)
670 return
671 }
672
673 if b.Len() != len(c) {
674 t.Errorf("%s: len=%d, want %d", f.Name, b.Len(), len(c))
675 return
676 }
677
678 for i, b := range b.Bytes() {
679 if b != c[i] {
680 t.Errorf("%s: content[%d]=%q want %q", f.Name, i, b, c[i])
681 return
682 }
683 }
684 }
685
686 func testFileMode(t *testing.T, f *File, want fs.FileMode) {
687 mode := f.Mode()
688 if want == 0 {
689 t.Errorf("%s mode: got %v, want none", f.Name, mode)
690 } else if mode != want {
691 t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
692 }
693 }
694
695 func TestInvalidFiles(t *testing.T) {
696 const size = 1024 * 70
697 b := make([]byte, size)
698
699
700 _, err := NewReader(bytes.NewReader(b), size)
701 if err != ErrFormat {
702 t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
703 }
704
705
706 sig := make([]byte, 4)
707 binary.LittleEndian.PutUint32(sig, directoryEndSignature)
708 for i := 0; i < size-4; i += 4 {
709 copy(b[i:i+4], sig)
710 }
711 _, err = NewReader(bytes.NewReader(b), size)
712 if err != ErrFormat {
713 t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
714 }
715
716
717 _, err = NewReader(bytes.NewReader([]byte("foobar")), -1)
718 if err == nil {
719 t.Errorf("archive/zip.NewReader: expected error when negative size is passed")
720 }
721 }
722
723 func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
724 data, err := os.ReadFile(filepath.Join("testdata", fileName))
725 if err != nil {
726 panic("Error reading " + fileName + ": " + err.Error())
727 }
728 corrupter(data)
729 return bytes.NewReader(data), int64(len(data))
730 }
731
732 func returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
733 return messWith("go-with-datadesc-sig.zip", func(b []byte) {
734
735 b[0x2d]++
736 })
737 }
738
739 func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
740 return messWith("crc32-not-streamed.zip", func(b []byte) {
741
742
743 b[0x11]++
744 b[0x9d]++
745
746
747
748
749
750
751
752 })
753 }
754
755
756
757 func rZipBytes() []byte {
758 s := `
759 0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
760 0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
761 0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
762 0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
763 0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
764 0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
765 0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
766 0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
767 0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
768 0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
769 00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
770 00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
771 00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
772 00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
773 00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
774 00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
775 0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
776 0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
777 0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
778 0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
779 0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
780 0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
781 0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
782 0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
783 0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
784 0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
785 00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
786 00001b0 00 00 6d 01 00 00 00 00`
787 s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
788 s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
789 b, err := hex.DecodeString(s)
790 if err != nil {
791 panic(err)
792 }
793 return b
794 }
795
796 func returnRecursiveZip() (r io.ReaderAt, size int64) {
797 b := rZipBytes()
798 return bytes.NewReader(b), int64(len(b))
799 }
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868 func biggestZipBytes() []byte {
869 s := `
870 0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
871 0000010 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 62 69
872 0000020 67 67 65 72 2e 7a 69 70 ec dc 6b 4c 53 67 18 07
873 0000030 f0 16 c5 ca 65 2e cb b8 94 20 61 1f 44 33 c7 cd
874 0000040 c0 86 4a b5 c0 62 8a 61 05 c6 cd 91 b2 54 8c 1b
875 0000050 63 8b 03 9c 1b 95 52 5a e3 a0 19 6c b2 05 59 44
876 0000060 64 9d 73 83 71 11 46 61 14 b9 1d 14 09 4a c3 60
877 0000070 2e 4c 6e a5 60 45 02 62 81 95 b6 94 9e 9e 77 e7
878 0000080 d0 43 b6 f8 71 df 96 3c e7 a4 69 ce bf cf e9 79
879 0000090 ce ef 79 3f bf f1 31 db b6 bb 31 76 92 e7 f3 07
880 00000a0 8b fc 9c ca cc 08 cc cb cc 5e d2 1c 88 d9 7e bb
881 00000b0 4f bb 3a 3f 75 f1 5d 7f 8f c2 68 67 77 8f 25 ff
882 00000c0 84 e2 93 2d ef a4 95 3d 71 4e 2c b9 b0 87 c3 be
883 00000d0 3d f8 a7 60 24 61 c5 ef ae 9e c8 6c 6d 4e 69 c8
884 00000e0 67 65 34 f8 37 76 2d 76 5c 54 f3 95 65 49 c7 0f
885 00000f0 18 71 4b 7e 5b 6a d1 79 47 61 41 b0 4e 2a 74 45
886 0000100 43 58 12 b2 5a a5 c6 7d 68 55 88 d4 98 75 18 6d
887 0000110 08 d1 1f 8f 5a 9e 96 ee 45 cf a4 84 4e 4b e8 50
888 0000120 a7 13 d9 06 de 52 81 97 36 b2 d7 b8 fc 2b 5f 55
889 0000130 23 1f 32 59 cf 30 27 fb e2 8a b9 de 45 dd 63 9c
890 0000140 4b b5 8b 96 4c 7a 62 62 cc a1 a7 cf fa f1 fe dd
891 0000150 54 62 11 bf 36 78 b3 c7 b1 b5 f2 61 4d 4e dd 66
892 0000160 32 2e e6 70 34 5f f4 c9 e6 6c 43 6f da 6b c6 c3
893 0000170 09 2c ce 09 57 7f d2 7e b4 23 ba 7c 1b 99 bc 22
894 0000180 3e f1 de 91 2f e3 9c 1b 82 cc c2 84 39 aa e6 de
895 0000190 b4 69 fc cc cb 72 a6 61 45 f0 d3 1d 26 19 7c 8d
896 00001a0 29 c8 66 02 be 77 6a f9 3d 34 79 17 19 c8 96 24
897 00001b0 a3 ac e4 dd 3b 1a 8e c6 fe 96 38 6b bf 67 5a 23
898 00001c0 f4 16 f4 e6 8a b4 fc c2 cd bf 95 66 1d bb 35 aa
899 00001d0 92 7d 66 d8 08 8d a5 1f 54 2a af 09 cf 61 ff d2
900 00001e0 85 9d 8f b6 d7 88 07 4a 86 03 db 64 f3 d9 92 73
901 00001f0 df ec a7 fc 23 4c 8d 83 79 63 2a d9 fd 8d b3 c8
902 0000200 8f 7e d4 19 85 e6 8d 1c 76 f0 8b 58 32 fd 9a d6
903 0000210 85 e2 48 ad c3 d5 60 6f 7e 22 dd ef 09 49 7c 7f
904 0000220 3a 45 c3 71 b7 df f3 4c 63 fb b5 d9 31 5f 6e d6
905 0000230 24 1d a4 4a fe 32 a7 5c 16 48 5c 3e 08 6b 8a d3
906 0000240 25 1d a2 12 a5 59 24 ea 20 5f 52 6d ad 94 db 6b
907 0000250 94 b9 5d eb 4b a7 5c 44 bb 1e f2 3c 6b cf 52 c9
908 0000260 e9 e5 ba 06 b9 c4 e5 0a d0 00 0d d0 00 0d d0 00
909 0000270 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d
910 0000280 d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0
911 0000290 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00
912 00002a0 0d d0 00 cd ff 9e 46 86 fa a7 7d 3a 43 d7 8e 10
913 00002b0 52 e9 be e6 6e cf eb 9e 85 4d 65 ce cc 30 c1 44
914 00002c0 c0 4e af bc 9c 6c 4b a0 d7 54 ff 1d d5 5c 89 fb
915 00002d0 b5 34 7e c4 c2 9e f5 a0 f6 5b 7e 6e ca 73 c7 ef
916 00002e0 5d be de f9 e8 81 eb a5 0a a5 63 54 2c d7 1c d1
917 00002f0 89 17 85 f8 16 94 f2 8a b2 a3 f5 b6 6d df 75 cd
918 0000300 90 dd 64 bd 5d 55 4e f2 55 19 1b b7 cc ef 1b ea
919 0000310 2e 05 9c f4 aa 1e a8 cd a6 82 c7 59 0f 5e 9d e0
920 0000320 bb fc 6c d6 99 23 eb 36 ad c6 c5 e1 d8 e1 e2 3e
921 0000330 d9 90 5a f7 91 5d 6f bc 33 6d 98 47 d2 7c 2e 2f
922 0000340 99 a4 25 72 85 49 2c be 0b 5b af 8f e5 6e 81 a6
923 0000350 a3 5a 6f 39 53 3a ab 7a 8b 1e 26 f7 46 6c 7d 26
924 0000360 53 b3 22 31 94 d3 83 f2 18 4d f5 92 33 27 53 97
925 0000370 0f d3 e6 55 9c a6 c5 31 87 6f d3 f3 ae 39 6f 56
926 0000380 10 7b ab 7e d0 b4 ca f2 b8 05 be 3f 0e 6e 5a 75
927 0000390 ab 0c f5 37 0e ba 8e 75 71 7a aa ed 7a dd 6a 63
928 00003a0 be 9b a0 97 27 6a 6f e7 d3 8b c4 7c ec d3 91 56
929 00003b0 d9 ac 5e bf 16 42 2f 00 1f 93 a2 23 87 bd e2 59
930 00003c0 a0 de 1a 66 c8 62 eb 55 8f 91 17 b4 61 42 7a 50
931 00003d0 40 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40
932 00003e0 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40 03
933 00003f0 34 40 03 34 40 03 34 ff 85 86 90 8b ea 67 90 0d
934 0000400 e1 42 1b d2 61 d6 79 ec fd 3e 44 28 a4 51 6c 5c
935 0000410 fc d2 72 ca ba 82 18 46 16 61 cd 93 a9 0f d1 24
936 0000420 17 99 e2 2c 71 16 84 0c c8 7a 13 0f 9a 5e c5 f0
937 0000430 79 64 e2 12 4d c8 82 a1 81 19 2d aa 44 6d 87 54
938 0000440 84 71 c1 f6 d4 ca 25 8c 77 b9 08 c7 c8 5e 10 8a
939 0000450 8f 61 ed 8c ba 30 1f 79 9a c7 60 34 2b b9 8c f8
940 0000460 18 a6 83 1b e3 9f ad 79 fe fd 1b 8b f1 fc 41 6f
941 0000470 d4 13 1f e3 b8 83 ba 64 92 e7 eb e4 77 05 8f ba
942 0000480 fa 3b 00 00 ff ff 50 4b 07 08 a6 18 b1 91 5e 04
943 0000490 00 00 e4 47 00 00 50 4b 01 02 14 00 14 00 08 00
944 00004a0 08 00 00 00 00 00 a6 18 b1 91 5e 04 00 00 e4 47
945 00004b0 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
946 00004c0 00 00 00 00 62 69 67 67 65 72 2e 7a 69 70 50 4b
947 00004d0 05 06 00 00 00 00 01 00 01 00 38 00 00 00 96 04
948 00004e0 00 00 00 00`
949 s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
950 s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
951 b, err := hex.DecodeString(s)
952 if err != nil {
953 panic(err)
954 }
955 return b
956 }
957
958 func returnBigZipBytes() (r io.ReaderAt, size int64) {
959 b := biggestZipBytes()
960 for i := 0; i < 2; i++ {
961 r, err := NewReader(bytes.NewReader(b), int64(len(b)))
962 if err != nil {
963 panic(err)
964 }
965 f, err := r.File[0].Open()
966 if err != nil {
967 panic(err)
968 }
969 b, err = io.ReadAll(f)
970 if err != nil {
971 panic(err)
972 }
973 }
974 return bytes.NewReader(b), int64(len(b))
975 }
976
977 func TestIssue8186(t *testing.T) {
978
979 dirEnts := []string{
980 "PK\x01\x02\n\x00\n\x00\x00\b\x00\x004\x9d3?\xaa\x1b\x06\xf0\x81\x02\x00\x00\x81\x02\x00\x00-\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00res/drawable-xhdpi-v4/ic_actionbar_accept.png\xfe\xca\x00\x00\x00",
981 "PK\x01\x02\n\x00\n\x00\x00\b\x00\x004\x9d3?\x90K\x89\xc7t\n\x00\x00t\n\x00\x00\x0e\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x02\x00\x00resources.arsc\x00\x00\x00",
982 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xff$\x18\xed3\x03\x00\x00\xb4\b\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\r\x00\x00AndroidManifest.xml",
983 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\x14\xc5K\xab\x192\x02\x00\xc8\xcd\x04\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x10\x00\x00classes.dex",
984 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?E\x96\nD\xac\x01\x00\x00P\x03\x00\x00&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:C\x02\x00res/layout/actionbar_set_wallpaper.xml",
985 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?Ļ\x14\xe3\xd8\x01\x00\x00\xd8\x03\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:E\x02\x00res/layout/wallpaper_cropper.xml",
986 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?}\xc1\x15\x9eZ\x01\x00\x00!\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`G\x02\x00META-INF/MANIFEST.MF",
987 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xe6\x98Ьo\x01\x00\x00\x84\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcH\x02\x00META-INF/CERT.SF",
988 "PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xbfP\x96b\x86\x04\x00\x00\xb2\x06\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9J\x02\x00META-INF/CERT.RSA",
989 }
990 for i, s := range dirEnts {
991 var f File
992 err := readDirectoryHeader(&f, strings.NewReader(s))
993 if err != nil {
994 t.Errorf("error reading #%d: %v", i, err)
995 }
996 }
997 }
998
999
1000 func TestIssue10957(t *testing.T) {
1001 data := []byte("PK\x03\x040000000PK\x01\x0200000" +
1002 "0000000000000000000\x00" +
1003 "\x00\x00\x00\x00\x00000000000000PK\x01" +
1004 "\x020000000000000000000" +
1005 "00000\v\x00\x00\x00\x00\x00000000000" +
1006 "00000000000000PK\x01\x0200" +
1007 "00000000000000000000" +
1008 "00\v\x00\x00\x00\x00\x00000000000000" +
1009 "00000000000PK\x01\x020000<" +
1010 "0\x00\x0000000000000000\v\x00\v" +
1011 "\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
1012 "00000000PK\x01\x0200000000" +
1013 "0000000000000000\v\x00\x00\x00" +
1014 "\x00\x0000PK\x05\x06000000\x05\x000000" +
1015 "\v\x00\x00\x00\x00\x00")
1016 z, err := NewReader(bytes.NewReader(data), int64(len(data)))
1017 if err != nil {
1018 t.Fatal(err)
1019 }
1020 for i, f := range z.File {
1021 r, err := f.Open()
1022 if err != nil {
1023 continue
1024 }
1025 if f.UncompressedSize64 < 1e6 {
1026 n, err := io.Copy(io.Discard, r)
1027 if i == 3 && err != io.ErrUnexpectedEOF {
1028 t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
1029 }
1030 if err == nil && uint64(n) != f.UncompressedSize64 {
1031 t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
1032 }
1033 }
1034 r.Close()
1035 }
1036 }
1037
1038
1039 func TestIssue10956(t *testing.T) {
1040 data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
1041 "0000PK\x05\x06000000000000" +
1042 "0000\v\x00000\x00\x00\x00\x00\x00\x00\x000")
1043 r, err := NewReader(bytes.NewReader(data), int64(len(data)))
1044 if err == nil {
1045 t.Errorf("got nil error, want ErrFormat")
1046 }
1047 if r != nil {
1048 t.Errorf("got non-nil Reader, want nil")
1049 }
1050 }
1051
1052
1053 func TestIssue11146(t *testing.T) {
1054 data := []byte("PK\x03\x040000000000000000" +
1055 "000000\x01\x00\x00\x000\x01\x00\x00\xff\xff0000" +
1056 "0000000000000000PK\x01\x02" +
1057 "0000\b0\b\x00000000000000" +
1058 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000PK\x05\x06\x00\x00" +
1059 "\x00\x0000\x01\x0000008\x00\x00\x00\x00\x00")
1060 z, err := NewReader(bytes.NewReader(data), int64(len(data)))
1061 if err != nil {
1062 t.Fatal(err)
1063 }
1064 r, err := z.File[0].Open()
1065 if err != nil {
1066 t.Fatal(err)
1067 }
1068 _, err = io.ReadAll(r)
1069 if err != io.ErrUnexpectedEOF {
1070 t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
1071 }
1072 r.Close()
1073 }
1074
1075
1076 func TestIssue12449(t *testing.T) {
1077 data := []byte{
1078 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
1079 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46, 0x00, 0x00,
1080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081 0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0xca, 0x64,
1082 0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
1083 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
1084 0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
1085 0x00, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x0a,
1086 0x50, 0x4b, 0x07, 0x08, 0x1d, 0x88, 0x77, 0xb0,
1087 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1088 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00,
1089 0x08, 0x00, 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46,
1090 0x1d, 0x88, 0x77, 0xb0, 0x07, 0x00, 0x00, 0x00,
1091 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00,
1092 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093 0xa0, 0x81, 0x00, 0x00, 0x00, 0x00, 0xca, 0x64,
1094 0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
1095 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
1096 0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
1097 0x00, 0x97, 0x2b, 0x49, 0x23, 0x05, 0xc5, 0x0b,
1098 0xa7, 0xd1, 0x52, 0xa2, 0x9c, 0x50, 0x4b, 0x06,
1099 0x07, 0xc8, 0x19, 0xc1, 0xaf, 0x94, 0x9c, 0x61,
1100 0x44, 0xbe, 0x94, 0x19, 0x42, 0x58, 0x12, 0xc6,
1101 0x5b, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
1102 0x00, 0x01, 0x00, 0x01, 0x00, 0x69, 0x00, 0x00,
1103 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
1104 }
1105
1106 _, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
1107 if err != nil {
1108 t.Errorf("Error reading the archive: %v", err)
1109 }
1110 }
1111
1112 func TestFS(t *testing.T) {
1113 for _, test := range []struct {
1114 file string
1115 want []string
1116 }{
1117 {
1118 "testdata/unix.zip",
1119 []string{"hello", "dir/bar", "readonly"},
1120 },
1121 {
1122 "testdata/subdir.zip",
1123 []string{"a/b/c"},
1124 },
1125 } {
1126 t.Run(test.file, func(t *testing.T) {
1127 t.Parallel()
1128 z, err := OpenReader(test.file)
1129 if err != nil {
1130 t.Fatal(err)
1131 }
1132 defer z.Close()
1133 if err := fstest.TestFS(z, test.want...); err != nil {
1134 t.Error(err)
1135 }
1136 })
1137 }
1138 }
1139
1140 func TestFSModTime(t *testing.T) {
1141 t.Parallel()
1142 z, err := OpenReader("testdata/subdir.zip")
1143 if err != nil {
1144 t.Fatal(err)
1145 }
1146 defer z.Close()
1147
1148 for _, test := range []struct {
1149 name string
1150 want time.Time
1151 }{
1152 {
1153 "a",
1154 time.Date(2021, 4, 19, 12, 29, 56, 0, timeZone(-7*time.Hour)).UTC(),
1155 },
1156 {
1157 "a/b/c",
1158 time.Date(2021, 4, 19, 12, 29, 59, 0, timeZone(-7*time.Hour)).UTC(),
1159 },
1160 } {
1161 fi, err := fs.Stat(z, test.name)
1162 if err != nil {
1163 t.Errorf("%s: %v", test.name, err)
1164 continue
1165 }
1166 if got := fi.ModTime(); !got.Equal(test.want) {
1167 t.Errorf("%s: got modtime %v, want %v", test.name, got, test.want)
1168 }
1169 }
1170 }
1171
1172 func TestCVE202127919(t *testing.T) {
1173
1174 data := []byte{
1175 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
1176 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2e, 0x2e,
1179 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
1180 0x74, 0x0a, 0xc9, 0xc8, 0x2c, 0x56, 0xc8, 0x2c,
1181 0x56, 0x48, 0x54, 0x28, 0x49, 0x2d, 0x2e, 0x51,
1182 0x28, 0x49, 0xad, 0x28, 0x51, 0x48, 0xcb, 0xcc,
1183 0x49, 0xd5, 0xe3, 0x02, 0x04, 0x00, 0x00, 0xff,
1184 0xff, 0x50, 0x4b, 0x07, 0x08, 0xc0, 0xd7, 0xed,
1185 0xc3, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
1186 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14,
1187 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0xc0, 0xd7, 0xed, 0xc3, 0x20, 0x00, 0x00,
1189 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
1192 0x2e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
1193 0x78, 0x74, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00,
1194 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
1195 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
1196 }
1197 r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
1198 if err != nil {
1199 t.Fatalf("Error reading the archive: %v", err)
1200 }
1201 _, err = r.Open("test.txt")
1202 if err != nil {
1203 t.Errorf("Error reading file: %v", err)
1204 }
1205 }
1206
1207 func TestReadDataDescriptor(t *testing.T) {
1208 tests := []struct {
1209 desc string
1210 in []byte
1211 zip64 bool
1212 want *dataDescriptor
1213 wantErr error
1214 }{{
1215 desc: "valid 32 bit with signature",
1216 in: []byte{
1217 0x50, 0x4b, 0x07, 0x08,
1218 0x00, 0x01, 0x02, 0x03,
1219 0x04, 0x05, 0x06, 0x07,
1220 0x08, 0x09, 0x0a, 0x0b,
1221 },
1222 want: &dataDescriptor{
1223 crc32: 0x03020100,
1224 compressedSize: 0x07060504,
1225 uncompressedSize: 0x0b0a0908,
1226 },
1227 }, {
1228 desc: "valid 32 bit without signature",
1229 in: []byte{
1230 0x00, 0x01, 0x02, 0x03,
1231 0x04, 0x05, 0x06, 0x07,
1232 0x08, 0x09, 0x0a, 0x0b,
1233 },
1234 want: &dataDescriptor{
1235 crc32: 0x03020100,
1236 compressedSize: 0x07060504,
1237 uncompressedSize: 0x0b0a0908,
1238 },
1239 }, {
1240 desc: "valid 64 bit with signature",
1241 in: []byte{
1242 0x50, 0x4b, 0x07, 0x08,
1243 0x00, 0x01, 0x02, 0x03,
1244 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
1245 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
1246 },
1247 zip64: true,
1248 want: &dataDescriptor{
1249 crc32: 0x03020100,
1250 compressedSize: 0x0b0a090807060504,
1251 uncompressedSize: 0x131211100f0e0d0c,
1252 },
1253 }, {
1254 desc: "valid 64 bit without signature",
1255 in: []byte{
1256 0x00, 0x01, 0x02, 0x03,
1257 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
1258 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
1259 },
1260 zip64: true,
1261 want: &dataDescriptor{
1262 crc32: 0x03020100,
1263 compressedSize: 0x0b0a090807060504,
1264 uncompressedSize: 0x131211100f0e0d0c,
1265 },
1266 }, {
1267 desc: "invalid 32 bit with signature",
1268 in: []byte{
1269 0x50, 0x4b, 0x07, 0x08,
1270 0x00, 0x01, 0x02, 0x03,
1271 0x04, 0x05,
1272 },
1273 wantErr: io.ErrUnexpectedEOF,
1274 }, {
1275 desc: "invalid 32 bit without signature",
1276 in: []byte{
1277 0x00, 0x01, 0x02, 0x03,
1278 0x04, 0x05,
1279 },
1280 wantErr: io.ErrUnexpectedEOF,
1281 }, {
1282 desc: "invalid 64 bit with signature",
1283 in: []byte{
1284 0x50, 0x4b, 0x07, 0x08,
1285 0x00, 0x01, 0x02, 0x03,
1286 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
1287 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
1288 },
1289 zip64: true,
1290 wantErr: io.ErrUnexpectedEOF,
1291 }, {
1292 desc: "invalid 64 bit without signature",
1293 in: []byte{
1294 0x00, 0x01, 0x02, 0x03,
1295 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
1296 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
1297 },
1298 zip64: true,
1299 wantErr: io.ErrUnexpectedEOF,
1300 }}
1301
1302 for _, test := range tests {
1303 t.Run(test.desc, func(t *testing.T) {
1304 r := bytes.NewReader(test.in)
1305
1306 desc, err := readDataDescriptor(r, test.zip64)
1307 if err != test.wantErr {
1308 t.Fatalf("got err %v; want nil", err)
1309 }
1310 if test.want == nil {
1311 return
1312 }
1313 if desc == nil {
1314 t.Fatalf("got nil DataDescriptor; want non-nil")
1315 }
1316 if desc.crc32 != test.want.crc32 {
1317 t.Errorf("got CRC32 %#x; want %#x", desc.crc32, test.want.crc32)
1318 }
1319 if desc.compressedSize != test.want.compressedSize {
1320 t.Errorf("got CompressedSize %#x; want %#x", desc.compressedSize, test.want.compressedSize)
1321 }
1322 if desc.uncompressedSize != test.want.uncompressedSize {
1323 t.Errorf("got UncompressedSize %#x; want %#x", desc.uncompressedSize, test.want.uncompressedSize)
1324 }
1325 })
1326 }
1327 }
1328
1329 func TestCVE202133196(t *testing.T) {
1330
1331
1332
1333 data := []byte{
1334 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
1335 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1338 0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00,
1339 0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20,
1340 0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00,
1341 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
1342 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
1343 0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00,
1344 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
1345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1347 0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c,
1348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
1349 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1350 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1351 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
1352 0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00,
1353 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
1354 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00,
1355 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
1356 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
1357 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff,
1358 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1359 0xff, 0xff, 0xff, 0x00, 0x00,
1360 }
1361 _, err := NewReader(bytes.NewReader(data), int64(len(data)))
1362 if err != ErrFormat {
1363 t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
1364 }
1365
1366
1367
1368 b := bytes.NewBuffer(nil)
1369 w := NewWriter(b)
1370 for i := 0; i < 5; i++ {
1371 _, err := w.Create("")
1372 if err != nil {
1373 t.Fatalf("Writer.Create failed: %s", err)
1374 }
1375 }
1376 if err := w.Close(); err != nil {
1377 t.Fatalf("Writer.Close failed: %s", err)
1378 }
1379 r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
1380 if err != nil {
1381 t.Fatalf("NewReader failed: %s", err)
1382 }
1383 if len(r.File) != 5 {
1384 t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
1385 }
1386 }
1387
View as plain text