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 "reflect"
17 "regexp"
18 "strings"
19 "testing"
20 "testing/fstest"
21 "time"
22 )
23
24 type ZipTest struct {
25 Name string
26 Source func() (r io.ReaderAt, size int64)
27 Comment string
28 File []ZipTestFile
29 Obscured bool
30 Error error
31 }
32
33 type ZipTestFile struct {
34 Name string
35 Mode fs.FileMode
36 NonUTF8 bool
37 ModTime time.Time
38 Modified time.Time
39
40
41
42
43
44
45
46
47
48
49
50 ContentErr error
51 Content []byte
52 File string
53 Size uint64
54 }
55
56 var tests = []ZipTest{
57 {
58 Name: "test.zip",
59 Comment: "This is a zipfile comment.",
60 File: []ZipTestFile{
61 {
62 Name: "test.txt",
63 Content: []byte("This is a test text file.\n"),
64 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
65 Mode: 0644,
66 },
67 {
68 Name: "gophercolor16x16.png",
69 File: "gophercolor16x16.png",
70 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
71 Mode: 0644,
72 },
73 },
74 },
75 {
76 Name: "test-trailing-junk.zip",
77 Comment: "This is a zipfile comment.",
78 File: []ZipTestFile{
79 {
80 Name: "test.txt",
81 Content: []byte("This is a test text file.\n"),
82 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
83 Mode: 0644,
84 },
85 {
86 Name: "gophercolor16x16.png",
87 File: "gophercolor16x16.png",
88 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
89 Mode: 0644,
90 },
91 },
92 },
93 {
94 Name: "test-prefix.zip",
95 Comment: "This is a zipfile comment.",
96 File: []ZipTestFile{
97 {
98 Name: "test.txt",
99 Content: []byte("This is a test text file.\n"),
100 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
101 Mode: 0644,
102 },
103 {
104 Name: "gophercolor16x16.png",
105 File: "gophercolor16x16.png",
106 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
107 Mode: 0644,
108 },
109 },
110 },
111 {
112 Name: "test-baddirsz.zip",
113 Comment: "This is a zipfile comment.",
114 File: []ZipTestFile{
115 {
116 Name: "test.txt",
117 Content: []byte("This is a test text file.\n"),
118 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
119 Mode: 0644,
120 },
121 {
122 Name: "gophercolor16x16.png",
123 File: "gophercolor16x16.png",
124 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
125 Mode: 0644,
126 },
127 },
128 },
129 {
130 Name: "test-badbase.zip",
131 Comment: "This is a zipfile comment.",
132 File: []ZipTestFile{
133 {
134 Name: "test.txt",
135 Content: []byte("This is a test text file.\n"),
136 Modified: time.Date(2010, 9, 5, 12, 12, 1, 0, timeZone(+10*time.Hour)),
137 Mode: 0644,
138 },
139 {
140 Name: "gophercolor16x16.png",
141 File: "gophercolor16x16.png",
142 Modified: time.Date(2010, 9, 5, 15, 52, 58, 0, timeZone(+10*time.Hour)),
143 Mode: 0644,
144 },
145 },
146 },
147 {
148 Name: "r.zip",
149 Source: returnRecursiveZip,
150 File: []ZipTestFile{
151 {
152 Name: "r/r.zip",
153 Content: rZipBytes(),
154 Modified: time.Date(2010, 3, 4, 0, 24, 16, 0, time.UTC),
155 Mode: 0666,
156 },
157 },
158 },
159 {
160 Name: "symlink.zip",
161 File: []ZipTestFile{
162 {
163 Name: "symlink",
164 Content: []byte("../target"),
165 Modified: time.Date(2012, 2, 3, 19, 56, 48, 0, timeZone(-2*time.Hour)),
166 Mode: 0777 | fs.ModeSymlink,
167 },
168 },
169 },
170 {
171 Name: "readme.zip",
172 },
173 {
174 Name: "readme.notzip",
175 Error: ErrFormat,
176 },
177 {
178 Name: "dd.zip",
179 File: []ZipTestFile{
180 {
181 Name: "filename",
182 Content: []byte("This is a test textfile.\n"),
183 Modified: time.Date(2011, 2, 2, 13, 6, 20, 0, time.UTC),
184 Mode: 0666,
185 },
186 },
187 },
188 {
189
190 Name: "winxp.zip",
191 File: []ZipTestFile{
192 {
193 Name: "hello",
194 Content: []byte("world \r\n"),
195 Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, time.UTC),
196 Mode: 0666,
197 },
198 {
199 Name: "dir/bar",
200 Content: []byte("foo \r\n"),
201 Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, time.UTC),
202 Mode: 0666,
203 },
204 {
205 Name: "dir/empty/",
206 Content: []byte{},
207 Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, time.UTC),
208 Mode: fs.ModeDir | 0777,
209 },
210 {
211 Name: "readonly",
212 Content: []byte("important \r\n"),
213 Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, time.UTC),
214 Mode: 0444,
215 },
216 },
217 },
218 {
219
220 Name: "unix.zip",
221 File: []ZipTestFile{
222 {
223 Name: "hello",
224 Content: []byte("world \r\n"),
225 Modified: time.Date(2011, 12, 8, 10, 4, 24, 0, timeZone(0)),
226 Mode: 0666,
227 },
228 {
229 Name: "dir/bar",
230 Content: []byte("foo \r\n"),
231 Modified: time.Date(2011, 12, 8, 10, 4, 50, 0, timeZone(0)),
232 Mode: 0666,
233 },
234 {
235 Name: "dir/empty/",
236 Content: []byte{},
237 Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, timeZone(0)),
238 Mode: fs.ModeDir | 0777,
239 },
240 {
241 Name: "readonly",
242 Content: []byte("important \r\n"),
243 Modified: time.Date(2011, 12, 8, 10, 6, 8, 0, timeZone(0)),
244 Mode: 0444,
245 },
246 },
247 },
248 {
249
250
251
252
253
254 Name: "go-no-datadesc-sig.zip.base64",
255 Obscured: true,
256 File: []ZipTestFile{
257 {
258 Name: "foo.txt",
259 Content: []byte("foo\n"),
260 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
261 Mode: 0644,
262 },
263 {
264 Name: "bar.txt",
265 Content: []byte("bar\n"),
266 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
267 Mode: 0644,
268 },
269 },
270 },
271 {
272
273
274 Name: "go-with-datadesc-sig.zip",
275 File: []ZipTestFile{
276 {
277 Name: "foo.txt",
278 Content: []byte("foo\n"),
279 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
280 Mode: 0666,
281 },
282 {
283 Name: "bar.txt",
284 Content: []byte("bar\n"),
285 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
286 Mode: 0666,
287 },
288 },
289 },
290 {
291 Name: "Bad-CRC32-in-data-descriptor",
292 Source: returnCorruptCRC32Zip,
293 File: []ZipTestFile{
294 {
295 Name: "foo.txt",
296 Content: []byte("foo\n"),
297 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
298 Mode: 0666,
299 ContentErr: ErrChecksum,
300 },
301 {
302 Name: "bar.txt",
303 Content: []byte("bar\n"),
304 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
305 Mode: 0666,
306 },
307 },
308 },
309
310
311 {
312 Name: "crc32-not-streamed.zip",
313 File: []ZipTestFile{
314 {
315 Name: "foo.txt",
316 Content: []byte("foo\n"),
317 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
318 Mode: 0644,
319 },
320 {
321 Name: "bar.txt",
322 Content: []byte("bar\n"),
323 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
324 Mode: 0644,
325 },
326 },
327 },
328
329
330 {
331 Name: "crc32-not-streamed.zip",
332 Source: returnCorruptNotStreamedZip,
333 File: []ZipTestFile{
334 {
335 Name: "foo.txt",
336 Content: []byte("foo\n"),
337 Modified: time.Date(2012, 3, 8, 16, 59, 10, 0, timeZone(-8*time.Hour)),
338 Mode: 0644,
339 ContentErr: ErrChecksum,
340 },
341 {
342 Name: "bar.txt",
343 Content: []byte("bar\n"),
344 Modified: time.Date(2012, 3, 8, 16, 59, 12, 0, timeZone(-8*time.Hour)),
345 Mode: 0644,
346 },
347 },
348 },
349 {
350 Name: "zip64.zip",
351 File: []ZipTestFile{
352 {
353 Name: "README",
354 Content: []byte("This small file is in ZIP64 format.\n"),
355 Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, time.UTC),
356 Mode: 0644,
357 },
358 },
359 },
360
361 {
362 Name: "zip64-2.zip",
363 File: []ZipTestFile{
364 {
365 Name: "README",
366 Content: []byte("This small file is in ZIP64 format.\n"),
367 Modified: time.Date(2012, 8, 10, 14, 33, 32, 0, timeZone(-4*time.Hour)),
368 Mode: 0644,
369 },
370 },
371 },
372
373 {
374 Name: "big.zip",
375 Source: returnBigZipBytes,
376 File: []ZipTestFile{
377 {
378 Name: "big.file",
379 Content: nil,
380 Size: 1<<32 - 1,
381 Modified: time.Date(1979, 11, 30, 0, 0, 0, 0, time.UTC),
382 Mode: 0666,
383 },
384 },
385 },
386 {
387 Name: "utf8-7zip.zip",
388 File: []ZipTestFile{
389 {
390 Name: "世界",
391 Content: []byte{},
392 Mode: 0666,
393 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
394 },
395 },
396 },
397 {
398 Name: "utf8-infozip.zip",
399 File: []ZipTestFile{
400 {
401 Name: "世界",
402 Content: []byte{},
403 Mode: 0644,
404
405
406
407
408 NonUTF8: true,
409 Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
410 },
411 },
412 },
413 {
414 Name: "utf8-osx.zip",
415 File: []ZipTestFile{
416 {
417 Name: "世界",
418 Content: []byte{},
419 Mode: 0644,
420
421 NonUTF8: true,
422 Modified: time.Date(2017, 11, 6, 13, 9, 27, 0, timeZone(-8*time.Hour)),
423 },
424 },
425 },
426 {
427 Name: "utf8-winrar.zip",
428 File: []ZipTestFile{
429 {
430 Name: "世界",
431 Content: []byte{},
432 Mode: 0666,
433 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867862500, timeZone(-8*time.Hour)),
434 },
435 },
436 },
437 {
438 Name: "utf8-winzip.zip",
439 File: []ZipTestFile{
440 {
441 Name: "世界",
442 Content: []byte{},
443 Mode: 0666,
444 Modified: time.Date(2017, 11, 6, 13, 9, 27, 867000000, timeZone(-8*time.Hour)),
445 },
446 },
447 },
448 {
449 Name: "time-7zip.zip",
450 File: []ZipTestFile{
451 {
452 Name: "test.txt",
453 Content: []byte{},
454 Size: 1<<32 - 1,
455 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
456 Mode: 0666,
457 },
458 },
459 },
460 {
461 Name: "time-infozip.zip",
462 File: []ZipTestFile{
463 {
464 Name: "test.txt",
465 Content: []byte{},
466 Size: 1<<32 - 1,
467 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
468 Mode: 0644,
469 },
470 },
471 },
472 {
473 Name: "time-osx.zip",
474 File: []ZipTestFile{
475 {
476 Name: "test.txt",
477 Content: []byte{},
478 Size: 1<<32 - 1,
479 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
480 Mode: 0644,
481 },
482 },
483 },
484 {
485 Name: "time-win7.zip",
486 File: []ZipTestFile{
487 {
488 Name: "test.txt",
489 Content: []byte{},
490 Size: 1<<32 - 1,
491 Modified: time.Date(2017, 10, 31, 21, 11, 58, 0, time.UTC),
492 Mode: 0666,
493 },
494 },
495 },
496 {
497 Name: "time-winrar.zip",
498 File: []ZipTestFile{
499 {
500 Name: "test.txt",
501 Content: []byte{},
502 Size: 1<<32 - 1,
503 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244817900, timeZone(-7*time.Hour)),
504 Mode: 0666,
505 },
506 },
507 },
508 {
509 Name: "time-winzip.zip",
510 File: []ZipTestFile{
511 {
512 Name: "test.txt",
513 Content: []byte{},
514 Size: 1<<32 - 1,
515 Modified: time.Date(2017, 10, 31, 21, 11, 57, 244000000, timeZone(-7*time.Hour)),
516 Mode: 0666,
517 },
518 },
519 },
520 {
521 Name: "time-go.zip",
522 File: []ZipTestFile{
523 {
524 Name: "test.txt",
525 Content: []byte{},
526 Size: 1<<32 - 1,
527 Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
528 Mode: 0666,
529 },
530 },
531 },
532 {
533 Name: "time-22738.zip",
534 File: []ZipTestFile{
535 {
536 Name: "file",
537 Content: []byte{},
538 Mode: 0666,
539 Modified: time.Date(1999, 12, 31, 19, 0, 0, 0, timeZone(-5*time.Hour)),
540 ModTime: time.Date(1999, 12, 31, 19, 0, 0, 0, time.UTC),
541 },
542 },
543 },
544 {
545 Name: "dupdir.zip",
546 File: []ZipTestFile{
547 {
548 Name: "a/",
549 Content: []byte{},
550 Mode: fs.ModeDir | 0666,
551 Modified: time.Date(2021, 12, 29, 0, 0, 0, 0, timeZone(0)),
552 },
553 {
554 Name: "a/b",
555 Content: []byte{},
556 Mode: 0666,
557 Modified: time.Date(2021, 12, 29, 0, 0, 0, 0, timeZone(0)),
558 },
559 {
560 Name: "a/b/",
561 Content: []byte{},
562 Mode: fs.ModeDir | 0666,
563 Modified: time.Date(2021, 12, 29, 0, 0, 0, 0, timeZone(0)),
564 },
565 {
566 Name: "a/b/c",
567 Content: []byte{},
568 Mode: 0666,
569 Modified: time.Date(2021, 12, 29, 0, 0, 0, 0, timeZone(0)),
570 },
571 },
572 },
573
574
575
576
577 {
578 Name: "comment-truncated.zip",
579 Error: ErrFormat,
580 },
581 }
582
583 func TestReader(t *testing.T) {
584 for _, zt := range tests {
585 t.Run(zt.Name, func(t *testing.T) {
586 readTestZip(t, zt)
587 })
588 }
589 }
590
591 func readTestZip(t *testing.T, zt ZipTest) {
592 var z *Reader
593 var err error
594 var raw []byte
595 if zt.Source != nil {
596 rat, size := zt.Source()
597 z, err = NewReader(rat, size)
598 raw = make([]byte, size)
599 if _, err := rat.ReadAt(raw, 0); err != nil {
600 t.Errorf("ReadAt error=%v", err)
601 return
602 }
603 } else {
604 path := filepath.Join("testdata", zt.Name)
605 if zt.Obscured {
606 tf, err := obscuretestdata.DecodeToTempFile(path)
607 if err != nil {
608 t.Errorf("obscuretestdata.DecodeToTempFile(%s): %v", path, err)
609 return
610 }
611 defer os.Remove(tf)
612 path = tf
613 }
614 var rc *ReadCloser
615 rc, err = OpenReader(path)
616 if err == nil {
617 defer rc.Close()
618 z = &rc.Reader
619 }
620 var err2 error
621 raw, err2 = os.ReadFile(path)
622 if err2 != nil {
623 t.Errorf("ReadFile(%s) error=%v", path, err2)
624 return
625 }
626 }
627 if err != zt.Error {
628 t.Errorf("error=%v, want %v", err, zt.Error)
629 return
630 }
631
632
633 if err == ErrFormat {
634 return
635 }
636
637
638
639 if zt.File == nil {
640 return
641 }
642
643 if z.Comment != zt.Comment {
644 t.Errorf("comment=%q, want %q", z.Comment, zt.Comment)
645 }
646 if len(z.File) != len(zt.File) {
647 t.Fatalf("file count=%d, want %d", len(z.File), len(zt.File))
648 }
649
650
651 for i, ft := range zt.File {
652 readTestFile(t, zt, ft, z.File[i], raw)
653 }
654 if t.Failed() {
655 return
656 }
657
658
659 n := 0
660 done := make(chan bool)
661 for i := 0; i < 5; i++ {
662 for j, ft := range zt.File {
663 go func(j int, ft ZipTestFile) {
664 readTestFile(t, zt, ft, z.File[j], raw)
665 done <- true
666 }(j, ft)
667 n++
668 }
669 }
670 for ; n > 0; n-- {
671 <-done
672 }
673 }
674
675 func equalTimeAndZone(t1, t2 time.Time) bool {
676 name1, offset1 := t1.Zone()
677 name2, offset2 := t2.Zone()
678 return t1.Equal(t2) && name1 == name2 && offset1 == offset2
679 }
680
681 func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File, raw []byte) {
682 if f.Name != ft.Name {
683 t.Errorf("name=%q, want %q", f.Name, ft.Name)
684 }
685 if !ft.Modified.IsZero() && !equalTimeAndZone(f.Modified, ft.Modified) {
686 t.Errorf("%s: Modified=%s, want %s", f.Name, f.Modified, ft.Modified)
687 }
688 if !ft.ModTime.IsZero() && !equalTimeAndZone(f.ModTime(), ft.ModTime) {
689 t.Errorf("%s: ModTime=%s, want %s", f.Name, f.ModTime(), ft.ModTime)
690 }
691
692 testFileMode(t, f, ft.Mode)
693
694 size := uint64(f.UncompressedSize)
695 if size == uint32max {
696 size = f.UncompressedSize64
697 } else if size != f.UncompressedSize64 {
698 t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
699 }
700
701
702 rw, err := f.OpenRaw()
703 if err != nil {
704 t.Errorf("%v: OpenRaw error=%v", f.Name, err)
705 return
706 }
707 start, err := f.DataOffset()
708 if err != nil {
709 t.Errorf("%v: DataOffset error=%v", f.Name, err)
710 return
711 }
712 got, err := io.ReadAll(rw)
713 if err != nil {
714 t.Errorf("%v: OpenRaw ReadAll error=%v", f.Name, err)
715 return
716 }
717 end := uint64(start) + f.CompressedSize64
718 want := raw[start:end]
719 if !bytes.Equal(got, want) {
720 t.Logf("got %q", got)
721 t.Logf("want %q", want)
722 t.Errorf("%v: OpenRaw returned unexpected bytes", f.Name)
723 return
724 }
725
726 r, err := f.Open()
727 if err != nil {
728 t.Errorf("%v", err)
729 return
730 }
731
732
733
734
735 if ft.Content == nil && ft.File == "" && ft.Size > 0 {
736 if size != ft.Size {
737 t.Errorf("%v: uncompressed size %#x, want %#x", ft.Name, size, ft.Size)
738 }
739 r.Close()
740 return
741 }
742
743 var b bytes.Buffer
744 _, err = io.Copy(&b, r)
745 if err != ft.ContentErr {
746 t.Errorf("copying contents: %v (want %v)", err, ft.ContentErr)
747 }
748 if err != nil {
749 return
750 }
751 r.Close()
752
753 if g := uint64(b.Len()); g != size {
754 t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
755 }
756
757 var c []byte
758 if ft.Content != nil {
759 c = ft.Content
760 } else if c, err = os.ReadFile("testdata/" + ft.File); err != nil {
761 t.Error(err)
762 return
763 }
764
765 if b.Len() != len(c) {
766 t.Errorf("%s: len=%d, want %d", f.Name, b.Len(), len(c))
767 return
768 }
769
770 for i, b := range b.Bytes() {
771 if b != c[i] {
772 t.Errorf("%s: content[%d]=%q want %q", f.Name, i, b, c[i])
773 return
774 }
775 }
776 }
777
778 func testFileMode(t *testing.T, f *File, want fs.FileMode) {
779 mode := f.Mode()
780 if want == 0 {
781 t.Errorf("%s mode: got %v, want none", f.Name, mode)
782 } else if mode != want {
783 t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
784 }
785 }
786
787 func TestInvalidFiles(t *testing.T) {
788 const size = 1024 * 70
789 b := make([]byte, size)
790
791
792 _, err := NewReader(bytes.NewReader(b), size)
793 if err != ErrFormat {
794 t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
795 }
796
797
798 sig := make([]byte, 4)
799 binary.LittleEndian.PutUint32(sig, directoryEndSignature)
800 for i := 0; i < size-4; i += 4 {
801 copy(b[i:i+4], sig)
802 }
803 _, err = NewReader(bytes.NewReader(b), size)
804 if err != ErrFormat {
805 t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
806 }
807
808
809 _, err = NewReader(bytes.NewReader([]byte("foobar")), -1)
810 if err == nil {
811 t.Errorf("archive/zip.NewReader: expected error when negative size is passed")
812 }
813 }
814
815 func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
816 data, err := os.ReadFile(filepath.Join("testdata", fileName))
817 if err != nil {
818 panic("Error reading " + fileName + ": " + err.Error())
819 }
820 corrupter(data)
821 return bytes.NewReader(data), int64(len(data))
822 }
823
824 func returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
825 return messWith("go-with-datadesc-sig.zip", func(b []byte) {
826
827 b[0x2d]++
828 })
829 }
830
831 func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
832 return messWith("crc32-not-streamed.zip", func(b []byte) {
833
834
835 b[0x11]++
836 b[0x9d]++
837
838
839
840
841
842
843
844 })
845 }
846
847
848
849 func rZipBytes() []byte {
850 s := `
851 0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
852 0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
853 0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
854 0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
855 0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
856 0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
857 0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
858 0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
859 0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
860 0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
861 00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
862 00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
863 00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
864 00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
865 00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
866 00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
867 0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
868 0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
869 0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
870 0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
871 0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
872 0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
873 0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
874 0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
875 0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
876 0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
877 00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
878 00001b0 00 00 6d 01 00 00 00 00`
879 s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
880 s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
881 b, err := hex.DecodeString(s)
882 if err != nil {
883 panic(err)
884 }
885 return b
886 }
887
888 func returnRecursiveZip() (r io.ReaderAt, size int64) {
889 b := rZipBytes()
890 return bytes.NewReader(b), int64(len(b))
891 }
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959 func biggestZipBytes() []byte {
960 s := `
961 0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
962 0000010 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 62 69
963 0000020 67 67 65 72 2e 7a 69 70 ec dc 6b 4c 53 67 18 07
964 0000030 f0 16 c5 ca 65 2e cb b8 94 20 61 1f 44 33 c7 cd
965 0000040 c0 86 4a b5 c0 62 8a 61 05 c6 cd 91 b2 54 8c 1b
966 0000050 63 8b 03 9c 1b 95 52 5a e3 a0 19 6c b2 05 59 44
967 0000060 64 9d 73 83 71 11 46 61 14 b9 1d 14 09 4a c3 60
968 0000070 2e 4c 6e a5 60 45 02 62 81 95 b6 94 9e 9e 77 e7
969 0000080 d0 43 b6 f8 71 df 96 3c e7 a4 69 ce bf cf e9 79
970 0000090 ce ef 79 3f bf f1 31 db b6 bb 31 76 92 e7 f3 07
971 00000a0 8b fc 9c ca cc 08 cc cb cc 5e d2 1c 88 d9 7e bb
972 00000b0 4f bb 3a 3f 75 f1 5d 7f 8f c2 68 67 77 8f 25 ff
973 00000c0 84 e2 93 2d ef a4 95 3d 71 4e 2c b9 b0 87 c3 be
974 00000d0 3d f8 a7 60 24 61 c5 ef ae 9e c8 6c 6d 4e 69 c8
975 00000e0 67 65 34 f8 37 76 2d 76 5c 54 f3 95 65 49 c7 0f
976 00000f0 18 71 4b 7e 5b 6a d1 79 47 61 41 b0 4e 2a 74 45
977 0000100 43 58 12 b2 5a a5 c6 7d 68 55 88 d4 98 75 18 6d
978 0000110 08 d1 1f 8f 5a 9e 96 ee 45 cf a4 84 4e 4b e8 50
979 0000120 a7 13 d9 06 de 52 81 97 36 b2 d7 b8 fc 2b 5f 55
980 0000130 23 1f 32 59 cf 30 27 fb e2 8a b9 de 45 dd 63 9c
981 0000140 4b b5 8b 96 4c 7a 62 62 cc a1 a7 cf fa f1 fe dd
982 0000150 54 62 11 bf 36 78 b3 c7 b1 b5 f2 61 4d 4e dd 66
983 0000160 32 2e e6 70 34 5f f4 c9 e6 6c 43 6f da 6b c6 c3
984 0000170 09 2c ce 09 57 7f d2 7e b4 23 ba 7c 1b 99 bc 22
985 0000180 3e f1 de 91 2f e3 9c 1b 82 cc c2 84 39 aa e6 de
986 0000190 b4 69 fc cc cb 72 a6 61 45 f0 d3 1d 26 19 7c 8d
987 00001a0 29 c8 66 02 be 77 6a f9 3d 34 79 17 19 c8 96 24
988 00001b0 a3 ac e4 dd 3b 1a 8e c6 fe 96 38 6b bf 67 5a 23
989 00001c0 f4 16 f4 e6 8a b4 fc c2 cd bf 95 66 1d bb 35 aa
990 00001d0 92 7d 66 d8 08 8d a5 1f 54 2a af 09 cf 61 ff d2
991 00001e0 85 9d 8f b6 d7 88 07 4a 86 03 db 64 f3 d9 92 73
992 00001f0 df ec a7 fc 23 4c 8d 83 79 63 2a d9 fd 8d b3 c8
993 0000200 8f 7e d4 19 85 e6 8d 1c 76 f0 8b 58 32 fd 9a d6
994 0000210 85 e2 48 ad c3 d5 60 6f 7e 22 dd ef 09 49 7c 7f
995 0000220 3a 45 c3 71 b7 df f3 4c 63 fb b5 d9 31 5f 6e d6
996 0000230 24 1d a4 4a fe 32 a7 5c 16 48 5c 3e 08 6b 8a d3
997 0000240 25 1d a2 12 a5 59 24 ea 20 5f 52 6d ad 94 db 6b
998 0000250 94 b9 5d eb 4b a7 5c 44 bb 1e f2 3c 6b cf 52 c9
999 0000260 e9 e5 ba 06 b9 c4 e5 0a d0 00 0d d0 00 0d d0 00
1000 0000270 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d
1001 0000280 d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0
1002 0000290 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00
1003 00002a0 0d d0 00 cd ff 9e 46 86 fa a7 7d 3a 43 d7 8e 10
1004 00002b0 52 e9 be e6 6e cf eb 9e 85 4d 65 ce cc 30 c1 44
1005 00002c0 c0 4e af bc 9c 6c 4b a0 d7 54 ff 1d d5 5c 89 fb
1006 00002d0 b5 34 7e c4 c2 9e f5 a0 f6 5b 7e 6e ca 73 c7 ef
1007 00002e0 5d be de f9 e8 81 eb a5 0a a5 63 54 2c d7 1c d1
1008 00002f0 89 17 85 f8 16 94 f2 8a b2 a3 f5 b6 6d df 75 cd
1009 0000300 90 dd 64 bd 5d 55 4e f2 55 19 1b b7 cc ef 1b ea
1010 0000310 2e 05 9c f4 aa 1e a8 cd a6 82 c7 59 0f 5e 9d e0
1011 0000320 bb fc 6c d6 99 23 eb 36 ad c6 c5 e1 d8 e1 e2 3e
1012 0000330 d9 90 5a f7 91 5d 6f bc 33 6d 98 47 d2 7c 2e 2f
1013 0000340 99 a4 25 72 85 49 2c be 0b 5b af 8f e5 6e 81 a6
1014 0000350 a3 5a 6f 39 53 3a ab 7a 8b 1e 26 f7 46 6c 7d 26
1015 0000360 53 b3 22 31 94 d3 83 f2 18 4d f5 92 33 27 53 97
1016 0000370 0f d3 e6 55 9c a6 c5 31 87 6f d3 f3 ae 39 6f 56
1017 0000380 10 7b ab 7e d0 b4 ca f2 b8 05 be 3f 0e 6e 5a 75
1018 0000390 ab 0c f5 37 0e ba 8e 75 71 7a aa ed 7a dd 6a 63
1019 00003a0 be 9b a0 97 27 6a 6f e7 d3 8b c4 7c ec d3 91 56
1020 00003b0 d9 ac 5e bf 16 42 2f 00 1f 93 a2 23 87 bd e2 59
1021 00003c0 a0 de 1a 66 c8 62 eb 55 8f 91 17 b4 61 42 7a 50
1022 00003d0 40 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40
1023 00003e0 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40 03
1024 00003f0 34 40 03 34 40 03 34 ff 85 86 90 8b ea 67 90 0d
1025 0000400 e1 42 1b d2 61 d6 79 ec fd 3e 44 28 a4 51 6c 5c
1026 0000410 fc d2 72 ca ba 82 18 46 16 61 cd 93 a9 0f d1 24
1027 0000420 17 99 e2 2c 71 16 84 0c c8 7a 13 0f 9a 5e c5 f0
1028 0000430 79 64 e2 12 4d c8 82 a1 81 19 2d aa 44 6d 87 54
1029 0000440 84 71 c1 f6 d4 ca 25 8c 77 b9 08 c7 c8 5e 10 8a
1030 0000450 8f 61 ed 8c ba 30 1f 79 9a c7 60 34 2b b9 8c f8
1031 0000460 18 a6 83 1b e3 9f ad 79 fe fd 1b 8b f1 fc 41 6f
1032 0000470 d4 13 1f e3 b8 83 ba 64 92 e7 eb e4 77 05 8f ba
1033 0000480 fa 3b 00 00 ff ff 50 4b 07 08 a6 18 b1 91 5e 04
1034 0000490 00 00 e4 47 00 00 50 4b 01 02 14 00 14 00 08 00
1035 00004a0 08 00 00 00 00 00 a6 18 b1 91 5e 04 00 00 e4 47
1036 00004b0 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
1037 00004c0 00 00 00 00 62 69 67 67 65 72 2e 7a 69 70 50 4b
1038 00004d0 05 06 00 00 00 00 01 00 01 00 38 00 00 00 96 04
1039 00004e0 00 00 00 00`
1040 s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
1041 s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
1042 b, err := hex.DecodeString(s)
1043 if err != nil {
1044 panic(err)
1045 }
1046 return b
1047 }
1048
1049 func returnBigZipBytes() (r io.ReaderAt, size int64) {
1050 b := biggestZipBytes()
1051 for i := 0; i < 2; i++ {
1052 r, err := NewReader(bytes.NewReader(b), int64(len(b)))
1053 if err != nil {
1054 panic(err)
1055 }
1056 f, err := r.File[0].Open()
1057 if err != nil {
1058 panic(err)
1059 }
1060 b, err = io.ReadAll(f)
1061 if err != nil {
1062 panic(err)
1063 }
1064 }
1065 return bytes.NewReader(b), int64(len(b))
1066 }
1067
1068 func TestIssue8186(t *testing.T) {
1069
1070 dirEnts := []string{
1071 "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",
1072 "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",
1073 "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",
1074 "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",
1075 "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",
1076 "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",
1077 "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",
1078 "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",
1079 "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",
1080 }
1081 for i, s := range dirEnts {
1082 var f File
1083 err := readDirectoryHeader(&f, strings.NewReader(s))
1084 if err != nil {
1085 t.Errorf("error reading #%d: %v", i, err)
1086 }
1087 }
1088 }
1089
1090
1091 func TestIssue10957(t *testing.T) {
1092 data := []byte("PK\x03\x040000000PK\x01\x0200000" +
1093 "0000000000000000000\x00" +
1094 "\x00\x00\x00\x00\x00000000000000PK\x01" +
1095 "\x020000000000000000000" +
1096 "00000\v\x00\x00\x00\x00\x00000000000" +
1097 "00000000000000PK\x01\x0200" +
1098 "00000000000000000000" +
1099 "00\v\x00\x00\x00\x00\x00000000000000" +
1100 "00000000000PK\x01\x020000<" +
1101 "0\x00\x0000000000000000\v\x00\v" +
1102 "\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
1103 "00000000PK\x01\x0200000000" +
1104 "0000000000000000\v\x00\x00\x00" +
1105 "\x00\x0000PK\x05\x06000000\x05\x00\xfd\x00\x00\x00" +
1106 "\v\x00\x00\x00\x00\x00")
1107 z, err := NewReader(bytes.NewReader(data), int64(len(data)))
1108 if err != nil {
1109 t.Fatal(err)
1110 }
1111 for i, f := range z.File {
1112 r, err := f.Open()
1113 if err != nil {
1114 continue
1115 }
1116 if f.UncompressedSize64 < 1e6 {
1117 n, err := io.Copy(io.Discard, r)
1118 if i == 3 && err != io.ErrUnexpectedEOF {
1119 t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
1120 }
1121 if err == nil && uint64(n) != f.UncompressedSize64 {
1122 t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
1123 }
1124 }
1125 r.Close()
1126 }
1127 }
1128
1129
1130 func TestIssue10956(t *testing.T) {
1131 data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
1132 "0000PK\x05\x06000000000000" +
1133 "0000\v\x00000\x00\x00\x00\x00\x00\x00\x000")
1134 r, err := NewReader(bytes.NewReader(data), int64(len(data)))
1135 if err == nil {
1136 t.Errorf("got nil error, want ErrFormat")
1137 }
1138 if r != nil {
1139 t.Errorf("got non-nil Reader, want nil")
1140 }
1141 }
1142
1143
1144 func TestIssue11146(t *testing.T) {
1145 data := []byte("PK\x03\x040000000000000000" +
1146 "000000\x01\x00\x00\x000\x01\x00\x00\xff\xff0000" +
1147 "0000000000000000PK\x01\x02" +
1148 "0000\b0\b\x00000000000000" +
1149 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000PK\x05\x06\x00\x00" +
1150 "\x00\x0000\x01\x00\x26\x00\x00\x008\x00\x00\x00\x00\x00")
1151 z, err := NewReader(bytes.NewReader(data), int64(len(data)))
1152 if err != nil {
1153 t.Fatal(err)
1154 }
1155 r, err := z.File[0].Open()
1156 if err != nil {
1157 t.Fatal(err)
1158 }
1159 _, err = io.ReadAll(r)
1160 if err != io.ErrUnexpectedEOF {
1161 t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
1162 }
1163 r.Close()
1164 }
1165
1166
1167 func TestIssue12449(t *testing.T) {
1168 data := []byte{
1169 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
1170 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46, 0x00, 0x00,
1171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172 0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0xca, 0x64,
1173 0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
1174 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
1175 0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
1176 0x00, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x0a,
1177 0x50, 0x4b, 0x07, 0x08, 0x1d, 0x88, 0x77, 0xb0,
1178 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1179 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00,
1180 0x08, 0x00, 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46,
1181 0x1d, 0x88, 0x77, 0xb0, 0x07, 0x00, 0x00, 0x00,
1182 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00,
1183 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0xa0, 0x81, 0x00, 0x00, 0x00, 0x00, 0xca, 0x64,
1185 0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
1186 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
1187 0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
1188 0x00, 0x97, 0x2b, 0x49, 0x23, 0x05, 0xc5, 0x0b,
1189 0xa7, 0xd1, 0x52, 0xa2, 0x9c, 0x50, 0x4b, 0x06,
1190 0x07, 0xc8, 0x19, 0xc1, 0xaf, 0x94, 0x9c, 0x61,
1191 0x44, 0xbe, 0x94, 0x19, 0x42, 0x58, 0x12, 0xc6,
1192 0x5b, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
1193 0x00, 0x01, 0x00, 0x01, 0x00, 0x69, 0x00, 0x00,
1194 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
1195 }
1196
1197 _, err := NewReader(bytes.NewReader(data), int64(len(data)))
1198 if err != nil {
1199 t.Errorf("Error reading the archive: %v", err)
1200 }
1201 }
1202
1203 func TestFS(t *testing.T) {
1204 for _, test := range []struct {
1205 file string
1206 want []string
1207 }{
1208 {
1209 "testdata/unix.zip",
1210 []string{"hello", "dir/bar", "readonly"},
1211 },
1212 {
1213 "testdata/subdir.zip",
1214 []string{"a/b/c"},
1215 },
1216 } {
1217 test := test
1218 t.Run(test.file, func(t *testing.T) {
1219 t.Parallel()
1220 z, err := OpenReader(test.file)
1221 if err != nil {
1222 t.Fatal(err)
1223 }
1224 defer z.Close()
1225 if err := fstest.TestFS(z, test.want...); err != nil {
1226 t.Error(err)
1227 }
1228 })
1229 }
1230 }
1231
1232 func TestFSWalk(t *testing.T) {
1233 for _, test := range []struct {
1234 file string
1235 want []string
1236 wantErr bool
1237 }{
1238 {
1239 file: "testdata/unix.zip",
1240 want: []string{".", "dir", "dir/bar", "dir/empty", "hello", "readonly"},
1241 },
1242 {
1243 file: "testdata/subdir.zip",
1244 want: []string{".", "a", "a/b", "a/b/c"},
1245 },
1246 {
1247 file: "testdata/dupdir.zip",
1248 wantErr: true,
1249 },
1250 } {
1251 test := test
1252 t.Run(test.file, func(t *testing.T) {
1253 t.Parallel()
1254 z, err := OpenReader(test.file)
1255 if err != nil {
1256 t.Fatal(err)
1257 }
1258 var files []string
1259 sawErr := false
1260 err = fs.WalkDir(z, ".", func(path string, d fs.DirEntry, err error) error {
1261 if err != nil {
1262 if !test.wantErr {
1263 t.Errorf("%s: %v", path, err)
1264 }
1265 sawErr = true
1266 return nil
1267 }
1268 files = append(files, path)
1269 return nil
1270 })
1271 if err != nil {
1272 t.Errorf("fs.WalkDir error: %v", err)
1273 }
1274 if test.wantErr && !sawErr {
1275 t.Error("succeeded but want error")
1276 } else if !test.wantErr && sawErr {
1277 t.Error("unexpected error")
1278 }
1279 if test.want != nil && !reflect.DeepEqual(files, test.want) {
1280 t.Errorf("got %v want %v", files, test.want)
1281 }
1282 })
1283 }
1284 }
1285
1286 func TestFSModTime(t *testing.T) {
1287 t.Parallel()
1288 z, err := OpenReader("testdata/subdir.zip")
1289 if err != nil {
1290 t.Fatal(err)
1291 }
1292 defer z.Close()
1293
1294 for _, test := range []struct {
1295 name string
1296 want time.Time
1297 }{
1298 {
1299 "a",
1300 time.Date(2021, 4, 19, 12, 29, 56, 0, timeZone(-7*time.Hour)).UTC(),
1301 },
1302 {
1303 "a/b/c",
1304 time.Date(2021, 4, 19, 12, 29, 59, 0, timeZone(-7*time.Hour)).UTC(),
1305 },
1306 } {
1307 fi, err := fs.Stat(z, test.name)
1308 if err != nil {
1309 t.Errorf("%s: %v", test.name, err)
1310 continue
1311 }
1312 if got := fi.ModTime(); !got.Equal(test.want) {
1313 t.Errorf("%s: got modtime %v, want %v", test.name, got, test.want)
1314 }
1315 }
1316 }
1317
1318 func TestCVE202127919(t *testing.T) {
1319 t.Setenv("GODEBUG", "zipinsecurepath=0")
1320
1321 data := []byte{
1322 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
1323 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2e, 0x2e,
1326 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
1327 0x74, 0x0a, 0xc9, 0xc8, 0x2c, 0x56, 0xc8, 0x2c,
1328 0x56, 0x48, 0x54, 0x28, 0x49, 0x2d, 0x2e, 0x51,
1329 0x28, 0x49, 0xad, 0x28, 0x51, 0x48, 0xcb, 0xcc,
1330 0x49, 0xd5, 0xe3, 0x02, 0x04, 0x00, 0x00, 0xff,
1331 0xff, 0x50, 0x4b, 0x07, 0x08, 0xc0, 0xd7, 0xed,
1332 0xc3, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
1333 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14,
1334 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1335 0x00, 0xc0, 0xd7, 0xed, 0xc3, 0x20, 0x00, 0x00,
1336 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
1339 0x2e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
1340 0x78, 0x74, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00,
1341 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
1342 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
1343 }
1344 r, err := NewReader(bytes.NewReader(data), int64(len(data)))
1345 if err != ErrInsecurePath {
1346 t.Fatalf("Error reading the archive: %v", err)
1347 }
1348 _, err = r.Open("test.txt")
1349 if err != nil {
1350 t.Errorf("Error reading file: %v", err)
1351 }
1352 if len(r.File) != 1 {
1353 t.Fatalf("No entries in the file list")
1354 }
1355 if r.File[0].Name != "../test.txt" {
1356 t.Errorf("Unexpected entry name: %s", r.File[0].Name)
1357 }
1358 if _, err := r.File[0].Open(); err != nil {
1359 t.Errorf("Error opening file: %v", err)
1360 }
1361 }
1362
1363 func TestOpenReaderInsecurePath(t *testing.T) {
1364 t.Setenv("GODEBUG", "zipinsecurepath=0")
1365
1366 data := []byte{
1367 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
1368 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1370 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2e, 0x2e,
1371 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
1372 0x74, 0x0a, 0xc9, 0xc8, 0x2c, 0x56, 0xc8, 0x2c,
1373 0x56, 0x48, 0x54, 0x28, 0x49, 0x2d, 0x2e, 0x51,
1374 0x28, 0x49, 0xad, 0x28, 0x51, 0x48, 0xcb, 0xcc,
1375 0x49, 0xd5, 0xe3, 0x02, 0x04, 0x00, 0x00, 0xff,
1376 0xff, 0x50, 0x4b, 0x07, 0x08, 0xc0, 0xd7, 0xed,
1377 0xc3, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
1378 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14,
1379 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1380 0x00, 0xc0, 0xd7, 0xed, 0xc3, 0x20, 0x00, 0x00,
1381 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
1384 0x2e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
1385 0x78, 0x74, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00,
1386 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
1387 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
1388 }
1389
1390
1391 name := filepath.Join(t.TempDir(), "test.zip")
1392 err := os.WriteFile(name, data, 0644)
1393 if err != nil {
1394 t.Fatalf("Unable to write out the bugos zip entry")
1395 }
1396 r, err := OpenReader(name)
1397 if r != nil {
1398 defer r.Close()
1399 }
1400
1401 if err != ErrInsecurePath {
1402 t.Fatalf("Error reading the archive, we expected ErrInsecurePath but got: %v", err)
1403 }
1404 _, err = r.Open("test.txt")
1405 if err != nil {
1406 t.Errorf("Error reading file: %v", err)
1407 }
1408 if len(r.File) != 1 {
1409 t.Fatalf("No entries in the file list")
1410 }
1411 if r.File[0].Name != "../test.txt" {
1412 t.Errorf("Unexpected entry name: %s", r.File[0].Name)
1413 }
1414 if _, err := r.File[0].Open(); err != nil {
1415 t.Errorf("Error opening file: %v", err)
1416 }
1417 }
1418
1419 func TestCVE202133196(t *testing.T) {
1420
1421
1422
1423 data := []byte{
1424 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
1425 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1428 0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00,
1429 0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20,
1430 0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00,
1431 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
1432 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
1433 0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00,
1434 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
1435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437 0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c,
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
1439 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1441 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
1442 0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00,
1443 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
1444 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00,
1445 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
1446 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
1447 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff,
1448 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1449 0xff, 0xff, 0xff, 0x00, 0x00,
1450 }
1451 _, err := NewReader(bytes.NewReader(data), int64(len(data)))
1452 if err != ErrFormat {
1453 t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
1454 }
1455
1456
1457
1458 b := bytes.NewBuffer(nil)
1459 w := NewWriter(b)
1460 for i := 0; i < 5; i++ {
1461 _, err := w.Create("")
1462 if err != nil {
1463 t.Fatalf("Writer.Create failed: %s", err)
1464 }
1465 }
1466 if err := w.Close(); err != nil {
1467 t.Fatalf("Writer.Close failed: %s", err)
1468 }
1469 r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
1470 if err != nil {
1471 t.Fatalf("NewReader failed: %s", err)
1472 }
1473 if len(r.File) != 5 {
1474 t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
1475 }
1476 }
1477
1478 func TestCVE202139293(t *testing.T) {
1479
1480
1481
1482 data := []byte{
1483 0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
1484 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1485 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
1486 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1487 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1488 0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
1489 }
1490 _, err := NewReader(bytes.NewReader(data), int64(len(data)))
1491 if err != ErrFormat {
1492 t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
1493 }
1494 }
1495
1496 func TestCVE202141772(t *testing.T) {
1497 t.Setenv("GODEBUG", "zipinsecurepath=0")
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509 data := []byte{
1510 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x08,
1511 0x00, 0x00, 0x06, 0x94, 0x05, 0x53, 0x00, 0x00,
1512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1513 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x50,
1514 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
1515 0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
1516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1517 0x00, 0x02, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x50,
1518 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
1519 0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
1520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1521 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x4b,
1522 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
1523 0x91, 0x68, 0x2e, 0x53, 0x85, 0x11, 0x4a, 0x0d,
1524 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1525 0x09, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
1526 0x74, 0x2e, 0x74, 0x78, 0x74, 0x68, 0x65, 0x6c,
1527 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
1528 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x0a, 0x00,
1529 0x00, 0x08, 0x00, 0x00, 0x06, 0x94, 0x05, 0x53,
1530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1531 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
1533 0xed, 0x41, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x50,
1534 0x4b, 0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00,
1535 0x00, 0x00, 0x00, 0x78, 0x67, 0x2e, 0x53, 0x00,
1536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1537 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00,
1538 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1539 0x00, 0x1f, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x0a,
1540 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1541 0x00, 0x18, 0x00, 0x93, 0x98, 0x25, 0x57, 0x25,
1542 0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
1543 0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
1544 0xa9, 0xd7, 0x01, 0x50, 0x4b, 0x01, 0x02, 0x3f,
1545 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
1546 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
1547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1548 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1549 0x00, 0x20, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
1550 0x00, 0x5c, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00,
1551 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x93, 0x98,
1552 0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
1553 0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
1554 0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x50, 0x4b,
1555 0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00, 0x00,
1556 0x00, 0x00, 0x91, 0x68, 0x2e, 0x53, 0x85, 0x11,
1557 0x4a, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00,
1558 0x00, 0x00, 0x09, 0x00, 0x24, 0x00, 0x00, 0x00,
1559 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
1560 0x5e, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
1561 0x74, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0x00, 0x20,
1562 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18,
1563 0x00, 0xa9, 0x80, 0x51, 0x01, 0x26, 0xa9, 0xd7,
1564 0x01, 0x31, 0xd1, 0x57, 0x01, 0x26, 0xa9, 0xd7,
1565 0x01, 0xdf, 0x48, 0x85, 0xf9, 0x25, 0xa9, 0xd7,
1566 0x01, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
1567 0x00, 0x04, 0x00, 0x04, 0x00, 0x31, 0x01, 0x00,
1568 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
1569 }
1570 r, err := NewReader(bytes.NewReader(data), int64(len(data)))
1571 if err != ErrInsecurePath {
1572 t.Fatalf("Error reading the archive: %v", err)
1573 }
1574 entryNames := []string{`/`, `//`, `\`, `/test.txt`}
1575 var names []string
1576 for _, f := range r.File {
1577 names = append(names, f.Name)
1578 if _, err := f.Open(); err != nil {
1579 t.Errorf("Error opening %q: %v", f.Name, err)
1580 }
1581 if _, err := r.Open(f.Name); err == nil {
1582 t.Errorf("Opening %q with fs.FS API succeeded", f.Name)
1583 }
1584 }
1585 if !reflect.DeepEqual(names, entryNames) {
1586 t.Errorf("Unexpected file entries: %q", names)
1587 }
1588 if _, err := r.Open(""); err == nil {
1589 t.Errorf("Opening %q with fs.FS API succeeded", "")
1590 }
1591 if _, err := r.Open("test.txt"); err != nil {
1592 t.Errorf("Error opening %q with fs.FS API: %v", "test.txt", err)
1593 }
1594 dirEntries, err := fs.ReadDir(r, ".")
1595 if err != nil {
1596 t.Fatalf("Error reading the root directory: %v", err)
1597 }
1598 if len(dirEntries) != 1 || dirEntries[0].Name() != "test.txt" {
1599 t.Errorf("Unexpected directory entries")
1600 for _, dirEntry := range dirEntries {
1601 _, err := r.Open(dirEntry.Name())
1602 t.Logf("%q (Open error: %v)", dirEntry.Name(), err)
1603 }
1604 t.FailNow()
1605 }
1606 info, err := dirEntries[0].Info()
1607 if err != nil {
1608 t.Fatalf("Error reading info entry: %v", err)
1609 }
1610 if name := info.Name(); name != "test.txt" {
1611 t.Errorf("Inconsistent name in info entry: %v", name)
1612 }
1613 }
1614
1615 func TestUnderSize(t *testing.T) {
1616 z, err := OpenReader("testdata/readme.zip")
1617 if err != nil {
1618 t.Fatal(err)
1619 }
1620 defer z.Close()
1621
1622 for _, f := range z.File {
1623 f.UncompressedSize64 = 1
1624 }
1625
1626 for _, f := range z.File {
1627 t.Run(f.Name, func(t *testing.T) {
1628 rd, err := f.Open()
1629 if err != nil {
1630 t.Fatal(err)
1631 }
1632 defer rd.Close()
1633
1634 _, err = io.Copy(io.Discard, rd)
1635 if err != ErrFormat {
1636 t.Fatalf("Error mismatch\n\tGot: %v\n\tWant: %v", err, ErrFormat)
1637 }
1638 })
1639 }
1640 }
1641
1642 func TestIssue54801(t *testing.T) {
1643 for _, input := range []string{"testdata/readme.zip", "testdata/dd.zip"} {
1644 z, err := OpenReader(input)
1645 if err != nil {
1646 t.Fatal(err)
1647 }
1648 defer z.Close()
1649
1650 for _, f := range z.File {
1651
1652 f.Name += "/"
1653
1654 t.Run(f.Name, func(t *testing.T) {
1655 t.Logf("CompressedSize64: %d, Flags: %#x", f.CompressedSize64, f.Flags)
1656
1657 rd, err := f.Open()
1658 if err != nil {
1659 t.Fatal(err)
1660 }
1661 defer rd.Close()
1662
1663 n, got := io.Copy(io.Discard, rd)
1664 if n != 0 || got != ErrFormat {
1665 t.Fatalf("Error mismatch, got: %d, %v, want: %v", n, got, ErrFormat)
1666 }
1667 })
1668 }
1669 }
1670 }
1671
1672 func TestInsecurePaths(t *testing.T) {
1673 t.Setenv("GODEBUG", "zipinsecurepath=0")
1674 for _, path := range []string{
1675 "../foo",
1676 "/foo",
1677 "a/b/../../../c",
1678 `a\b`,
1679 } {
1680 var buf bytes.Buffer
1681 zw := NewWriter(&buf)
1682 _, err := zw.Create(path)
1683 if err != nil {
1684 t.Errorf("zw.Create(%q) = %v", path, err)
1685 continue
1686 }
1687 zw.Close()
1688
1689 zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
1690 if err != ErrInsecurePath {
1691 t.Errorf("NewReader for archive with file %q: got err %v, want ErrInsecurePath", path, err)
1692 continue
1693 }
1694 var gotPaths []string
1695 for _, f := range zr.File {
1696 gotPaths = append(gotPaths, f.Name)
1697 }
1698 if !reflect.DeepEqual(gotPaths, []string{path}) {
1699 t.Errorf("NewReader for archive with file %q: got files %q", path, gotPaths)
1700 continue
1701 }
1702 }
1703 }
1704
1705 func TestDisableInsecurePathCheck(t *testing.T) {
1706 t.Setenv("GODEBUG", "zipinsecurepath=1")
1707 var buf bytes.Buffer
1708 zw := NewWriter(&buf)
1709 const name = "/foo"
1710 _, err := zw.Create(name)
1711 if err != nil {
1712 t.Fatalf("zw.Create(%q) = %v", name, err)
1713 }
1714 zw.Close()
1715 zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
1716 if err != nil {
1717 t.Fatalf("NewReader with zipinsecurepath=1: got err %v, want nil", err)
1718 }
1719 var gotPaths []string
1720 for _, f := range zr.File {
1721 gotPaths = append(gotPaths, f.Name)
1722 }
1723 if want := []string{name}; !reflect.DeepEqual(gotPaths, want) {
1724 t.Errorf("NewReader with zipinsecurepath=1: got files %q, want %q", gotPaths, want)
1725 }
1726 }
1727
1728 func TestCompressedDirectory(t *testing.T) {
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738 data := []byte{
1739 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
1740 0x08, 0x00, 0x49, 0x86, 0x81, 0x55, 0x00, 0x00,
1741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1742 0x00, 0x00, 0x09, 0x00, 0x04, 0x00, 0x4d, 0x45,
1743 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46, 0x2f, 0xfe,
1744 0xca, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4b, 0x07,
1745 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
1746 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03,
1747 0x04, 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x49,
1748 0x86, 0x81, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
1750 0x00, 0x00, 0x00, 0x4d, 0x45, 0x54, 0x41, 0x2d,
1751 0x49, 0x4e, 0x46, 0x2f, 0x4d, 0x41, 0x4e, 0x49,
1752 0x46, 0x45, 0x53, 0x54, 0x2e, 0x4d, 0x46, 0xf3,
1753 0x4d, 0xcc, 0xcb, 0x4c, 0x4b, 0x2d, 0x2e, 0xd1,
1754 0x0d, 0x4b, 0x2d, 0x2a, 0xce, 0xcc, 0xcf, 0xb3,
1755 0x52, 0x30, 0xd4, 0x33, 0xe0, 0xe5, 0x72, 0x2e,
1756 0x4a, 0x4d, 0x2c, 0x49, 0x4d, 0xd1, 0x75, 0xaa,
1757 0x04, 0x0a, 0x00, 0x45, 0xf4, 0x0c, 0x8d, 0x15,
1758 0x34, 0xdc, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0x15,
1759 0x3c, 0xf3, 0x92, 0xf5, 0x34, 0x79, 0xb9, 0x78,
1760 0xb9, 0x00, 0x50, 0x4b, 0x07, 0x08, 0x93, 0x7e,
1761 0x93, 0xaf, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00,
1762 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
1763 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x49, 0x86,
1764 0x81, 0x55, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
1766 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
1769 0x2f, 0xfe, 0xca, 0x00, 0x00, 0x50, 0x4b, 0x01,
1770 0x02, 0x14, 0x00, 0x14, 0x00, 0x08, 0x08, 0x08,
1771 0x00, 0x49, 0x86, 0x81, 0x55, 0x93, 0x7e, 0x93,
1772 0xaf, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
1773 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
1775 0x00, 0x00, 0x00, 0x4d, 0x45, 0x54, 0x41, 0x2d,
1776 0x49, 0x4e, 0x46, 0x2f, 0x4d, 0x41, 0x4e, 0x49,
1777 0x46, 0x45, 0x53, 0x54, 0x2e, 0x4d, 0x46, 0x50,
1778 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02,
1779 0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x00, 0xba,
1780 0x00, 0x00, 0x00, 0x00, 0x00,
1781 }
1782 r, err := NewReader(bytes.NewReader(data), int64(len(data)))
1783 if err != nil {
1784 t.Fatalf("unexpected error: %v", err)
1785 }
1786 for _, f := range r.File {
1787 r, err := f.Open()
1788 if err != nil {
1789 t.Fatalf("unexpected error: %v", err)
1790 }
1791 if _, err := io.Copy(io.Discard, r); err != nil {
1792 t.Fatalf("unexpected error: %v", err)
1793 }
1794 }
1795 }
1796
1797 func TestBaseOffsetPlusOverflow(t *testing.T) {
1798
1799 data := []byte{
1800 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1801 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1802 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1803 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1804 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1805 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1806 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1807 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1808 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1809 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1810 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1811 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1812 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1813 0x20, 0x20, 0x20, 0x50, 0x4b, 0x06, 0x06, 0x20,
1814 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1815 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1816 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1817 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1818 0x20, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00,
1820 0x00, 0x00, 0x80, 0x50, 0x4b, 0x06, 0x07, 0x00,
1821 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
1822 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
1823 0x4b, 0x05, 0x06, 0x20, 0x20, 0x20, 0x20, 0xff,
1824 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1825 0xff, 0xff, 0xff, 0x20, 0x00,
1826 }
1827 defer func() {
1828 if r := recover(); r != nil {
1829 t.Fatalf("NewReader panicked: %s", r)
1830 }
1831 }()
1832
1833
1834
1835 NewReader(bytes.NewReader(data), int64(len(data))+1875)
1836 }
1837
View as plain text