xref: /aosp_15_r20/build/soong/third_party/zip/reader_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2010 The Go Authors. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style
3*333d2b36SAndroid Build Coastguard Worker// license that can be found in the LICENSE file.
4*333d2b36SAndroid Build Coastguard Worker
5*333d2b36SAndroid Build Coastguard Workerpackage zip
6*333d2b36SAndroid Build Coastguard Worker
7*333d2b36SAndroid Build Coastguard Workerimport (
8*333d2b36SAndroid Build Coastguard Worker	"bytes"
9*333d2b36SAndroid Build Coastguard Worker	"encoding/binary"
10*333d2b36SAndroid Build Coastguard Worker	"encoding/hex"
11*333d2b36SAndroid Build Coastguard Worker	"io"
12*333d2b36SAndroid Build Coastguard Worker	"io/ioutil"
13*333d2b36SAndroid Build Coastguard Worker	"os"
14*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
15*333d2b36SAndroid Build Coastguard Worker	"regexp"
16*333d2b36SAndroid Build Coastguard Worker	"strings"
17*333d2b36SAndroid Build Coastguard Worker	"testing"
18*333d2b36SAndroid Build Coastguard Worker	"time"
19*333d2b36SAndroid Build Coastguard Worker)
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Workertype ZipTest struct {
22*333d2b36SAndroid Build Coastguard Worker	Name    string
23*333d2b36SAndroid Build Coastguard Worker	Source  func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/<Name> file
24*333d2b36SAndroid Build Coastguard Worker	Comment string
25*333d2b36SAndroid Build Coastguard Worker	File    []ZipTestFile
26*333d2b36SAndroid Build Coastguard Worker	Error   error // the error that Opening this file should return
27*333d2b36SAndroid Build Coastguard Worker}
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Workertype ZipTestFile struct {
30*333d2b36SAndroid Build Coastguard Worker	Name  string
31*333d2b36SAndroid Build Coastguard Worker	Mode  os.FileMode
32*333d2b36SAndroid Build Coastguard Worker	Mtime string // optional, modified time in format "mm-dd-yy hh:mm:ss"
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Worker	// Information describing expected zip file content.
35*333d2b36SAndroid Build Coastguard Worker	// First, reading the entire content should produce the error ContentErr.
36*333d2b36SAndroid Build Coastguard Worker	// Second, if ContentErr==nil, the content should match Content.
37*333d2b36SAndroid Build Coastguard Worker	// If content is large, an alternative to setting Content is to set File,
38*333d2b36SAndroid Build Coastguard Worker	// which names a file in the testdata/ directory containing the
39*333d2b36SAndroid Build Coastguard Worker	// uncompressed expected content.
40*333d2b36SAndroid Build Coastguard Worker	// If content is very large, an alternative to setting Content or File
41*333d2b36SAndroid Build Coastguard Worker	// is to set Size, which will then be checked against the header-reported size
42*333d2b36SAndroid Build Coastguard Worker	// but will bypass the decompressing of the actual data.
43*333d2b36SAndroid Build Coastguard Worker	// This last option is used for testing very large (multi-GB) compressed files.
44*333d2b36SAndroid Build Coastguard Worker	ContentErr error
45*333d2b36SAndroid Build Coastguard Worker	Content    []byte
46*333d2b36SAndroid Build Coastguard Worker	File       string
47*333d2b36SAndroid Build Coastguard Worker	Size       uint64
48*333d2b36SAndroid Build Coastguard Worker}
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Worker// Caution: The Mtime values found for the test files should correspond to
51*333d2b36SAndroid Build Coastguard Worker//          the values listed with unzip -l <zipfile>. However, the values
52*333d2b36SAndroid Build Coastguard Worker//          listed by unzip appear to be off by some hours. When creating
53*333d2b36SAndroid Build Coastguard Worker//          fresh test files and testing them, this issue is not present.
54*333d2b36SAndroid Build Coastguard Worker//          The test files were created in Sydney, so there might be a time
55*333d2b36SAndroid Build Coastguard Worker//          zone issue. The time zone information does have to be encoded
56*333d2b36SAndroid Build Coastguard Worker//          somewhere, because otherwise unzip -l could not provide a different
57*333d2b36SAndroid Build Coastguard Worker//          time from what the archive/zip package provides, but there appears
58*333d2b36SAndroid Build Coastguard Worker//          to be no documentation about this.
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Workervar tests = []ZipTest{
61*333d2b36SAndroid Build Coastguard Worker	{
62*333d2b36SAndroid Build Coastguard Worker		Name:    "test.zip",
63*333d2b36SAndroid Build Coastguard Worker		Comment: "This is a zipfile comment.",
64*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
65*333d2b36SAndroid Build Coastguard Worker			{
66*333d2b36SAndroid Build Coastguard Worker				Name:    "test.txt",
67*333d2b36SAndroid Build Coastguard Worker				Content: []byte("This is a test text file.\n"),
68*333d2b36SAndroid Build Coastguard Worker				Mtime:   "09-05-10 12:12:02",
69*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
70*333d2b36SAndroid Build Coastguard Worker			},
71*333d2b36SAndroid Build Coastguard Worker			{
72*333d2b36SAndroid Build Coastguard Worker				Name:  "gophercolor16x16.png",
73*333d2b36SAndroid Build Coastguard Worker				File:  "gophercolor16x16.png",
74*333d2b36SAndroid Build Coastguard Worker				Mtime: "09-05-10 15:52:58",
75*333d2b36SAndroid Build Coastguard Worker				Mode:  0644,
76*333d2b36SAndroid Build Coastguard Worker			},
77*333d2b36SAndroid Build Coastguard Worker		},
78*333d2b36SAndroid Build Coastguard Worker	},
79*333d2b36SAndroid Build Coastguard Worker	{
80*333d2b36SAndroid Build Coastguard Worker		Name:    "test-trailing-junk.zip",
81*333d2b36SAndroid Build Coastguard Worker		Comment: "This is a zipfile comment.",
82*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
83*333d2b36SAndroid Build Coastguard Worker			{
84*333d2b36SAndroid Build Coastguard Worker				Name:    "test.txt",
85*333d2b36SAndroid Build Coastguard Worker				Content: []byte("This is a test text file.\n"),
86*333d2b36SAndroid Build Coastguard Worker				Mtime:   "09-05-10 12:12:02",
87*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
88*333d2b36SAndroid Build Coastguard Worker			},
89*333d2b36SAndroid Build Coastguard Worker			{
90*333d2b36SAndroid Build Coastguard Worker				Name:  "gophercolor16x16.png",
91*333d2b36SAndroid Build Coastguard Worker				File:  "gophercolor16x16.png",
92*333d2b36SAndroid Build Coastguard Worker				Mtime: "09-05-10 15:52:58",
93*333d2b36SAndroid Build Coastguard Worker				Mode:  0644,
94*333d2b36SAndroid Build Coastguard Worker			},
95*333d2b36SAndroid Build Coastguard Worker		},
96*333d2b36SAndroid Build Coastguard Worker	},
97*333d2b36SAndroid Build Coastguard Worker	{
98*333d2b36SAndroid Build Coastguard Worker		Name:   "r.zip",
99*333d2b36SAndroid Build Coastguard Worker		Source: returnRecursiveZip,
100*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
101*333d2b36SAndroid Build Coastguard Worker			{
102*333d2b36SAndroid Build Coastguard Worker				Name:    "r/r.zip",
103*333d2b36SAndroid Build Coastguard Worker				Content: rZipBytes(),
104*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-04-10 00:24:16",
105*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
106*333d2b36SAndroid Build Coastguard Worker			},
107*333d2b36SAndroid Build Coastguard Worker		},
108*333d2b36SAndroid Build Coastguard Worker	},
109*333d2b36SAndroid Build Coastguard Worker	{
110*333d2b36SAndroid Build Coastguard Worker		Name: "symlink.zip",
111*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
112*333d2b36SAndroid Build Coastguard Worker			{
113*333d2b36SAndroid Build Coastguard Worker				Name:    "symlink",
114*333d2b36SAndroid Build Coastguard Worker				Content: []byte("../target"),
115*333d2b36SAndroid Build Coastguard Worker				Mode:    0777 | os.ModeSymlink,
116*333d2b36SAndroid Build Coastguard Worker			},
117*333d2b36SAndroid Build Coastguard Worker		},
118*333d2b36SAndroid Build Coastguard Worker	},
119*333d2b36SAndroid Build Coastguard Worker	{
120*333d2b36SAndroid Build Coastguard Worker		Name: "readme.zip",
121*333d2b36SAndroid Build Coastguard Worker	},
122*333d2b36SAndroid Build Coastguard Worker	{
123*333d2b36SAndroid Build Coastguard Worker		Name:  "readme.notzip",
124*333d2b36SAndroid Build Coastguard Worker		Error: ErrFormat,
125*333d2b36SAndroid Build Coastguard Worker	},
126*333d2b36SAndroid Build Coastguard Worker	{
127*333d2b36SAndroid Build Coastguard Worker		Name: "dd.zip",
128*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
129*333d2b36SAndroid Build Coastguard Worker			{
130*333d2b36SAndroid Build Coastguard Worker				Name:    "filename",
131*333d2b36SAndroid Build Coastguard Worker				Content: []byte("This is a test textfile.\n"),
132*333d2b36SAndroid Build Coastguard Worker				Mtime:   "02-02-11 13:06:20",
133*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
134*333d2b36SAndroid Build Coastguard Worker			},
135*333d2b36SAndroid Build Coastguard Worker		},
136*333d2b36SAndroid Build Coastguard Worker	},
137*333d2b36SAndroid Build Coastguard Worker	{
138*333d2b36SAndroid Build Coastguard Worker		// created in windows XP file manager.
139*333d2b36SAndroid Build Coastguard Worker		Name: "winxp.zip",
140*333d2b36SAndroid Build Coastguard Worker		File: crossPlatform,
141*333d2b36SAndroid Build Coastguard Worker	},
142*333d2b36SAndroid Build Coastguard Worker	{
143*333d2b36SAndroid Build Coastguard Worker		// created by Zip 3.0 under Linux
144*333d2b36SAndroid Build Coastguard Worker		Name: "unix.zip",
145*333d2b36SAndroid Build Coastguard Worker		File: crossPlatform,
146*333d2b36SAndroid Build Coastguard Worker	},
147*333d2b36SAndroid Build Coastguard Worker	{
148*333d2b36SAndroid Build Coastguard Worker		// created by Go, before we wrote the "optional" data
149*333d2b36SAndroid Build Coastguard Worker		// descriptor signatures (which are required by OS X)
150*333d2b36SAndroid Build Coastguard Worker		Name: "go-no-datadesc-sig.zip",
151*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
152*333d2b36SAndroid Build Coastguard Worker			{
153*333d2b36SAndroid Build Coastguard Worker				Name:    "foo.txt",
154*333d2b36SAndroid Build Coastguard Worker				Content: []byte("foo\n"),
155*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-08-12 16:59:10",
156*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
157*333d2b36SAndroid Build Coastguard Worker			},
158*333d2b36SAndroid Build Coastguard Worker			{
159*333d2b36SAndroid Build Coastguard Worker				Name:    "bar.txt",
160*333d2b36SAndroid Build Coastguard Worker				Content: []byte("bar\n"),
161*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-08-12 16:59:12",
162*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
163*333d2b36SAndroid Build Coastguard Worker			},
164*333d2b36SAndroid Build Coastguard Worker		},
165*333d2b36SAndroid Build Coastguard Worker	},
166*333d2b36SAndroid Build Coastguard Worker	{
167*333d2b36SAndroid Build Coastguard Worker		// created by Go, after we wrote the "optional" data
168*333d2b36SAndroid Build Coastguard Worker		// descriptor signatures (which are required by OS X)
169*333d2b36SAndroid Build Coastguard Worker		Name: "go-with-datadesc-sig.zip",
170*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
171*333d2b36SAndroid Build Coastguard Worker			{
172*333d2b36SAndroid Build Coastguard Worker				Name:    "foo.txt",
173*333d2b36SAndroid Build Coastguard Worker				Content: []byte("foo\n"),
174*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
175*333d2b36SAndroid Build Coastguard Worker			},
176*333d2b36SAndroid Build Coastguard Worker			{
177*333d2b36SAndroid Build Coastguard Worker				Name:    "bar.txt",
178*333d2b36SAndroid Build Coastguard Worker				Content: []byte("bar\n"),
179*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
180*333d2b36SAndroid Build Coastguard Worker			},
181*333d2b36SAndroid Build Coastguard Worker		},
182*333d2b36SAndroid Build Coastguard Worker	},
183*333d2b36SAndroid Build Coastguard Worker	{
184*333d2b36SAndroid Build Coastguard Worker		Name:   "Bad-CRC32-in-data-descriptor",
185*333d2b36SAndroid Build Coastguard Worker		Source: returnCorruptCRC32Zip,
186*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
187*333d2b36SAndroid Build Coastguard Worker			{
188*333d2b36SAndroid Build Coastguard Worker				Name:       "foo.txt",
189*333d2b36SAndroid Build Coastguard Worker				Content:    []byte("foo\n"),
190*333d2b36SAndroid Build Coastguard Worker				Mode:       0666,
191*333d2b36SAndroid Build Coastguard Worker				ContentErr: ErrChecksum,
192*333d2b36SAndroid Build Coastguard Worker			},
193*333d2b36SAndroid Build Coastguard Worker			{
194*333d2b36SAndroid Build Coastguard Worker				Name:    "bar.txt",
195*333d2b36SAndroid Build Coastguard Worker				Content: []byte("bar\n"),
196*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
197*333d2b36SAndroid Build Coastguard Worker			},
198*333d2b36SAndroid Build Coastguard Worker		},
199*333d2b36SAndroid Build Coastguard Worker	},
200*333d2b36SAndroid Build Coastguard Worker	// Tests that we verify (and accept valid) crc32s on files
201*333d2b36SAndroid Build Coastguard Worker	// with crc32s in their file header (not in data descriptors)
202*333d2b36SAndroid Build Coastguard Worker	{
203*333d2b36SAndroid Build Coastguard Worker		Name: "crc32-not-streamed.zip",
204*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
205*333d2b36SAndroid Build Coastguard Worker			{
206*333d2b36SAndroid Build Coastguard Worker				Name:    "foo.txt",
207*333d2b36SAndroid Build Coastguard Worker				Content: []byte("foo\n"),
208*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-08-12 16:59:10",
209*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
210*333d2b36SAndroid Build Coastguard Worker			},
211*333d2b36SAndroid Build Coastguard Worker			{
212*333d2b36SAndroid Build Coastguard Worker				Name:    "bar.txt",
213*333d2b36SAndroid Build Coastguard Worker				Content: []byte("bar\n"),
214*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-08-12 16:59:12",
215*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
216*333d2b36SAndroid Build Coastguard Worker			},
217*333d2b36SAndroid Build Coastguard Worker		},
218*333d2b36SAndroid Build Coastguard Worker	},
219*333d2b36SAndroid Build Coastguard Worker	// Tests that we verify (and reject invalid) crc32s on files
220*333d2b36SAndroid Build Coastguard Worker	// with crc32s in their file header (not in data descriptors)
221*333d2b36SAndroid Build Coastguard Worker	{
222*333d2b36SAndroid Build Coastguard Worker		Name:   "crc32-not-streamed.zip",
223*333d2b36SAndroid Build Coastguard Worker		Source: returnCorruptNotStreamedZip,
224*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
225*333d2b36SAndroid Build Coastguard Worker			{
226*333d2b36SAndroid Build Coastguard Worker				Name:       "foo.txt",
227*333d2b36SAndroid Build Coastguard Worker				Content:    []byte("foo\n"),
228*333d2b36SAndroid Build Coastguard Worker				Mtime:      "03-08-12 16:59:10",
229*333d2b36SAndroid Build Coastguard Worker				Mode:       0644,
230*333d2b36SAndroid Build Coastguard Worker				ContentErr: ErrChecksum,
231*333d2b36SAndroid Build Coastguard Worker			},
232*333d2b36SAndroid Build Coastguard Worker			{
233*333d2b36SAndroid Build Coastguard Worker				Name:    "bar.txt",
234*333d2b36SAndroid Build Coastguard Worker				Content: []byte("bar\n"),
235*333d2b36SAndroid Build Coastguard Worker				Mtime:   "03-08-12 16:59:12",
236*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
237*333d2b36SAndroid Build Coastguard Worker			},
238*333d2b36SAndroid Build Coastguard Worker		},
239*333d2b36SAndroid Build Coastguard Worker	},
240*333d2b36SAndroid Build Coastguard Worker	{
241*333d2b36SAndroid Build Coastguard Worker		Name: "zip64.zip",
242*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
243*333d2b36SAndroid Build Coastguard Worker			{
244*333d2b36SAndroid Build Coastguard Worker				Name:    "README",
245*333d2b36SAndroid Build Coastguard Worker				Content: []byte("This small file is in ZIP64 format.\n"),
246*333d2b36SAndroid Build Coastguard Worker				Mtime:   "08-10-12 14:33:32",
247*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
248*333d2b36SAndroid Build Coastguard Worker			},
249*333d2b36SAndroid Build Coastguard Worker		},
250*333d2b36SAndroid Build Coastguard Worker	},
251*333d2b36SAndroid Build Coastguard Worker	// Another zip64 file with different Extras fields. (golang.org/issue/7069)
252*333d2b36SAndroid Build Coastguard Worker	{
253*333d2b36SAndroid Build Coastguard Worker		Name: "zip64-2.zip",
254*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
255*333d2b36SAndroid Build Coastguard Worker			{
256*333d2b36SAndroid Build Coastguard Worker				Name:    "README",
257*333d2b36SAndroid Build Coastguard Worker				Content: []byte("This small file is in ZIP64 format.\n"),
258*333d2b36SAndroid Build Coastguard Worker				Mtime:   "08-10-12 14:33:32",
259*333d2b36SAndroid Build Coastguard Worker				Mode:    0644,
260*333d2b36SAndroid Build Coastguard Worker			},
261*333d2b36SAndroid Build Coastguard Worker		},
262*333d2b36SAndroid Build Coastguard Worker	},
263*333d2b36SAndroid Build Coastguard Worker	// Largest possible non-zip64 file, with no zip64 header.
264*333d2b36SAndroid Build Coastguard Worker	{
265*333d2b36SAndroid Build Coastguard Worker		Name:   "big.zip",
266*333d2b36SAndroid Build Coastguard Worker		Source: returnBigZipBytes,
267*333d2b36SAndroid Build Coastguard Worker		File: []ZipTestFile{
268*333d2b36SAndroid Build Coastguard Worker			{
269*333d2b36SAndroid Build Coastguard Worker				Name:    "big.file",
270*333d2b36SAndroid Build Coastguard Worker				Content: nil,
271*333d2b36SAndroid Build Coastguard Worker				Size:    1<<32 - 1,
272*333d2b36SAndroid Build Coastguard Worker				Mode:    0666,
273*333d2b36SAndroid Build Coastguard Worker			},
274*333d2b36SAndroid Build Coastguard Worker		},
275*333d2b36SAndroid Build Coastguard Worker	},
276*333d2b36SAndroid Build Coastguard Worker}
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Workervar crossPlatform = []ZipTestFile{
279*333d2b36SAndroid Build Coastguard Worker	{
280*333d2b36SAndroid Build Coastguard Worker		Name:    "hello",
281*333d2b36SAndroid Build Coastguard Worker		Content: []byte("world \r\n"),
282*333d2b36SAndroid Build Coastguard Worker		Mode:    0666,
283*333d2b36SAndroid Build Coastguard Worker	},
284*333d2b36SAndroid Build Coastguard Worker	{
285*333d2b36SAndroid Build Coastguard Worker		Name:    "dir/bar",
286*333d2b36SAndroid Build Coastguard Worker		Content: []byte("foo \r\n"),
287*333d2b36SAndroid Build Coastguard Worker		Mode:    0666,
288*333d2b36SAndroid Build Coastguard Worker	},
289*333d2b36SAndroid Build Coastguard Worker	{
290*333d2b36SAndroid Build Coastguard Worker		Name:    "dir/empty/",
291*333d2b36SAndroid Build Coastguard Worker		Content: []byte{},
292*333d2b36SAndroid Build Coastguard Worker		Mode:    os.ModeDir | 0777,
293*333d2b36SAndroid Build Coastguard Worker	},
294*333d2b36SAndroid Build Coastguard Worker	{
295*333d2b36SAndroid Build Coastguard Worker		Name:    "readonly",
296*333d2b36SAndroid Build Coastguard Worker		Content: []byte("important \r\n"),
297*333d2b36SAndroid Build Coastguard Worker		Mode:    0444,
298*333d2b36SAndroid Build Coastguard Worker	},
299*333d2b36SAndroid Build Coastguard Worker}
300*333d2b36SAndroid Build Coastguard Worker
301*333d2b36SAndroid Build Coastguard Workerfunc TestReader(t *testing.T) {
302*333d2b36SAndroid Build Coastguard Worker	for _, zt := range tests {
303*333d2b36SAndroid Build Coastguard Worker		readTestZip(t, zt)
304*333d2b36SAndroid Build Coastguard Worker	}
305*333d2b36SAndroid Build Coastguard Worker}
306*333d2b36SAndroid Build Coastguard Worker
307*333d2b36SAndroid Build Coastguard Workerfunc readTestZip(t *testing.T, zt ZipTest) {
308*333d2b36SAndroid Build Coastguard Worker	var z *Reader
309*333d2b36SAndroid Build Coastguard Worker	var err error
310*333d2b36SAndroid Build Coastguard Worker	if zt.Source != nil {
311*333d2b36SAndroid Build Coastguard Worker		rat, size := zt.Source()
312*333d2b36SAndroid Build Coastguard Worker		z, err = NewReader(rat, size)
313*333d2b36SAndroid Build Coastguard Worker	} else {
314*333d2b36SAndroid Build Coastguard Worker		var rc *ReadCloser
315*333d2b36SAndroid Build Coastguard Worker		rc, err = OpenReader(filepath.Join("testdata", zt.Name))
316*333d2b36SAndroid Build Coastguard Worker		if err == nil {
317*333d2b36SAndroid Build Coastguard Worker			defer rc.Close()
318*333d2b36SAndroid Build Coastguard Worker			z = &rc.Reader
319*333d2b36SAndroid Build Coastguard Worker		}
320*333d2b36SAndroid Build Coastguard Worker	}
321*333d2b36SAndroid Build Coastguard Worker	if err != zt.Error {
322*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error)
323*333d2b36SAndroid Build Coastguard Worker		return
324*333d2b36SAndroid Build Coastguard Worker	}
325*333d2b36SAndroid Build Coastguard Worker
326*333d2b36SAndroid Build Coastguard Worker	// bail if file is not zip
327*333d2b36SAndroid Build Coastguard Worker	if err == ErrFormat {
328*333d2b36SAndroid Build Coastguard Worker		return
329*333d2b36SAndroid Build Coastguard Worker	}
330*333d2b36SAndroid Build Coastguard Worker
331*333d2b36SAndroid Build Coastguard Worker	// bail here if no Files expected to be tested
332*333d2b36SAndroid Build Coastguard Worker	// (there may actually be files in the zip, but we don't care)
333*333d2b36SAndroid Build Coastguard Worker	if zt.File == nil {
334*333d2b36SAndroid Build Coastguard Worker		return
335*333d2b36SAndroid Build Coastguard Worker	}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker	if z.Comment != zt.Comment {
338*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
339*333d2b36SAndroid Build Coastguard Worker	}
340*333d2b36SAndroid Build Coastguard Worker	if len(z.File) != len(zt.File) {
341*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
342*333d2b36SAndroid Build Coastguard Worker	}
343*333d2b36SAndroid Build Coastguard Worker
344*333d2b36SAndroid Build Coastguard Worker	// test read of each file
345*333d2b36SAndroid Build Coastguard Worker	for i, ft := range zt.File {
346*333d2b36SAndroid Build Coastguard Worker		readTestFile(t, zt, ft, z.File[i])
347*333d2b36SAndroid Build Coastguard Worker	}
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Worker	// test simultaneous reads
350*333d2b36SAndroid Build Coastguard Worker	n := 0
351*333d2b36SAndroid Build Coastguard Worker	done := make(chan bool)
352*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < 5; i++ {
353*333d2b36SAndroid Build Coastguard Worker		for j, ft := range zt.File {
354*333d2b36SAndroid Build Coastguard Worker			go func(j int, ft ZipTestFile) {
355*333d2b36SAndroid Build Coastguard Worker				readTestFile(t, zt, ft, z.File[j])
356*333d2b36SAndroid Build Coastguard Worker				done <- true
357*333d2b36SAndroid Build Coastguard Worker			}(j, ft)
358*333d2b36SAndroid Build Coastguard Worker			n++
359*333d2b36SAndroid Build Coastguard Worker		}
360*333d2b36SAndroid Build Coastguard Worker	}
361*333d2b36SAndroid Build Coastguard Worker	for ; n > 0; n-- {
362*333d2b36SAndroid Build Coastguard Worker		<-done
363*333d2b36SAndroid Build Coastguard Worker	}
364*333d2b36SAndroid Build Coastguard Worker}
365*333d2b36SAndroid Build Coastguard Worker
366*333d2b36SAndroid Build Coastguard Workerfunc readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
367*333d2b36SAndroid Build Coastguard Worker	if f.Name != ft.Name {
368*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: name=%q, want %q", zt.Name, f.Name, ft.Name)
369*333d2b36SAndroid Build Coastguard Worker	}
370*333d2b36SAndroid Build Coastguard Worker
371*333d2b36SAndroid Build Coastguard Worker	if ft.Mtime != "" {
372*333d2b36SAndroid Build Coastguard Worker		mtime, err := time.Parse("01-02-06 15:04:05", ft.Mtime)
373*333d2b36SAndroid Build Coastguard Worker		if err != nil {
374*333d2b36SAndroid Build Coastguard Worker			t.Error(err)
375*333d2b36SAndroid Build Coastguard Worker			return
376*333d2b36SAndroid Build Coastguard Worker		}
377*333d2b36SAndroid Build Coastguard Worker		if ft := f.ModTime(); !ft.Equal(mtime) {
378*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: %s: mtime=%s, want %s", zt.Name, f.Name, ft, mtime)
379*333d2b36SAndroid Build Coastguard Worker		}
380*333d2b36SAndroid Build Coastguard Worker	}
381*333d2b36SAndroid Build Coastguard Worker
382*333d2b36SAndroid Build Coastguard Worker	testFileMode(t, zt.Name, f, ft.Mode)
383*333d2b36SAndroid Build Coastguard Worker
384*333d2b36SAndroid Build Coastguard Worker	size := uint64(f.UncompressedSize)
385*333d2b36SAndroid Build Coastguard Worker	if size == uint32max {
386*333d2b36SAndroid Build Coastguard Worker		size = f.UncompressedSize64
387*333d2b36SAndroid Build Coastguard Worker	} else if size != f.UncompressedSize64 {
388*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
389*333d2b36SAndroid Build Coastguard Worker	}
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Worker	r, err := f.Open()
392*333d2b36SAndroid Build Coastguard Worker	if err != nil {
393*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: %v", zt.Name, err)
394*333d2b36SAndroid Build Coastguard Worker		return
395*333d2b36SAndroid Build Coastguard Worker	}
396*333d2b36SAndroid Build Coastguard Worker
397*333d2b36SAndroid Build Coastguard Worker	// For very large files, just check that the size is correct.
398*333d2b36SAndroid Build Coastguard Worker	// The content is expected to be all zeros.
399*333d2b36SAndroid Build Coastguard Worker	// Don't bother uncompressing: too big.
400*333d2b36SAndroid Build Coastguard Worker	if ft.Content == nil && ft.File == "" && ft.Size > 0 {
401*333d2b36SAndroid Build Coastguard Worker		if size != ft.Size {
402*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%v: uncompressed size %#x, want %#x", ft.Name, size, ft.Size)
403*333d2b36SAndroid Build Coastguard Worker		}
404*333d2b36SAndroid Build Coastguard Worker		r.Close()
405*333d2b36SAndroid Build Coastguard Worker		return
406*333d2b36SAndroid Build Coastguard Worker	}
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker	var b bytes.Buffer
409*333d2b36SAndroid Build Coastguard Worker	_, err = io.Copy(&b, r)
410*333d2b36SAndroid Build Coastguard Worker	if err != ft.ContentErr {
411*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
412*333d2b36SAndroid Build Coastguard Worker	}
413*333d2b36SAndroid Build Coastguard Worker	if err != nil {
414*333d2b36SAndroid Build Coastguard Worker		return
415*333d2b36SAndroid Build Coastguard Worker	}
416*333d2b36SAndroid Build Coastguard Worker	r.Close()
417*333d2b36SAndroid Build Coastguard Worker
418*333d2b36SAndroid Build Coastguard Worker	if g := uint64(b.Len()); g != size {
419*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
420*333d2b36SAndroid Build Coastguard Worker	}
421*333d2b36SAndroid Build Coastguard Worker
422*333d2b36SAndroid Build Coastguard Worker	var c []byte
423*333d2b36SAndroid Build Coastguard Worker	if ft.Content != nil {
424*333d2b36SAndroid Build Coastguard Worker		c = ft.Content
425*333d2b36SAndroid Build Coastguard Worker	} else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil {
426*333d2b36SAndroid Build Coastguard Worker		t.Error(err)
427*333d2b36SAndroid Build Coastguard Worker		return
428*333d2b36SAndroid Build Coastguard Worker	}
429*333d2b36SAndroid Build Coastguard Worker
430*333d2b36SAndroid Build Coastguard Worker	if b.Len() != len(c) {
431*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: len=%d, want %d", f.Name, b.Len(), len(c))
432*333d2b36SAndroid Build Coastguard Worker		return
433*333d2b36SAndroid Build Coastguard Worker	}
434*333d2b36SAndroid Build Coastguard Worker
435*333d2b36SAndroid Build Coastguard Worker	for i, b := range b.Bytes() {
436*333d2b36SAndroid Build Coastguard Worker		if b != c[i] {
437*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: content[%d]=%q want %q", f.Name, i, b, c[i])
438*333d2b36SAndroid Build Coastguard Worker			return
439*333d2b36SAndroid Build Coastguard Worker		}
440*333d2b36SAndroid Build Coastguard Worker	}
441*333d2b36SAndroid Build Coastguard Worker}
442*333d2b36SAndroid Build Coastguard Worker
443*333d2b36SAndroid Build Coastguard Workerfunc testFileMode(t *testing.T, zipName string, f *File, want os.FileMode) {
444*333d2b36SAndroid Build Coastguard Worker	mode := f.Mode()
445*333d2b36SAndroid Build Coastguard Worker	if want == 0 {
446*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: %s mode: got %v, want none", zipName, f.Name, mode)
447*333d2b36SAndroid Build Coastguard Worker	} else if mode != want {
448*333d2b36SAndroid Build Coastguard Worker		t.Errorf("%s: %s mode: want %v, got %v", zipName, f.Name, want, mode)
449*333d2b36SAndroid Build Coastguard Worker	}
450*333d2b36SAndroid Build Coastguard Worker}
451*333d2b36SAndroid Build Coastguard Worker
452*333d2b36SAndroid Build Coastguard Workerfunc TestInvalidFiles(t *testing.T) {
453*333d2b36SAndroid Build Coastguard Worker	const size = 1024 * 70 // 70kb
454*333d2b36SAndroid Build Coastguard Worker	b := make([]byte, size)
455*333d2b36SAndroid Build Coastguard Worker
456*333d2b36SAndroid Build Coastguard Worker	// zeroes
457*333d2b36SAndroid Build Coastguard Worker	_, err := NewReader(bytes.NewReader(b), size)
458*333d2b36SAndroid Build Coastguard Worker	if err != ErrFormat {
459*333d2b36SAndroid Build Coastguard Worker		t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
460*333d2b36SAndroid Build Coastguard Worker	}
461*333d2b36SAndroid Build Coastguard Worker
462*333d2b36SAndroid Build Coastguard Worker	// repeated directoryEndSignatures
463*333d2b36SAndroid Build Coastguard Worker	sig := make([]byte, 4)
464*333d2b36SAndroid Build Coastguard Worker	binary.LittleEndian.PutUint32(sig, directoryEndSignature)
465*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < size-4; i += 4 {
466*333d2b36SAndroid Build Coastguard Worker		copy(b[i:i+4], sig)
467*333d2b36SAndroid Build Coastguard Worker	}
468*333d2b36SAndroid Build Coastguard Worker	_, err = NewReader(bytes.NewReader(b), size)
469*333d2b36SAndroid Build Coastguard Worker	if err != ErrFormat {
470*333d2b36SAndroid Build Coastguard Worker		t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
471*333d2b36SAndroid Build Coastguard Worker	}
472*333d2b36SAndroid Build Coastguard Worker}
473*333d2b36SAndroid Build Coastguard Worker
474*333d2b36SAndroid Build Coastguard Workerfunc messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
475*333d2b36SAndroid Build Coastguard Worker	data, err := ioutil.ReadFile(filepath.Join("testdata", fileName))
476*333d2b36SAndroid Build Coastguard Worker	if err != nil {
477*333d2b36SAndroid Build Coastguard Worker		panic("Error reading " + fileName + ": " + err.Error())
478*333d2b36SAndroid Build Coastguard Worker	}
479*333d2b36SAndroid Build Coastguard Worker	corrupter(data)
480*333d2b36SAndroid Build Coastguard Worker	return bytes.NewReader(data), int64(len(data))
481*333d2b36SAndroid Build Coastguard Worker}
482*333d2b36SAndroid Build Coastguard Worker
483*333d2b36SAndroid Build Coastguard Workerfunc returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
484*333d2b36SAndroid Build Coastguard Worker	return messWith("go-with-datadesc-sig.zip", func(b []byte) {
485*333d2b36SAndroid Build Coastguard Worker		// Corrupt one of the CRC32s in the data descriptor:
486*333d2b36SAndroid Build Coastguard Worker		b[0x2d]++
487*333d2b36SAndroid Build Coastguard Worker	})
488*333d2b36SAndroid Build Coastguard Worker}
489*333d2b36SAndroid Build Coastguard Worker
490*333d2b36SAndroid Build Coastguard Workerfunc returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
491*333d2b36SAndroid Build Coastguard Worker	return messWith("crc32-not-streamed.zip", func(b []byte) {
492*333d2b36SAndroid Build Coastguard Worker		// Corrupt foo.txt's final crc32 byte, in both
493*333d2b36SAndroid Build Coastguard Worker		// the file header and TOC. (0x7e -> 0x7f)
494*333d2b36SAndroid Build Coastguard Worker		b[0x11]++
495*333d2b36SAndroid Build Coastguard Worker		b[0x9d]++
496*333d2b36SAndroid Build Coastguard Worker
497*333d2b36SAndroid Build Coastguard Worker		// TODO(bradfitz): add a new test that only corrupts
498*333d2b36SAndroid Build Coastguard Worker		// one of these values, and verify that that's also an
499*333d2b36SAndroid Build Coastguard Worker		// error. Currently, the reader code doesn't verify the
500*333d2b36SAndroid Build Coastguard Worker		// fileheader and TOC's crc32 match if they're both
501*333d2b36SAndroid Build Coastguard Worker		// non-zero and only the second line above, the TOC,
502*333d2b36SAndroid Build Coastguard Worker		// is what matters.
503*333d2b36SAndroid Build Coastguard Worker	})
504*333d2b36SAndroid Build Coastguard Worker}
505*333d2b36SAndroid Build Coastguard Worker
506*333d2b36SAndroid Build Coastguard Worker// rZipBytes returns the bytes of a recursive zip file, without
507*333d2b36SAndroid Build Coastguard Worker// putting it on disk and triggering certain virus scanners.
508*333d2b36SAndroid Build Coastguard Workerfunc rZipBytes() []byte {
509*333d2b36SAndroid Build Coastguard Worker	s := `
510*333d2b36SAndroid Build Coastguard Worker0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
511*333d2b36SAndroid Build Coastguard Worker0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
512*333d2b36SAndroid Build Coastguard Worker0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
513*333d2b36SAndroid Build Coastguard Worker0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
514*333d2b36SAndroid Build Coastguard Worker0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
515*333d2b36SAndroid Build Coastguard Worker0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
516*333d2b36SAndroid Build Coastguard Worker0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
517*333d2b36SAndroid Build Coastguard Worker0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
518*333d2b36SAndroid Build Coastguard Worker0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
519*333d2b36SAndroid Build Coastguard Worker0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
520*333d2b36SAndroid Build Coastguard Worker00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
521*333d2b36SAndroid Build Coastguard Worker00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
522*333d2b36SAndroid Build Coastguard Worker00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
523*333d2b36SAndroid Build Coastguard Worker00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
524*333d2b36SAndroid Build Coastguard Worker00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
525*333d2b36SAndroid Build Coastguard Worker00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
526*333d2b36SAndroid Build Coastguard Worker0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
527*333d2b36SAndroid Build Coastguard Worker0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
528*333d2b36SAndroid Build Coastguard Worker0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
529*333d2b36SAndroid Build Coastguard Worker0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
530*333d2b36SAndroid Build Coastguard Worker0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
531*333d2b36SAndroid Build Coastguard Worker0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
532*333d2b36SAndroid Build Coastguard Worker0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
533*333d2b36SAndroid Build Coastguard Worker0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
534*333d2b36SAndroid Build Coastguard Worker0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
535*333d2b36SAndroid Build Coastguard Worker0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
536*333d2b36SAndroid Build Coastguard Worker00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
537*333d2b36SAndroid Build Coastguard Worker00001b0 00 00 6d 01 00 00 00 00`
538*333d2b36SAndroid Build Coastguard Worker	s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
539*333d2b36SAndroid Build Coastguard Worker	s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
540*333d2b36SAndroid Build Coastguard Worker	b, err := hex.DecodeString(s)
541*333d2b36SAndroid Build Coastguard Worker	if err != nil {
542*333d2b36SAndroid Build Coastguard Worker		panic(err)
543*333d2b36SAndroid Build Coastguard Worker	}
544*333d2b36SAndroid Build Coastguard Worker	return b
545*333d2b36SAndroid Build Coastguard Worker}
546*333d2b36SAndroid Build Coastguard Worker
547*333d2b36SAndroid Build Coastguard Workerfunc returnRecursiveZip() (r io.ReaderAt, size int64) {
548*333d2b36SAndroid Build Coastguard Worker	b := rZipBytes()
549*333d2b36SAndroid Build Coastguard Worker	return bytes.NewReader(b), int64(len(b))
550*333d2b36SAndroid Build Coastguard Worker}
551*333d2b36SAndroid Build Coastguard Worker
552*333d2b36SAndroid Build Coastguard Worker// biggestZipBytes returns the bytes of a zip file biggest.zip
553*333d2b36SAndroid Build Coastguard Worker// that contains a zip file bigger.zip that contains a zip file
554*333d2b36SAndroid Build Coastguard Worker// big.zip that contains big.file, which contains 2³²-1 zeros.
555*333d2b36SAndroid Build Coastguard Worker// The big.zip file is interesting because it has no zip64 header,
556*333d2b36SAndroid Build Coastguard Worker// much like the innermost zip files in the well-known 42.zip.
557*333d2b36SAndroid Build Coastguard Worker//
558*333d2b36SAndroid Build Coastguard Worker// biggest.zip was generated by changing isZip64 to use > uint32max
559*333d2b36SAndroid Build Coastguard Worker// instead of >= uint32max and then running this program:
560*333d2b36SAndroid Build Coastguard Worker//
561*333d2b36SAndroid Build Coastguard Worker//	package main
562*333d2b36SAndroid Build Coastguard Worker//
563*333d2b36SAndroid Build Coastguard Worker//	import (
564*333d2b36SAndroid Build Coastguard Worker//		"archive/zip"
565*333d2b36SAndroid Build Coastguard Worker//		"bytes"
566*333d2b36SAndroid Build Coastguard Worker//		"io"
567*333d2b36SAndroid Build Coastguard Worker//		"io/ioutil"
568*333d2b36SAndroid Build Coastguard Worker//		"log"
569*333d2b36SAndroid Build Coastguard Worker//	)
570*333d2b36SAndroid Build Coastguard Worker//
571*333d2b36SAndroid Build Coastguard Worker//	type zeros struct{}
572*333d2b36SAndroid Build Coastguard Worker//
573*333d2b36SAndroid Build Coastguard Worker//	func (zeros) Read(b []byte) (int, error) {
574*333d2b36SAndroid Build Coastguard Worker//		for i := range b {
575*333d2b36SAndroid Build Coastguard Worker//			b[i] = 0
576*333d2b36SAndroid Build Coastguard Worker//		}
577*333d2b36SAndroid Build Coastguard Worker//		return len(b), nil
578*333d2b36SAndroid Build Coastguard Worker//	}
579*333d2b36SAndroid Build Coastguard Worker//
580*333d2b36SAndroid Build Coastguard Worker//	func main() {
581*333d2b36SAndroid Build Coastguard Worker//		bigZip := makeZip("big.file", io.LimitReader(zeros{}, 1<<32-1))
582*333d2b36SAndroid Build Coastguard Worker//		if err := ioutil.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil {
583*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
584*333d2b36SAndroid Build Coastguard Worker//		}
585*333d2b36SAndroid Build Coastguard Worker//
586*333d2b36SAndroid Build Coastguard Worker//		biggerZip := makeZip("big.zip", bytes.NewReader(bigZip))
587*333d2b36SAndroid Build Coastguard Worker//		if err := ioutil.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil {
588*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
589*333d2b36SAndroid Build Coastguard Worker//		}
590*333d2b36SAndroid Build Coastguard Worker//
591*333d2b36SAndroid Build Coastguard Worker//		biggestZip := makeZip("bigger.zip", bytes.NewReader(biggerZip))
592*333d2b36SAndroid Build Coastguard Worker//		if err := ioutil.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil {
593*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
594*333d2b36SAndroid Build Coastguard Worker//		}
595*333d2b36SAndroid Build Coastguard Worker//	}
596*333d2b36SAndroid Build Coastguard Worker//
597*333d2b36SAndroid Build Coastguard Worker//	func makeZip(name string, r io.Reader) []byte {
598*333d2b36SAndroid Build Coastguard Worker//		var buf bytes.Buffer
599*333d2b36SAndroid Build Coastguard Worker//		w := zip.NewWriter(&buf)
600*333d2b36SAndroid Build Coastguard Worker//		wf, err := w.Create(name)
601*333d2b36SAndroid Build Coastguard Worker//		if err != nil {
602*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
603*333d2b36SAndroid Build Coastguard Worker//		}
604*333d2b36SAndroid Build Coastguard Worker//		if _, err = io.Copy(wf, r); err != nil {
605*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
606*333d2b36SAndroid Build Coastguard Worker//		}
607*333d2b36SAndroid Build Coastguard Worker//		if err := w.Close(); err != nil {
608*333d2b36SAndroid Build Coastguard Worker//			log.Fatal(err)
609*333d2b36SAndroid Build Coastguard Worker//		}
610*333d2b36SAndroid Build Coastguard Worker//		return buf.Bytes()
611*333d2b36SAndroid Build Coastguard Worker//	}
612*333d2b36SAndroid Build Coastguard Worker//
613*333d2b36SAndroid Build Coastguard Worker// The 4 GB of zeros compresses to 4 MB, which compresses to 20 kB,
614*333d2b36SAndroid Build Coastguard Worker// which compresses to 1252 bytes (in the hex dump below).
615*333d2b36SAndroid Build Coastguard Worker//
616*333d2b36SAndroid Build Coastguard Worker// It's here in hex for the same reason as rZipBytes above: to avoid
617*333d2b36SAndroid Build Coastguard Worker// problems with on-disk virus scanners or other zip processors.
618*333d2b36SAndroid Build Coastguard Workerfunc biggestZipBytes() []byte {
619*333d2b36SAndroid Build Coastguard Worker	s := `
620*333d2b36SAndroid Build Coastguard Worker0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
621*333d2b36SAndroid Build Coastguard Worker0000010 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 62 69
622*333d2b36SAndroid Build Coastguard Worker0000020 67 67 65 72 2e 7a 69 70 ec dc 6b 4c 53 67 18 07
623*333d2b36SAndroid Build Coastguard Worker0000030 f0 16 c5 ca 65 2e cb b8 94 20 61 1f 44 33 c7 cd
624*333d2b36SAndroid Build Coastguard Worker0000040 c0 86 4a b5 c0 62 8a 61 05 c6 cd 91 b2 54 8c 1b
625*333d2b36SAndroid Build Coastguard Worker0000050 63 8b 03 9c 1b 95 52 5a e3 a0 19 6c b2 05 59 44
626*333d2b36SAndroid Build Coastguard Worker0000060 64 9d 73 83 71 11 46 61 14 b9 1d 14 09 4a c3 60
627*333d2b36SAndroid Build Coastguard Worker0000070 2e 4c 6e a5 60 45 02 62 81 95 b6 94 9e 9e 77 e7
628*333d2b36SAndroid Build Coastguard Worker0000080 d0 43 b6 f8 71 df 96 3c e7 a4 69 ce bf cf e9 79
629*333d2b36SAndroid Build Coastguard Worker0000090 ce ef 79 3f bf f1 31 db b6 bb 31 76 92 e7 f3 07
630*333d2b36SAndroid Build Coastguard Worker00000a0 8b fc 9c ca cc 08 cc cb cc 5e d2 1c 88 d9 7e bb
631*333d2b36SAndroid Build Coastguard Worker00000b0 4f bb 3a 3f 75 f1 5d 7f 8f c2 68 67 77 8f 25 ff
632*333d2b36SAndroid Build Coastguard Worker00000c0 84 e2 93 2d ef a4 95 3d 71 4e 2c b9 b0 87 c3 be
633*333d2b36SAndroid Build Coastguard Worker00000d0 3d f8 a7 60 24 61 c5 ef ae 9e c8 6c 6d 4e 69 c8
634*333d2b36SAndroid Build Coastguard Worker00000e0 67 65 34 f8 37 76 2d 76 5c 54 f3 95 65 49 c7 0f
635*333d2b36SAndroid Build Coastguard Worker00000f0 18 71 4b 7e 5b 6a d1 79 47 61 41 b0 4e 2a 74 45
636*333d2b36SAndroid Build Coastguard Worker0000100 43 58 12 b2 5a a5 c6 7d 68 55 88 d4 98 75 18 6d
637*333d2b36SAndroid Build Coastguard Worker0000110 08 d1 1f 8f 5a 9e 96 ee 45 cf a4 84 4e 4b e8 50
638*333d2b36SAndroid Build Coastguard Worker0000120 a7 13 d9 06 de 52 81 97 36 b2 d7 b8 fc 2b 5f 55
639*333d2b36SAndroid Build Coastguard Worker0000130 23 1f 32 59 cf 30 27 fb e2 8a b9 de 45 dd 63 9c
640*333d2b36SAndroid Build Coastguard Worker0000140 4b b5 8b 96 4c 7a 62 62 cc a1 a7 cf fa f1 fe dd
641*333d2b36SAndroid Build Coastguard Worker0000150 54 62 11 bf 36 78 b3 c7 b1 b5 f2 61 4d 4e dd 66
642*333d2b36SAndroid Build Coastguard Worker0000160 32 2e e6 70 34 5f f4 c9 e6 6c 43 6f da 6b c6 c3
643*333d2b36SAndroid Build Coastguard Worker0000170 09 2c ce 09 57 7f d2 7e b4 23 ba 7c 1b 99 bc 22
644*333d2b36SAndroid Build Coastguard Worker0000180 3e f1 de 91 2f e3 9c 1b 82 cc c2 84 39 aa e6 de
645*333d2b36SAndroid Build Coastguard Worker0000190 b4 69 fc cc cb 72 a6 61 45 f0 d3 1d 26 19 7c 8d
646*333d2b36SAndroid Build Coastguard Worker00001a0 29 c8 66 02 be 77 6a f9 3d 34 79 17 19 c8 96 24
647*333d2b36SAndroid Build Coastguard Worker00001b0 a3 ac e4 dd 3b 1a 8e c6 fe 96 38 6b bf 67 5a 23
648*333d2b36SAndroid Build Coastguard Worker00001c0 f4 16 f4 e6 8a b4 fc c2 cd bf 95 66 1d bb 35 aa
649*333d2b36SAndroid Build Coastguard Worker00001d0 92 7d 66 d8 08 8d a5 1f 54 2a af 09 cf 61 ff d2
650*333d2b36SAndroid Build Coastguard Worker00001e0 85 9d 8f b6 d7 88 07 4a 86 03 db 64 f3 d9 92 73
651*333d2b36SAndroid Build Coastguard Worker00001f0 df ec a7 fc 23 4c 8d 83 79 63 2a d9 fd 8d b3 c8
652*333d2b36SAndroid Build Coastguard Worker0000200 8f 7e d4 19 85 e6 8d 1c 76 f0 8b 58 32 fd 9a d6
653*333d2b36SAndroid Build Coastguard Worker0000210 85 e2 48 ad c3 d5 60 6f 7e 22 dd ef 09 49 7c 7f
654*333d2b36SAndroid Build Coastguard Worker0000220 3a 45 c3 71 b7 df f3 4c 63 fb b5 d9 31 5f 6e d6
655*333d2b36SAndroid Build Coastguard Worker0000230 24 1d a4 4a fe 32 a7 5c 16 48 5c 3e 08 6b 8a d3
656*333d2b36SAndroid Build Coastguard Worker0000240 25 1d a2 12 a5 59 24 ea 20 5f 52 6d ad 94 db 6b
657*333d2b36SAndroid Build Coastguard Worker0000250 94 b9 5d eb 4b a7 5c 44 bb 1e f2 3c 6b cf 52 c9
658*333d2b36SAndroid Build Coastguard Worker0000260 e9 e5 ba 06 b9 c4 e5 0a d0 00 0d d0 00 0d d0 00
659*333d2b36SAndroid Build Coastguard Worker0000270 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d
660*333d2b36SAndroid Build Coastguard Worker0000280 d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0
661*333d2b36SAndroid Build Coastguard Worker0000290 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00
662*333d2b36SAndroid Build Coastguard Worker00002a0 0d d0 00 cd ff 9e 46 86 fa a7 7d 3a 43 d7 8e 10
663*333d2b36SAndroid Build Coastguard Worker00002b0 52 e9 be e6 6e cf eb 9e 85 4d 65 ce cc 30 c1 44
664*333d2b36SAndroid Build Coastguard Worker00002c0 c0 4e af bc 9c 6c 4b a0 d7 54 ff 1d d5 5c 89 fb
665*333d2b36SAndroid Build Coastguard Worker00002d0 b5 34 7e c4 c2 9e f5 a0 f6 5b 7e 6e ca 73 c7 ef
666*333d2b36SAndroid Build Coastguard Worker00002e0 5d be de f9 e8 81 eb a5 0a a5 63 54 2c d7 1c d1
667*333d2b36SAndroid Build Coastguard Worker00002f0 89 17 85 f8 16 94 f2 8a b2 a3 f5 b6 6d df 75 cd
668*333d2b36SAndroid Build Coastguard Worker0000300 90 dd 64 bd 5d 55 4e f2 55 19 1b b7 cc ef 1b ea
669*333d2b36SAndroid Build Coastguard Worker0000310 2e 05 9c f4 aa 1e a8 cd a6 82 c7 59 0f 5e 9d e0
670*333d2b36SAndroid Build Coastguard Worker0000320 bb fc 6c d6 99 23 eb 36 ad c6 c5 e1 d8 e1 e2 3e
671*333d2b36SAndroid Build Coastguard Worker0000330 d9 90 5a f7 91 5d 6f bc 33 6d 98 47 d2 7c 2e 2f
672*333d2b36SAndroid Build Coastguard Worker0000340 99 a4 25 72 85 49 2c be 0b 5b af 8f e5 6e 81 a6
673*333d2b36SAndroid Build Coastguard Worker0000350 a3 5a 6f 39 53 3a ab 7a 8b 1e 26 f7 46 6c 7d 26
674*333d2b36SAndroid Build Coastguard Worker0000360 53 b3 22 31 94 d3 83 f2 18 4d f5 92 33 27 53 97
675*333d2b36SAndroid Build Coastguard Worker0000370 0f d3 e6 55 9c a6 c5 31 87 6f d3 f3 ae 39 6f 56
676*333d2b36SAndroid Build Coastguard Worker0000380 10 7b ab 7e d0 b4 ca f2 b8 05 be 3f 0e 6e 5a 75
677*333d2b36SAndroid Build Coastguard Worker0000390 ab 0c f5 37 0e ba 8e 75 71 7a aa ed 7a dd 6a 63
678*333d2b36SAndroid Build Coastguard Worker00003a0 be 9b a0 97 27 6a 6f e7 d3 8b c4 7c ec d3 91 56
679*333d2b36SAndroid Build Coastguard Worker00003b0 d9 ac 5e bf 16 42 2f 00 1f 93 a2 23 87 bd e2 59
680*333d2b36SAndroid Build Coastguard Worker00003c0 a0 de 1a 66 c8 62 eb 55 8f 91 17 b4 61 42 7a 50
681*333d2b36SAndroid Build Coastguard Worker00003d0 40 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40
682*333d2b36SAndroid Build Coastguard Worker00003e0 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40 03
683*333d2b36SAndroid Build Coastguard Worker00003f0 34 40 03 34 40 03 34 ff 85 86 90 8b ea 67 90 0d
684*333d2b36SAndroid Build Coastguard Worker0000400 e1 42 1b d2 61 d6 79 ec fd 3e 44 28 a4 51 6c 5c
685*333d2b36SAndroid Build Coastguard Worker0000410 fc d2 72 ca ba 82 18 46 16 61 cd 93 a9 0f d1 24
686*333d2b36SAndroid Build Coastguard Worker0000420 17 99 e2 2c 71 16 84 0c c8 7a 13 0f 9a 5e c5 f0
687*333d2b36SAndroid Build Coastguard Worker0000430 79 64 e2 12 4d c8 82 a1 81 19 2d aa 44 6d 87 54
688*333d2b36SAndroid Build Coastguard Worker0000440 84 71 c1 f6 d4 ca 25 8c 77 b9 08 c7 c8 5e 10 8a
689*333d2b36SAndroid Build Coastguard Worker0000450 8f 61 ed 8c ba 30 1f 79 9a c7 60 34 2b b9 8c f8
690*333d2b36SAndroid Build Coastguard Worker0000460 18 a6 83 1b e3 9f ad 79 fe fd 1b 8b f1 fc 41 6f
691*333d2b36SAndroid Build Coastguard Worker0000470 d4 13 1f e3 b8 83 ba 64 92 e7 eb e4 77 05 8f ba
692*333d2b36SAndroid Build Coastguard Worker0000480 fa 3b 00 00 ff ff 50 4b 07 08 a6 18 b1 91 5e 04
693*333d2b36SAndroid Build Coastguard Worker0000490 00 00 e4 47 00 00 50 4b 01 02 14 00 14 00 08 00
694*333d2b36SAndroid Build Coastguard Worker00004a0 08 00 00 00 00 00 a6 18 b1 91 5e 04 00 00 e4 47
695*333d2b36SAndroid Build Coastguard Worker00004b0 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
696*333d2b36SAndroid Build Coastguard Worker00004c0 00 00 00 00 62 69 67 67 65 72 2e 7a 69 70 50 4b
697*333d2b36SAndroid Build Coastguard Worker00004d0 05 06 00 00 00 00 01 00 01 00 38 00 00 00 96 04
698*333d2b36SAndroid Build Coastguard Worker00004e0 00 00 00 00`
699*333d2b36SAndroid Build Coastguard Worker	s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
700*333d2b36SAndroid Build Coastguard Worker	s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
701*333d2b36SAndroid Build Coastguard Worker	b, err := hex.DecodeString(s)
702*333d2b36SAndroid Build Coastguard Worker	if err != nil {
703*333d2b36SAndroid Build Coastguard Worker		panic(err)
704*333d2b36SAndroid Build Coastguard Worker	}
705*333d2b36SAndroid Build Coastguard Worker	return b
706*333d2b36SAndroid Build Coastguard Worker}
707*333d2b36SAndroid Build Coastguard Worker
708*333d2b36SAndroid Build Coastguard Workerfunc returnBigZipBytes() (r io.ReaderAt, size int64) {
709*333d2b36SAndroid Build Coastguard Worker	b := biggestZipBytes()
710*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < 2; i++ {
711*333d2b36SAndroid Build Coastguard Worker		r, err := NewReader(bytes.NewReader(b), int64(len(b)))
712*333d2b36SAndroid Build Coastguard Worker		if err != nil {
713*333d2b36SAndroid Build Coastguard Worker			panic(err)
714*333d2b36SAndroid Build Coastguard Worker		}
715*333d2b36SAndroid Build Coastguard Worker		f, err := r.File[0].Open()
716*333d2b36SAndroid Build Coastguard Worker		if err != nil {
717*333d2b36SAndroid Build Coastguard Worker			panic(err)
718*333d2b36SAndroid Build Coastguard Worker		}
719*333d2b36SAndroid Build Coastguard Worker		b, err = ioutil.ReadAll(f)
720*333d2b36SAndroid Build Coastguard Worker		if err != nil {
721*333d2b36SAndroid Build Coastguard Worker			panic(err)
722*333d2b36SAndroid Build Coastguard Worker		}
723*333d2b36SAndroid Build Coastguard Worker	}
724*333d2b36SAndroid Build Coastguard Worker	return bytes.NewReader(b), int64(len(b))
725*333d2b36SAndroid Build Coastguard Worker}
726*333d2b36SAndroid Build Coastguard Worker
727*333d2b36SAndroid Build Coastguard Workerfunc TestIssue8186(t *testing.T) {
728*333d2b36SAndroid Build Coastguard Worker	// Directory headers & data found in the TOC of a JAR file.
729*333d2b36SAndroid Build Coastguard Worker	dirEnts := []string{
730*333d2b36SAndroid Build Coastguard Worker		"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",
731*333d2b36SAndroid Build Coastguard Worker		"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",
732*333d2b36SAndroid Build Coastguard Worker		"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",
733*333d2b36SAndroid Build Coastguard Worker		"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",
734*333d2b36SAndroid Build Coastguard Worker		"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",
735*333d2b36SAndroid Build Coastguard Worker		"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",
736*333d2b36SAndroid Build Coastguard Worker		"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",
737*333d2b36SAndroid Build Coastguard Worker		"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",
738*333d2b36SAndroid Build Coastguard Worker		"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",
739*333d2b36SAndroid Build Coastguard Worker	}
740*333d2b36SAndroid Build Coastguard Worker	for i, s := range dirEnts {
741*333d2b36SAndroid Build Coastguard Worker		var f File
742*333d2b36SAndroid Build Coastguard Worker		err := readDirectoryHeader(&f, strings.NewReader(s))
743*333d2b36SAndroid Build Coastguard Worker		if err != nil {
744*333d2b36SAndroid Build Coastguard Worker			t.Errorf("error reading #%d: %v", i, err)
745*333d2b36SAndroid Build Coastguard Worker		}
746*333d2b36SAndroid Build Coastguard Worker	}
747*333d2b36SAndroid Build Coastguard Worker}
748*333d2b36SAndroid Build Coastguard Worker
749*333d2b36SAndroid Build Coastguard Worker// Verify we return ErrUnexpectedEOF when length is short.
750*333d2b36SAndroid Build Coastguard Workerfunc TestIssue10957(t *testing.T) {
751*333d2b36SAndroid Build Coastguard Worker	data := []byte("PK\x03\x040000000PK\x01\x0200000" +
752*333d2b36SAndroid Build Coastguard Worker		"0000000000000000000\x00" +
753*333d2b36SAndroid Build Coastguard Worker		"\x00\x00\x00\x00\x00000000000000PK\x01" +
754*333d2b36SAndroid Build Coastguard Worker		"\x020000000000000000000" +
755*333d2b36SAndroid Build Coastguard Worker		"00000\v\x00\x00\x00\x00\x00000000000" +
756*333d2b36SAndroid Build Coastguard Worker		"00000000000000PK\x01\x0200" +
757*333d2b36SAndroid Build Coastguard Worker		"00000000000000000000" +
758*333d2b36SAndroid Build Coastguard Worker		"00\v\x00\x00\x00\x00\x00000000000000" +
759*333d2b36SAndroid Build Coastguard Worker		"00000000000PK\x01\x020000<" +
760*333d2b36SAndroid Build Coastguard Worker		"0\x00\x0000000000000000\v\x00\v" +
761*333d2b36SAndroid Build Coastguard Worker		"\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
762*333d2b36SAndroid Build Coastguard Worker		"00000000PK\x01\x0200000000" +
763*333d2b36SAndroid Build Coastguard Worker		"0000000000000000\v\x00\x00\x00" +
764*333d2b36SAndroid Build Coastguard Worker		"\x00\x0000PK\x05\x06000000\x05\x000000" +
765*333d2b36SAndroid Build Coastguard Worker		"\v\x00\x00\x00\x00\x00")
766*333d2b36SAndroid Build Coastguard Worker	z, err := NewReader(bytes.NewReader(data), int64(len(data)))
767*333d2b36SAndroid Build Coastguard Worker	if err != nil {
768*333d2b36SAndroid Build Coastguard Worker		t.Fatal(err)
769*333d2b36SAndroid Build Coastguard Worker	}
770*333d2b36SAndroid Build Coastguard Worker	for i, f := range z.File {
771*333d2b36SAndroid Build Coastguard Worker		r, err := f.Open()
772*333d2b36SAndroid Build Coastguard Worker		if err != nil {
773*333d2b36SAndroid Build Coastguard Worker			continue
774*333d2b36SAndroid Build Coastguard Worker		}
775*333d2b36SAndroid Build Coastguard Worker		if f.UncompressedSize64 < 1e6 {
776*333d2b36SAndroid Build Coastguard Worker			n, err := io.Copy(ioutil.Discard, r)
777*333d2b36SAndroid Build Coastguard Worker			if i == 3 && err != io.ErrUnexpectedEOF {
778*333d2b36SAndroid Build Coastguard Worker				t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
779*333d2b36SAndroid Build Coastguard Worker			}
780*333d2b36SAndroid Build Coastguard Worker			if err == nil && uint64(n) != f.UncompressedSize64 {
781*333d2b36SAndroid Build Coastguard Worker				t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
782*333d2b36SAndroid Build Coastguard Worker			}
783*333d2b36SAndroid Build Coastguard Worker		}
784*333d2b36SAndroid Build Coastguard Worker		r.Close()
785*333d2b36SAndroid Build Coastguard Worker	}
786*333d2b36SAndroid Build Coastguard Worker}
787*333d2b36SAndroid Build Coastguard Worker
788*333d2b36SAndroid Build Coastguard Worker// Verify the number of files is within expected bounds
789*333d2b36SAndroid Build Coastguard Workerfunc TestIssue10956(t *testing.T) {
790*333d2b36SAndroid Build Coastguard Worker	data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
791*333d2b36SAndroid Build Coastguard Worker		"0000PK\x05\x06000000000000" +
792*333d2b36SAndroid Build Coastguard Worker		"0000\v\x00000\x00\x00\x00\x00\x00\x00\x000")
793*333d2b36SAndroid Build Coastguard Worker	_, err := NewReader(bytes.NewReader(data), int64(len(data)))
794*333d2b36SAndroid Build Coastguard Worker	const want = "TOC declares impossible 3472328296227680304 files in 57 byte"
795*333d2b36SAndroid Build Coastguard Worker	if err == nil && !strings.Contains(err.Error(), want) {
796*333d2b36SAndroid Build Coastguard Worker		t.Errorf("error = %v; want %q", err, want)
797*333d2b36SAndroid Build Coastguard Worker	}
798*333d2b36SAndroid Build Coastguard Worker}
799*333d2b36SAndroid Build Coastguard Worker
800*333d2b36SAndroid Build Coastguard Worker// Verify we return ErrUnexpectedEOF when reading truncated data descriptor.
801*333d2b36SAndroid Build Coastguard Workerfunc TestIssue11146(t *testing.T) {
802*333d2b36SAndroid Build Coastguard Worker	data := []byte("PK\x03\x040000000000000000" +
803*333d2b36SAndroid Build Coastguard Worker		"000000\x01\x00\x00\x000\x01\x00\x00\xff\xff0000" +
804*333d2b36SAndroid Build Coastguard Worker		"0000000000000000PK\x01\x02" +
805*333d2b36SAndroid Build Coastguard Worker		"0000\b0\b\x00000000000000" +
806*333d2b36SAndroid Build Coastguard Worker		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000PK\x05\x06\x00\x00" +
807*333d2b36SAndroid Build Coastguard Worker		"\x00\x0000\x01\x0000008\x00\x00\x00\x00\x00")
808*333d2b36SAndroid Build Coastguard Worker	z, err := NewReader(bytes.NewReader(data), int64(len(data)))
809*333d2b36SAndroid Build Coastguard Worker	if err != nil {
810*333d2b36SAndroid Build Coastguard Worker		t.Fatal(err)
811*333d2b36SAndroid Build Coastguard Worker	}
812*333d2b36SAndroid Build Coastguard Worker	r, err := z.File[0].Open()
813*333d2b36SAndroid Build Coastguard Worker	if err != nil {
814*333d2b36SAndroid Build Coastguard Worker		t.Fatal(err)
815*333d2b36SAndroid Build Coastguard Worker	}
816*333d2b36SAndroid Build Coastguard Worker	_, err = ioutil.ReadAll(r)
817*333d2b36SAndroid Build Coastguard Worker	if err != io.ErrUnexpectedEOF {
818*333d2b36SAndroid Build Coastguard Worker		t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
819*333d2b36SAndroid Build Coastguard Worker	}
820*333d2b36SAndroid Build Coastguard Worker	r.Close()
821*333d2b36SAndroid Build Coastguard Worker}
822*333d2b36SAndroid Build Coastguard Worker
823*333d2b36SAndroid Build Coastguard Worker// Verify we do not treat non-zip64 archives as zip64
824*333d2b36SAndroid Build Coastguard Workerfunc TestIssue12449(t *testing.T) {
825*333d2b36SAndroid Build Coastguard Worker	data := []byte{
826*333d2b36SAndroid Build Coastguard Worker		0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
827*333d2b36SAndroid Build Coastguard Worker		0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46, 0x00, 0x00,
828*333d2b36SAndroid Build Coastguard Worker		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829*333d2b36SAndroid Build Coastguard Worker		0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0xca, 0x64,
830*333d2b36SAndroid Build Coastguard Worker		0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
831*333d2b36SAndroid Build Coastguard Worker		0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
832*333d2b36SAndroid Build Coastguard Worker		0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
833*333d2b36SAndroid Build Coastguard Worker		0x00, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x0a,
834*333d2b36SAndroid Build Coastguard Worker		0x50, 0x4b, 0x07, 0x08, 0x1d, 0x88, 0x77, 0xb0,
835*333d2b36SAndroid Build Coastguard Worker		0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
836*333d2b36SAndroid Build Coastguard Worker		0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00,
837*333d2b36SAndroid Build Coastguard Worker		0x08, 0x00, 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46,
838*333d2b36SAndroid Build Coastguard Worker		0x1d, 0x88, 0x77, 0xb0, 0x07, 0x00, 0x00, 0x00,
839*333d2b36SAndroid Build Coastguard Worker		0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00,
840*333d2b36SAndroid Build Coastguard Worker		0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841*333d2b36SAndroid Build Coastguard Worker		0xa0, 0x81, 0x00, 0x00, 0x00, 0x00, 0xca, 0x64,
842*333d2b36SAndroid Build Coastguard Worker		0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
843*333d2b36SAndroid Build Coastguard Worker		0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
844*333d2b36SAndroid Build Coastguard Worker		0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
845*333d2b36SAndroid Build Coastguard Worker		0x00, 0x97, 0x2b, 0x49, 0x23, 0x05, 0xc5, 0x0b,
846*333d2b36SAndroid Build Coastguard Worker		0xa7, 0xd1, 0x52, 0xa2, 0x9c, 0x50, 0x4b, 0x06,
847*333d2b36SAndroid Build Coastguard Worker		0x07, 0xc8, 0x19, 0xc1, 0xaf, 0x94, 0x9c, 0x61,
848*333d2b36SAndroid Build Coastguard Worker		0x44, 0xbe, 0x94, 0x19, 0x42, 0x58, 0x12, 0xc6,
849*333d2b36SAndroid Build Coastguard Worker		0x5b, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
850*333d2b36SAndroid Build Coastguard Worker		0x00, 0x01, 0x00, 0x01, 0x00, 0x69, 0x00, 0x00,
851*333d2b36SAndroid Build Coastguard Worker		0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
852*333d2b36SAndroid Build Coastguard Worker	}
853*333d2b36SAndroid Build Coastguard Worker	// Read in the archive.
854*333d2b36SAndroid Build Coastguard Worker	_, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
855*333d2b36SAndroid Build Coastguard Worker	if err != nil {
856*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Error reading the archive: %v", err)
857*333d2b36SAndroid Build Coastguard Worker	}
858*333d2b36SAndroid Build Coastguard Worker}
859