ยปCore Development>Code coverage>Lib/test/test_zipfile.py

Python code coverage for Lib/test/test_zipfile.py

#countcontent
1n/aimport contextlib
2n/aimport io
3n/aimport os
4n/aimport importlib.util
5n/aimport posixpath
6n/aimport time
7n/aimport struct
8n/aimport zipfile
9n/aimport unittest
10n/a
11n/a
12n/afrom tempfile import TemporaryFile
13n/afrom random import randint, random, getrandbits
14n/a
15n/afrom test.support import script_helper
16n/afrom test.support import (TESTFN, findfile, unlink, rmtree, temp_dir,
17n/a requires_zlib, requires_bz2, requires_lzma,
18n/a captured_stdout, check_warnings)
19n/a
20n/aTESTFN2 = TESTFN + "2"
21n/aTESTFNDIR = TESTFN + "d"
22n/aFIXEDTEST_SIZE = 1000
23n/aDATAFILES_DIR = 'zipfile_datafiles'
24n/a
25n/aSMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'),
26n/a ('ziptest2dir/_ziptest2', 'qawsedrftg'),
27n/a ('ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'),
28n/a ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')]
29n/a
30n/adef getrandbytes(size):
31n/a return getrandbits(8 * size).to_bytes(size, 'little')
32n/a
33n/adef get_files(test):
34n/a yield TESTFN2
35n/a with TemporaryFile() as f:
36n/a yield f
37n/a test.assertFalse(f.closed)
38n/a with io.BytesIO() as f:
39n/a yield f
40n/a test.assertFalse(f.closed)
41n/a
42n/aclass AbstractTestsWithSourceFile:
43n/a @classmethod
44n/a def setUpClass(cls):
45n/a cls.line_gen = [bytes("Zipfile test line %d. random float: %f\n" %
46n/a (i, random()), "ascii")
47n/a for i in range(FIXEDTEST_SIZE)]
48n/a cls.data = b''.join(cls.line_gen)
49n/a
50n/a def setUp(self):
51n/a # Make a source file with some lines
52n/a with open(TESTFN, "wb") as fp:
53n/a fp.write(self.data)
54n/a
55n/a def make_test_archive(self, f, compression):
56n/a # Create the ZIP archive
57n/a with zipfile.ZipFile(f, "w", compression) as zipfp:
58n/a zipfp.write(TESTFN, "another.name")
59n/a zipfp.write(TESTFN, TESTFN)
60n/a zipfp.writestr("strfile", self.data)
61n/a with zipfp.open('written-open-w', mode='w') as f:
62n/a for line in self.line_gen:
63n/a f.write(line)
64n/a
65n/a def zip_test(self, f, compression):
66n/a self.make_test_archive(f, compression)
67n/a
68n/a # Read the ZIP archive
69n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
70n/a self.assertEqual(zipfp.read(TESTFN), self.data)
71n/a self.assertEqual(zipfp.read("another.name"), self.data)
72n/a self.assertEqual(zipfp.read("strfile"), self.data)
73n/a
74n/a # Print the ZIP directory
75n/a fp = io.StringIO()
76n/a zipfp.printdir(file=fp)
77n/a directory = fp.getvalue()
78n/a lines = directory.splitlines()
79n/a self.assertEqual(len(lines), 5) # Number of files + header
80n/a
81n/a self.assertIn('File Name', lines[0])
82n/a self.assertIn('Modified', lines[0])
83n/a self.assertIn('Size', lines[0])
84n/a
85n/a fn, date, time_, size = lines[1].split()
86n/a self.assertEqual(fn, 'another.name')
87n/a self.assertTrue(time.strptime(date, '%Y-%m-%d'))
88n/a self.assertTrue(time.strptime(time_, '%H:%M:%S'))
89n/a self.assertEqual(size, str(len(self.data)))
90n/a
91n/a # Check the namelist
92n/a names = zipfp.namelist()
93n/a self.assertEqual(len(names), 4)
94n/a self.assertIn(TESTFN, names)
95n/a self.assertIn("another.name", names)
96n/a self.assertIn("strfile", names)
97n/a self.assertIn("written-open-w", names)
98n/a
99n/a # Check infolist
100n/a infos = zipfp.infolist()
101n/a names = [i.filename for i in infos]
102n/a self.assertEqual(len(names), 4)
103n/a self.assertIn(TESTFN, names)
104n/a self.assertIn("another.name", names)
105n/a self.assertIn("strfile", names)
106n/a self.assertIn("written-open-w", names)
107n/a for i in infos:
108n/a self.assertEqual(i.file_size, len(self.data))
109n/a
110n/a # check getinfo
111n/a for nm in (TESTFN, "another.name", "strfile", "written-open-w"):
112n/a info = zipfp.getinfo(nm)
113n/a self.assertEqual(info.filename, nm)
114n/a self.assertEqual(info.file_size, len(self.data))
115n/a
116n/a # Check that testzip doesn't raise an exception
117n/a zipfp.testzip()
118n/a
119n/a def test_basic(self):
120n/a for f in get_files(self):
121n/a self.zip_test(f, self.compression)
122n/a
123n/a def zip_open_test(self, f, compression):
124n/a self.make_test_archive(f, compression)
125n/a
126n/a # Read the ZIP archive
127n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
128n/a zipdata1 = []
129n/a with zipfp.open(TESTFN) as zipopen1:
130n/a while True:
131n/a read_data = zipopen1.read(256)
132n/a if not read_data:
133n/a break
134n/a zipdata1.append(read_data)
135n/a
136n/a zipdata2 = []
137n/a with zipfp.open("another.name") as zipopen2:
138n/a while True:
139n/a read_data = zipopen2.read(256)
140n/a if not read_data:
141n/a break
142n/a zipdata2.append(read_data)
143n/a
144n/a self.assertEqual(b''.join(zipdata1), self.data)
145n/a self.assertEqual(b''.join(zipdata2), self.data)
146n/a
147n/a def test_open(self):
148n/a for f in get_files(self):
149n/a self.zip_open_test(f, self.compression)
150n/a
151n/a def zip_random_open_test(self, f, compression):
152n/a self.make_test_archive(f, compression)
153n/a
154n/a # Read the ZIP archive
155n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
156n/a zipdata1 = []
157n/a with zipfp.open(TESTFN) as zipopen1:
158n/a while True:
159n/a read_data = zipopen1.read(randint(1, 1024))
160n/a if not read_data:
161n/a break
162n/a zipdata1.append(read_data)
163n/a
164n/a self.assertEqual(b''.join(zipdata1), self.data)
165n/a
166n/a def test_random_open(self):
167n/a for f in get_files(self):
168n/a self.zip_random_open_test(f, self.compression)
169n/a
170n/a def zip_read1_test(self, f, compression):
171n/a self.make_test_archive(f, compression)
172n/a
173n/a # Read the ZIP archive
174n/a with zipfile.ZipFile(f, "r") as zipfp, \
175n/a zipfp.open(TESTFN) as zipopen:
176n/a zipdata = []
177n/a while True:
178n/a read_data = zipopen.read1(-1)
179n/a if not read_data:
180n/a break
181n/a zipdata.append(read_data)
182n/a
183n/a self.assertEqual(b''.join(zipdata), self.data)
184n/a
185n/a def test_read1(self):
186n/a for f in get_files(self):
187n/a self.zip_read1_test(f, self.compression)
188n/a
189n/a def zip_read1_10_test(self, f, compression):
190n/a self.make_test_archive(f, compression)
191n/a
192n/a # Read the ZIP archive
193n/a with zipfile.ZipFile(f, "r") as zipfp, \
194n/a zipfp.open(TESTFN) as zipopen:
195n/a zipdata = []
196n/a while True:
197n/a read_data = zipopen.read1(10)
198n/a self.assertLessEqual(len(read_data), 10)
199n/a if not read_data:
200n/a break
201n/a zipdata.append(read_data)
202n/a
203n/a self.assertEqual(b''.join(zipdata), self.data)
204n/a
205n/a def test_read1_10(self):
206n/a for f in get_files(self):
207n/a self.zip_read1_10_test(f, self.compression)
208n/a
209n/a def zip_readline_read_test(self, f, compression):
210n/a self.make_test_archive(f, compression)
211n/a
212n/a # Read the ZIP archive
213n/a with zipfile.ZipFile(f, "r") as zipfp, \
214n/a zipfp.open(TESTFN) as zipopen:
215n/a data = b''
216n/a while True:
217n/a read = zipopen.readline()
218n/a if not read:
219n/a break
220n/a data += read
221n/a
222n/a read = zipopen.read(100)
223n/a if not read:
224n/a break
225n/a data += read
226n/a
227n/a self.assertEqual(data, self.data)
228n/a
229n/a def test_readline_read(self):
230n/a # Issue #7610: calls to readline() interleaved with calls to read().
231n/a for f in get_files(self):
232n/a self.zip_readline_read_test(f, self.compression)
233n/a
234n/a def zip_readline_test(self, f, compression):
235n/a self.make_test_archive(f, compression)
236n/a
237n/a # Read the ZIP archive
238n/a with zipfile.ZipFile(f, "r") as zipfp:
239n/a with zipfp.open(TESTFN) as zipopen:
240n/a for line in self.line_gen:
241n/a linedata = zipopen.readline()
242n/a self.assertEqual(linedata, line)
243n/a
244n/a def test_readline(self):
245n/a for f in get_files(self):
246n/a self.zip_readline_test(f, self.compression)
247n/a
248n/a def zip_readlines_test(self, f, compression):
249n/a self.make_test_archive(f, compression)
250n/a
251n/a # Read the ZIP archive
252n/a with zipfile.ZipFile(f, "r") as zipfp:
253n/a with zipfp.open(TESTFN) as zipopen:
254n/a ziplines = zipopen.readlines()
255n/a for line, zipline in zip(self.line_gen, ziplines):
256n/a self.assertEqual(zipline, line)
257n/a
258n/a def test_readlines(self):
259n/a for f in get_files(self):
260n/a self.zip_readlines_test(f, self.compression)
261n/a
262n/a def zip_iterlines_test(self, f, compression):
263n/a self.make_test_archive(f, compression)
264n/a
265n/a # Read the ZIP archive
266n/a with zipfile.ZipFile(f, "r") as zipfp:
267n/a with zipfp.open(TESTFN) as zipopen:
268n/a for line, zipline in zip(self.line_gen, zipopen):
269n/a self.assertEqual(zipline, line)
270n/a
271n/a def test_iterlines(self):
272n/a for f in get_files(self):
273n/a self.zip_iterlines_test(f, self.compression)
274n/a
275n/a def test_low_compression(self):
276n/a """Check for cases where compressed data is larger than original."""
277n/a # Create the ZIP archive
278n/a with zipfile.ZipFile(TESTFN2, "w", self.compression) as zipfp:
279n/a zipfp.writestr("strfile", '12')
280n/a
281n/a # Get an open object for strfile
282n/a with zipfile.ZipFile(TESTFN2, "r", self.compression) as zipfp:
283n/a with zipfp.open("strfile") as openobj:
284n/a self.assertEqual(openobj.read(1), b'1')
285n/a self.assertEqual(openobj.read(1), b'2')
286n/a
287n/a def test_writestr_compression(self):
288n/a zipfp = zipfile.ZipFile(TESTFN2, "w")
289n/a zipfp.writestr("b.txt", "hello world", compress_type=self.compression)
290n/a info = zipfp.getinfo('b.txt')
291n/a self.assertEqual(info.compress_type, self.compression)
292n/a
293n/a def test_read_return_size(self):
294n/a # Issue #9837: ZipExtFile.read() shouldn't return more bytes
295n/a # than requested.
296n/a for test_size in (1, 4095, 4096, 4097, 16384):
297n/a file_size = test_size + 1
298n/a junk = getrandbytes(file_size)
299n/a with zipfile.ZipFile(io.BytesIO(), "w", self.compression) as zipf:
300n/a zipf.writestr('foo', junk)
301n/a with zipf.open('foo', 'r') as fp:
302n/a buf = fp.read(test_size)
303n/a self.assertEqual(len(buf), test_size)
304n/a
305n/a def test_truncated_zipfile(self):
306n/a fp = io.BytesIO()
307n/a with zipfile.ZipFile(fp, mode='w') as zipf:
308n/a zipf.writestr('strfile', self.data, compress_type=self.compression)
309n/a end_offset = fp.tell()
310n/a zipfiledata = fp.getvalue()
311n/a
312n/a fp = io.BytesIO(zipfiledata)
313n/a with zipfile.ZipFile(fp) as zipf:
314n/a with zipf.open('strfile') as zipopen:
315n/a fp.truncate(end_offset - 20)
316n/a with self.assertRaises(EOFError):
317n/a zipopen.read()
318n/a
319n/a fp = io.BytesIO(zipfiledata)
320n/a with zipfile.ZipFile(fp) as zipf:
321n/a with zipf.open('strfile') as zipopen:
322n/a fp.truncate(end_offset - 20)
323n/a with self.assertRaises(EOFError):
324n/a while zipopen.read(100):
325n/a pass
326n/a
327n/a fp = io.BytesIO(zipfiledata)
328n/a with zipfile.ZipFile(fp) as zipf:
329n/a with zipf.open('strfile') as zipopen:
330n/a fp.truncate(end_offset - 20)
331n/a with self.assertRaises(EOFError):
332n/a while zipopen.read1(100):
333n/a pass
334n/a
335n/a def test_repr(self):
336n/a fname = 'file.name'
337n/a for f in get_files(self):
338n/a with zipfile.ZipFile(f, 'w', self.compression) as zipfp:
339n/a zipfp.write(TESTFN, fname)
340n/a r = repr(zipfp)
341n/a self.assertIn("mode='w'", r)
342n/a
343n/a with zipfile.ZipFile(f, 'r') as zipfp:
344n/a r = repr(zipfp)
345n/a if isinstance(f, str):
346n/a self.assertIn('filename=%r' % f, r)
347n/a else:
348n/a self.assertIn('file=%r' % f, r)
349n/a self.assertIn("mode='r'", r)
350n/a r = repr(zipfp.getinfo(fname))
351n/a self.assertIn('filename=%r' % fname, r)
352n/a self.assertIn('filemode=', r)
353n/a self.assertIn('file_size=', r)
354n/a if self.compression != zipfile.ZIP_STORED:
355n/a self.assertIn('compress_type=', r)
356n/a self.assertIn('compress_size=', r)
357n/a with zipfp.open(fname) as zipopen:
358n/a r = repr(zipopen)
359n/a self.assertIn('name=%r' % fname, r)
360n/a self.assertIn("mode='r'", r)
361n/a if self.compression != zipfile.ZIP_STORED:
362n/a self.assertIn('compress_type=', r)
363n/a self.assertIn('[closed]', repr(zipopen))
364n/a self.assertIn('[closed]', repr(zipfp))
365n/a
366n/a def tearDown(self):
367n/a unlink(TESTFN)
368n/a unlink(TESTFN2)
369n/a
370n/a
371n/aclass StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
372n/a unittest.TestCase):
373n/a compression = zipfile.ZIP_STORED
374n/a test_low_compression = None
375n/a
376n/a def zip_test_writestr_permissions(self, f, compression):
377n/a # Make sure that writestr and open(... mode='w') create files with
378n/a # mode 0600, when they are passed a name rather than a ZipInfo
379n/a # instance.
380n/a
381n/a self.make_test_archive(f, compression)
382n/a with zipfile.ZipFile(f, "r") as zipfp:
383n/a zinfo = zipfp.getinfo('strfile')
384n/a self.assertEqual(zinfo.external_attr, 0o600 << 16)
385n/a
386n/a zinfo2 = zipfp.getinfo('written-open-w')
387n/a self.assertEqual(zinfo2.external_attr, 0o600 << 16)
388n/a
389n/a def test_writestr_permissions(self):
390n/a for f in get_files(self):
391n/a self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED)
392n/a
393n/a def test_absolute_arcnames(self):
394n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
395n/a zipfp.write(TESTFN, "/absolute")
396n/a
397n/a with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp:
398n/a self.assertEqual(zipfp.namelist(), ["absolute"])
399n/a
400n/a def test_append_to_zip_file(self):
401n/a """Test appending to an existing zipfile."""
402n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
403n/a zipfp.write(TESTFN, TESTFN)
404n/a
405n/a with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp:
406n/a zipfp.writestr("strfile", self.data)
407n/a self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"])
408n/a
409n/a def test_append_to_non_zip_file(self):
410n/a """Test appending to an existing file that is not a zipfile."""
411n/a # NOTE: this test fails if len(d) < 22 because of the first
412n/a # line "fpin.seek(-22, 2)" in _EndRecData
413n/a data = b'I am not a ZipFile!'*10
414n/a with open(TESTFN2, 'wb') as f:
415n/a f.write(data)
416n/a
417n/a with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp:
418n/a zipfp.write(TESTFN, TESTFN)
419n/a
420n/a with open(TESTFN2, 'rb') as f:
421n/a f.seek(len(data))
422n/a with zipfile.ZipFile(f, "r") as zipfp:
423n/a self.assertEqual(zipfp.namelist(), [TESTFN])
424n/a self.assertEqual(zipfp.read(TESTFN), self.data)
425n/a with open(TESTFN2, 'rb') as f:
426n/a self.assertEqual(f.read(len(data)), data)
427n/a zipfiledata = f.read()
428n/a with io.BytesIO(zipfiledata) as bio, zipfile.ZipFile(bio) as zipfp:
429n/a self.assertEqual(zipfp.namelist(), [TESTFN])
430n/a self.assertEqual(zipfp.read(TESTFN), self.data)
431n/a
432n/a def test_read_concatenated_zip_file(self):
433n/a with io.BytesIO() as bio:
434n/a with zipfile.ZipFile(bio, 'w', zipfile.ZIP_STORED) as zipfp:
435n/a zipfp.write(TESTFN, TESTFN)
436n/a zipfiledata = bio.getvalue()
437n/a data = b'I am not a ZipFile!'*10
438n/a with open(TESTFN2, 'wb') as f:
439n/a f.write(data)
440n/a f.write(zipfiledata)
441n/a
442n/a with zipfile.ZipFile(TESTFN2) as zipfp:
443n/a self.assertEqual(zipfp.namelist(), [TESTFN])
444n/a self.assertEqual(zipfp.read(TESTFN), self.data)
445n/a
446n/a def test_append_to_concatenated_zip_file(self):
447n/a with io.BytesIO() as bio:
448n/a with zipfile.ZipFile(bio, 'w', zipfile.ZIP_STORED) as zipfp:
449n/a zipfp.write(TESTFN, TESTFN)
450n/a zipfiledata = bio.getvalue()
451n/a data = b'I am not a ZipFile!'*1000000
452n/a with open(TESTFN2, 'wb') as f:
453n/a f.write(data)
454n/a f.write(zipfiledata)
455n/a
456n/a with zipfile.ZipFile(TESTFN2, 'a') as zipfp:
457n/a self.assertEqual(zipfp.namelist(), [TESTFN])
458n/a zipfp.writestr('strfile', self.data)
459n/a
460n/a with open(TESTFN2, 'rb') as f:
461n/a self.assertEqual(f.read(len(data)), data)
462n/a zipfiledata = f.read()
463n/a with io.BytesIO(zipfiledata) as bio, zipfile.ZipFile(bio) as zipfp:
464n/a self.assertEqual(zipfp.namelist(), [TESTFN, 'strfile'])
465n/a self.assertEqual(zipfp.read(TESTFN), self.data)
466n/a self.assertEqual(zipfp.read('strfile'), self.data)
467n/a
468n/a def test_ignores_newline_at_end(self):
469n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
470n/a zipfp.write(TESTFN, TESTFN)
471n/a with open(TESTFN2, 'a') as f:
472n/a f.write("\r\n\00\00\00")
473n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
474n/a self.assertIsInstance(zipfp, zipfile.ZipFile)
475n/a
476n/a def test_ignores_stuff_appended_past_comments(self):
477n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
478n/a zipfp.comment = b"this is a comment"
479n/a zipfp.write(TESTFN, TESTFN)
480n/a with open(TESTFN2, 'a') as f:
481n/a f.write("abcdef\r\n")
482n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
483n/a self.assertIsInstance(zipfp, zipfile.ZipFile)
484n/a self.assertEqual(zipfp.comment, b"this is a comment")
485n/a
486n/a def test_write_default_name(self):
487n/a """Check that calling ZipFile.write without arcname specified
488n/a produces the expected result."""
489n/a with zipfile.ZipFile(TESTFN2, "w") as zipfp:
490n/a zipfp.write(TESTFN)
491n/a with open(TESTFN, "rb") as f:
492n/a self.assertEqual(zipfp.read(TESTFN), f.read())
493n/a
494n/a def test_write_to_readonly(self):
495n/a """Check that trying to call write() on a readonly ZipFile object
496n/a raises a ValueError."""
497n/a with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
498n/a zipfp.writestr("somefile.txt", "bogus")
499n/a
500n/a with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
501n/a self.assertRaises(ValueError, zipfp.write, TESTFN)
502n/a
503n/a with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
504n/a with self.assertRaises(ValueError):
505n/a zipfp.open(TESTFN, mode='w')
506n/a
507n/a def test_add_file_before_1980(self):
508n/a # Set atime and mtime to 1970-01-01
509n/a os.utime(TESTFN, (0, 0))
510n/a with zipfile.ZipFile(TESTFN2, "w") as zipfp:
511n/a self.assertRaises(ValueError, zipfp.write, TESTFN)
512n/a
513n/a
514n/a@requires_zlib
515n/aclass DeflateTestsWithSourceFile(AbstractTestsWithSourceFile,
516n/a unittest.TestCase):
517n/a compression = zipfile.ZIP_DEFLATED
518n/a
519n/a def test_per_file_compression(self):
520n/a """Check that files within a Zip archive can have different
521n/a compression options."""
522n/a with zipfile.ZipFile(TESTFN2, "w") as zipfp:
523n/a zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED)
524n/a zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED)
525n/a sinfo = zipfp.getinfo('storeme')
526n/a dinfo = zipfp.getinfo('deflateme')
527n/a self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED)
528n/a self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED)
529n/a
530n/a@requires_bz2
531n/aclass Bzip2TestsWithSourceFile(AbstractTestsWithSourceFile,
532n/a unittest.TestCase):
533n/a compression = zipfile.ZIP_BZIP2
534n/a
535n/a@requires_lzma
536n/aclass LzmaTestsWithSourceFile(AbstractTestsWithSourceFile,
537n/a unittest.TestCase):
538n/a compression = zipfile.ZIP_LZMA
539n/a
540n/a
541n/aclass AbstractTestZip64InSmallFiles:
542n/a # These tests test the ZIP64 functionality without using large files,
543n/a # see test_zipfile64 for proper tests.
544n/a
545n/a @classmethod
546n/a def setUpClass(cls):
547n/a line_gen = (bytes("Test of zipfile line %d." % i, "ascii")
548n/a for i in range(0, FIXEDTEST_SIZE))
549n/a cls.data = b'\n'.join(line_gen)
550n/a
551n/a def setUp(self):
552n/a self._limit = zipfile.ZIP64_LIMIT
553n/a self._filecount_limit = zipfile.ZIP_FILECOUNT_LIMIT
554n/a zipfile.ZIP64_LIMIT = 1000
555n/a zipfile.ZIP_FILECOUNT_LIMIT = 9
556n/a
557n/a # Make a source file with some lines
558n/a with open(TESTFN, "wb") as fp:
559n/a fp.write(self.data)
560n/a
561n/a def zip_test(self, f, compression):
562n/a # Create the ZIP archive
563n/a with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp:
564n/a zipfp.write(TESTFN, "another.name")
565n/a zipfp.write(TESTFN, TESTFN)
566n/a zipfp.writestr("strfile", self.data)
567n/a
568n/a # Read the ZIP archive
569n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
570n/a self.assertEqual(zipfp.read(TESTFN), self.data)
571n/a self.assertEqual(zipfp.read("another.name"), self.data)
572n/a self.assertEqual(zipfp.read("strfile"), self.data)
573n/a
574n/a # Print the ZIP directory
575n/a fp = io.StringIO()
576n/a zipfp.printdir(fp)
577n/a
578n/a directory = fp.getvalue()
579n/a lines = directory.splitlines()
580n/a self.assertEqual(len(lines), 4) # Number of files + header
581n/a
582n/a self.assertIn('File Name', lines[0])
583n/a self.assertIn('Modified', lines[0])
584n/a self.assertIn('Size', lines[0])
585n/a
586n/a fn, date, time_, size = lines[1].split()
587n/a self.assertEqual(fn, 'another.name')
588n/a self.assertTrue(time.strptime(date, '%Y-%m-%d'))
589n/a self.assertTrue(time.strptime(time_, '%H:%M:%S'))
590n/a self.assertEqual(size, str(len(self.data)))
591n/a
592n/a # Check the namelist
593n/a names = zipfp.namelist()
594n/a self.assertEqual(len(names), 3)
595n/a self.assertIn(TESTFN, names)
596n/a self.assertIn("another.name", names)
597n/a self.assertIn("strfile", names)
598n/a
599n/a # Check infolist
600n/a infos = zipfp.infolist()
601n/a names = [i.filename for i in infos]
602n/a self.assertEqual(len(names), 3)
603n/a self.assertIn(TESTFN, names)
604n/a self.assertIn("another.name", names)
605n/a self.assertIn("strfile", names)
606n/a for i in infos:
607n/a self.assertEqual(i.file_size, len(self.data))
608n/a
609n/a # check getinfo
610n/a for nm in (TESTFN, "another.name", "strfile"):
611n/a info = zipfp.getinfo(nm)
612n/a self.assertEqual(info.filename, nm)
613n/a self.assertEqual(info.file_size, len(self.data))
614n/a
615n/a # Check that testzip doesn't raise an exception
616n/a zipfp.testzip()
617n/a
618n/a def test_basic(self):
619n/a for f in get_files(self):
620n/a self.zip_test(f, self.compression)
621n/a
622n/a def test_too_many_files(self):
623n/a # This test checks that more than 64k files can be added to an archive,
624n/a # and that the resulting archive can be read properly by ZipFile
625n/a zipf = zipfile.ZipFile(TESTFN, "w", self.compression,
626n/a allowZip64=True)
627n/a zipf.debug = 100
628n/a numfiles = 15
629n/a for i in range(numfiles):
630n/a zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
631n/a self.assertEqual(len(zipf.namelist()), numfiles)
632n/a zipf.close()
633n/a
634n/a zipf2 = zipfile.ZipFile(TESTFN, "r", self.compression)
635n/a self.assertEqual(len(zipf2.namelist()), numfiles)
636n/a for i in range(numfiles):
637n/a content = zipf2.read("foo%08d" % i).decode('ascii')
638n/a self.assertEqual(content, "%d" % (i**3 % 57))
639n/a zipf2.close()
640n/a
641n/a def test_too_many_files_append(self):
642n/a zipf = zipfile.ZipFile(TESTFN, "w", self.compression,
643n/a allowZip64=False)
644n/a zipf.debug = 100
645n/a numfiles = 9
646n/a for i in range(numfiles):
647n/a zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
648n/a self.assertEqual(len(zipf.namelist()), numfiles)
649n/a with self.assertRaises(zipfile.LargeZipFile):
650n/a zipf.writestr("foo%08d" % numfiles, b'')
651n/a self.assertEqual(len(zipf.namelist()), numfiles)
652n/a zipf.close()
653n/a
654n/a zipf = zipfile.ZipFile(TESTFN, "a", self.compression,
655n/a allowZip64=False)
656n/a zipf.debug = 100
657n/a self.assertEqual(len(zipf.namelist()), numfiles)
658n/a with self.assertRaises(zipfile.LargeZipFile):
659n/a zipf.writestr("foo%08d" % numfiles, b'')
660n/a self.assertEqual(len(zipf.namelist()), numfiles)
661n/a zipf.close()
662n/a
663n/a zipf = zipfile.ZipFile(TESTFN, "a", self.compression,
664n/a allowZip64=True)
665n/a zipf.debug = 100
666n/a self.assertEqual(len(zipf.namelist()), numfiles)
667n/a numfiles2 = 15
668n/a for i in range(numfiles, numfiles2):
669n/a zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
670n/a self.assertEqual(len(zipf.namelist()), numfiles2)
671n/a zipf.close()
672n/a
673n/a zipf2 = zipfile.ZipFile(TESTFN, "r", self.compression)
674n/a self.assertEqual(len(zipf2.namelist()), numfiles2)
675n/a for i in range(numfiles2):
676n/a content = zipf2.read("foo%08d" % i).decode('ascii')
677n/a self.assertEqual(content, "%d" % (i**3 % 57))
678n/a zipf2.close()
679n/a
680n/a def tearDown(self):
681n/a zipfile.ZIP64_LIMIT = self._limit
682n/a zipfile.ZIP_FILECOUNT_LIMIT = self._filecount_limit
683n/a unlink(TESTFN)
684n/a unlink(TESTFN2)
685n/a
686n/a
687n/aclass StoredTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
688n/a unittest.TestCase):
689n/a compression = zipfile.ZIP_STORED
690n/a
691n/a def large_file_exception_test(self, f, compression):
692n/a with zipfile.ZipFile(f, "w", compression, allowZip64=False) as zipfp:
693n/a self.assertRaises(zipfile.LargeZipFile,
694n/a zipfp.write, TESTFN, "another.name")
695n/a
696n/a def large_file_exception_test2(self, f, compression):
697n/a with zipfile.ZipFile(f, "w", compression, allowZip64=False) as zipfp:
698n/a self.assertRaises(zipfile.LargeZipFile,
699n/a zipfp.writestr, "another.name", self.data)
700n/a
701n/a def test_large_file_exception(self):
702n/a for f in get_files(self):
703n/a self.large_file_exception_test(f, zipfile.ZIP_STORED)
704n/a self.large_file_exception_test2(f, zipfile.ZIP_STORED)
705n/a
706n/a def test_absolute_arcnames(self):
707n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED,
708n/a allowZip64=True) as zipfp:
709n/a zipfp.write(TESTFN, "/absolute")
710n/a
711n/a with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp:
712n/a self.assertEqual(zipfp.namelist(), ["absolute"])
713n/a
714n/a@requires_zlib
715n/aclass DeflateTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
716n/a unittest.TestCase):
717n/a compression = zipfile.ZIP_DEFLATED
718n/a
719n/a@requires_bz2
720n/aclass Bzip2TestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
721n/a unittest.TestCase):
722n/a compression = zipfile.ZIP_BZIP2
723n/a
724n/a@requires_lzma
725n/aclass LzmaTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
726n/a unittest.TestCase):
727n/a compression = zipfile.ZIP_LZMA
728n/a
729n/a
730n/aclass PyZipFileTests(unittest.TestCase):
731n/a def assertCompiledIn(self, name, namelist):
732n/a if name + 'o' not in namelist:
733n/a self.assertIn(name + 'c', namelist)
734n/a
735n/a def requiresWriteAccess(self, path):
736n/a # effective_ids unavailable on windows
737n/a if not os.access(path, os.W_OK,
738n/a effective_ids=os.access in os.supports_effective_ids):
739n/a self.skipTest('requires write access to the installed location')
740n/a filename = os.path.join(path, 'test_zipfile.try')
741n/a try:
742n/a fd = os.open(filename, os.O_WRONLY | os.O_CREAT)
743n/a os.close(fd)
744n/a except Exception:
745n/a self.skipTest('requires write access to the installed location')
746n/a unlink(filename)
747n/a
748n/a def test_write_pyfile(self):
749n/a self.requiresWriteAccess(os.path.dirname(__file__))
750n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
751n/a fn = __file__
752n/a if fn.endswith('.pyc'):
753n/a path_split = fn.split(os.sep)
754n/a if os.altsep is not None:
755n/a path_split.extend(fn.split(os.altsep))
756n/a if '__pycache__' in path_split:
757n/a fn = importlib.util.source_from_cache(fn)
758n/a else:
759n/a fn = fn[:-1]
760n/a
761n/a zipfp.writepy(fn)
762n/a
763n/a bn = os.path.basename(fn)
764n/a self.assertNotIn(bn, zipfp.namelist())
765n/a self.assertCompiledIn(bn, zipfp.namelist())
766n/a
767n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
768n/a fn = __file__
769n/a if fn.endswith('.pyc'):
770n/a fn = fn[:-1]
771n/a
772n/a zipfp.writepy(fn, "testpackage")
773n/a
774n/a bn = "%s/%s" % ("testpackage", os.path.basename(fn))
775n/a self.assertNotIn(bn, zipfp.namelist())
776n/a self.assertCompiledIn(bn, zipfp.namelist())
777n/a
778n/a def test_write_python_package(self):
779n/a import email
780n/a packagedir = os.path.dirname(email.__file__)
781n/a self.requiresWriteAccess(packagedir)
782n/a
783n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
784n/a zipfp.writepy(packagedir)
785n/a
786n/a # Check for a couple of modules at different levels of the
787n/a # hierarchy
788n/a names = zipfp.namelist()
789n/a self.assertCompiledIn('email/__init__.py', names)
790n/a self.assertCompiledIn('email/mime/text.py', names)
791n/a
792n/a def test_write_filtered_python_package(self):
793n/a import test
794n/a packagedir = os.path.dirname(test.__file__)
795n/a self.requiresWriteAccess(packagedir)
796n/a
797n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
798n/a
799n/a # first make sure that the test folder gives error messages
800n/a # (on the badsyntax_... files)
801n/a with captured_stdout() as reportSIO:
802n/a zipfp.writepy(packagedir)
803n/a reportStr = reportSIO.getvalue()
804n/a self.assertTrue('SyntaxError' in reportStr)
805n/a
806n/a # then check that the filter works on the whole package
807n/a with captured_stdout() as reportSIO:
808n/a zipfp.writepy(packagedir, filterfunc=lambda whatever: False)
809n/a reportStr = reportSIO.getvalue()
810n/a self.assertTrue('SyntaxError' not in reportStr)
811n/a
812n/a # then check that the filter works on individual files
813n/a def filter(path):
814n/a return not os.path.basename(path).startswith("bad")
815n/a with captured_stdout() as reportSIO, self.assertWarns(UserWarning):
816n/a zipfp.writepy(packagedir, filterfunc=filter)
817n/a reportStr = reportSIO.getvalue()
818n/a if reportStr:
819n/a print(reportStr)
820n/a self.assertTrue('SyntaxError' not in reportStr)
821n/a
822n/a def test_write_with_optimization(self):
823n/a import email
824n/a packagedir = os.path.dirname(email.__file__)
825n/a self.requiresWriteAccess(packagedir)
826n/a optlevel = 1 if __debug__ else 0
827n/a ext = '.pyc'
828n/a
829n/a with TemporaryFile() as t, \
830n/a zipfile.PyZipFile(t, "w", optimize=optlevel) as zipfp:
831n/a zipfp.writepy(packagedir)
832n/a
833n/a names = zipfp.namelist()
834n/a self.assertIn('email/__init__' + ext, names)
835n/a self.assertIn('email/mime/text' + ext, names)
836n/a
837n/a def test_write_python_directory(self):
838n/a os.mkdir(TESTFN2)
839n/a try:
840n/a with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp:
841n/a fp.write("print(42)\n")
842n/a
843n/a with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp:
844n/a fp.write("print(42 * 42)\n")
845n/a
846n/a with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp:
847n/a fp.write("bla bla bla\n")
848n/a
849n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
850n/a zipfp.writepy(TESTFN2)
851n/a
852n/a names = zipfp.namelist()
853n/a self.assertCompiledIn('mod1.py', names)
854n/a self.assertCompiledIn('mod2.py', names)
855n/a self.assertNotIn('mod2.txt', names)
856n/a
857n/a finally:
858n/a rmtree(TESTFN2)
859n/a
860n/a def test_write_python_directory_filtered(self):
861n/a os.mkdir(TESTFN2)
862n/a try:
863n/a with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp:
864n/a fp.write("print(42)\n")
865n/a
866n/a with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp:
867n/a fp.write("print(42 * 42)\n")
868n/a
869n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
870n/a zipfp.writepy(TESTFN2, filterfunc=lambda fn:
871n/a not fn.endswith('mod2.py'))
872n/a
873n/a names = zipfp.namelist()
874n/a self.assertCompiledIn('mod1.py', names)
875n/a self.assertNotIn('mod2.py', names)
876n/a
877n/a finally:
878n/a rmtree(TESTFN2)
879n/a
880n/a def test_write_non_pyfile(self):
881n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
882n/a with open(TESTFN, 'w') as f:
883n/a f.write('most definitely not a python file')
884n/a self.assertRaises(RuntimeError, zipfp.writepy, TESTFN)
885n/a unlink(TESTFN)
886n/a
887n/a def test_write_pyfile_bad_syntax(self):
888n/a os.mkdir(TESTFN2)
889n/a try:
890n/a with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp:
891n/a fp.write("Bad syntax in python file\n")
892n/a
893n/a with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
894n/a # syntax errors are printed to stdout
895n/a with captured_stdout() as s:
896n/a zipfp.writepy(os.path.join(TESTFN2, "mod1.py"))
897n/a
898n/a self.assertIn("SyntaxError", s.getvalue())
899n/a
900n/a # as it will not have compiled the python file, it will
901n/a # include the .py file not .pyc
902n/a names = zipfp.namelist()
903n/a self.assertIn('mod1.py', names)
904n/a self.assertNotIn('mod1.pyc', names)
905n/a
906n/a finally:
907n/a rmtree(TESTFN2)
908n/a
909n/a
910n/aclass ExtractTests(unittest.TestCase):
911n/a def test_extract(self):
912n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
913n/a for fpath, fdata in SMALL_TEST_DATA:
914n/a zipfp.writestr(fpath, fdata)
915n/a
916n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
917n/a for fpath, fdata in SMALL_TEST_DATA:
918n/a writtenfile = zipfp.extract(fpath)
919n/a
920n/a # make sure it was written to the right place
921n/a correctfile = os.path.join(os.getcwd(), fpath)
922n/a correctfile = os.path.normpath(correctfile)
923n/a
924n/a self.assertEqual(writtenfile, correctfile)
925n/a
926n/a # make sure correct data is in correct file
927n/a with open(writtenfile, "rb") as f:
928n/a self.assertEqual(fdata.encode(), f.read())
929n/a
930n/a unlink(writtenfile)
931n/a
932n/a # remove the test file subdirectories
933n/a rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
934n/a
935n/a def test_extract_all(self):
936n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
937n/a for fpath, fdata in SMALL_TEST_DATA:
938n/a zipfp.writestr(fpath, fdata)
939n/a
940n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
941n/a zipfp.extractall()
942n/a for fpath, fdata in SMALL_TEST_DATA:
943n/a outfile = os.path.join(os.getcwd(), fpath)
944n/a
945n/a with open(outfile, "rb") as f:
946n/a self.assertEqual(fdata.encode(), f.read())
947n/a
948n/a unlink(outfile)
949n/a
950n/a # remove the test file subdirectories
951n/a rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
952n/a
953n/a def check_file(self, filename, content):
954n/a self.assertTrue(os.path.isfile(filename))
955n/a with open(filename, 'rb') as f:
956n/a self.assertEqual(f.read(), content)
957n/a
958n/a def test_sanitize_windows_name(self):
959n/a san = zipfile.ZipFile._sanitize_windows_name
960n/a # Passing pathsep in allows this test to work regardless of platform.
961n/a self.assertEqual(san(r',,?,C:,foo,bar/z', ','), r'_,C_,foo,bar/z')
962n/a self.assertEqual(san(r'a\b,c<d>e|f"g?h*i', ','), r'a\b,c_d_e_f_g_h_i')
963n/a self.assertEqual(san('../../foo../../ba..r', '/'), r'foo/ba..r')
964n/a
965n/a def test_extract_hackers_arcnames_common_cases(self):
966n/a common_hacknames = [
967n/a ('../foo/bar', 'foo/bar'),
968n/a ('foo/../bar', 'foo/bar'),
969n/a ('foo/../../bar', 'foo/bar'),
970n/a ('foo/bar/..', 'foo/bar'),
971n/a ('./../foo/bar', 'foo/bar'),
972n/a ('/foo/bar', 'foo/bar'),
973n/a ('/foo/../bar', 'foo/bar'),
974n/a ('/foo/../../bar', 'foo/bar'),
975n/a ]
976n/a self._test_extract_hackers_arcnames(common_hacknames)
977n/a
978n/a @unittest.skipIf(os.path.sep != '\\', 'Requires \\ as path separator.')
979n/a def test_extract_hackers_arcnames_windows_only(self):
980n/a """Test combination of path fixing and windows name sanitization."""
981n/a windows_hacknames = [
982n/a (r'..\foo\bar', 'foo/bar'),
983n/a (r'..\/foo\/bar', 'foo/bar'),
984n/a (r'foo/\..\/bar', 'foo/bar'),
985n/a (r'foo\/../\bar', 'foo/bar'),
986n/a (r'C:foo/bar', 'foo/bar'),
987n/a (r'C:/foo/bar', 'foo/bar'),
988n/a (r'C://foo/bar', 'foo/bar'),
989n/a (r'C:\foo\bar', 'foo/bar'),
990n/a (r'//conky/mountpoint/foo/bar', 'foo/bar'),
991n/a (r'\\conky\mountpoint\foo\bar', 'foo/bar'),
992n/a (r'///conky/mountpoint/foo/bar', 'conky/mountpoint/foo/bar'),
993n/a (r'\\\conky\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'),
994n/a (r'//conky//mountpoint/foo/bar', 'conky/mountpoint/foo/bar'),
995n/a (r'\\conky\\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'),
996n/a (r'//?/C:/foo/bar', 'foo/bar'),
997n/a (r'\\?\C:\foo\bar', 'foo/bar'),
998n/a (r'C:/../C:/foo/bar', 'C_/foo/bar'),
999n/a (r'a:b\c<d>e|f"g?h*i', 'b/c_d_e_f_g_h_i'),
1000n/a ('../../foo../../ba..r', 'foo/ba..r'),
1001n/a ]
1002n/a self._test_extract_hackers_arcnames(windows_hacknames)
1003n/a
1004n/a @unittest.skipIf(os.path.sep != '/', r'Requires / as path separator.')
1005n/a def test_extract_hackers_arcnames_posix_only(self):
1006n/a posix_hacknames = [
1007n/a ('//foo/bar', 'foo/bar'),
1008n/a ('../../foo../../ba..r', 'foo../ba..r'),
1009n/a (r'foo/..\bar', r'foo/..\bar'),
1010n/a ]
1011n/a self._test_extract_hackers_arcnames(posix_hacknames)
1012n/a
1013n/a def _test_extract_hackers_arcnames(self, hacknames):
1014n/a for arcname, fixedname in hacknames:
1015n/a content = b'foobar' + arcname.encode()
1016n/a with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_STORED) as zipfp:
1017n/a zinfo = zipfile.ZipInfo()
1018n/a # preserve backslashes
1019n/a zinfo.filename = arcname
1020n/a zinfo.external_attr = 0o600 << 16
1021n/a zipfp.writestr(zinfo, content)
1022n/a
1023n/a arcname = arcname.replace(os.sep, "/")
1024n/a targetpath = os.path.join('target', 'subdir', 'subsub')
1025n/a correctfile = os.path.join(targetpath, *fixedname.split('/'))
1026n/a
1027n/a with zipfile.ZipFile(TESTFN2, 'r') as zipfp:
1028n/a writtenfile = zipfp.extract(arcname, targetpath)
1029n/a self.assertEqual(writtenfile, correctfile,
1030n/a msg='extract %r: %r != %r' %
1031n/a (arcname, writtenfile, correctfile))
1032n/a self.check_file(correctfile, content)
1033n/a rmtree('target')
1034n/a
1035n/a with zipfile.ZipFile(TESTFN2, 'r') as zipfp:
1036n/a zipfp.extractall(targetpath)
1037n/a self.check_file(correctfile, content)
1038n/a rmtree('target')
1039n/a
1040n/a correctfile = os.path.join(os.getcwd(), *fixedname.split('/'))
1041n/a
1042n/a with zipfile.ZipFile(TESTFN2, 'r') as zipfp:
1043n/a writtenfile = zipfp.extract(arcname)
1044n/a self.assertEqual(writtenfile, correctfile,
1045n/a msg="extract %r" % arcname)
1046n/a self.check_file(correctfile, content)
1047n/a rmtree(fixedname.split('/')[0])
1048n/a
1049n/a with zipfile.ZipFile(TESTFN2, 'r') as zipfp:
1050n/a zipfp.extractall()
1051n/a self.check_file(correctfile, content)
1052n/a rmtree(fixedname.split('/')[0])
1053n/a
1054n/a unlink(TESTFN2)
1055n/a
1056n/a
1057n/aclass OtherTests(unittest.TestCase):
1058n/a def test_open_via_zip_info(self):
1059n/a # Create the ZIP archive
1060n/a with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
1061n/a zipfp.writestr("name", "foo")
1062n/a with self.assertWarns(UserWarning):
1063n/a zipfp.writestr("name", "bar")
1064n/a self.assertEqual(zipfp.namelist(), ["name"] * 2)
1065n/a
1066n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
1067n/a infos = zipfp.infolist()
1068n/a data = b""
1069n/a for info in infos:
1070n/a with zipfp.open(info) as zipopen:
1071n/a data += zipopen.read()
1072n/a self.assertIn(data, {b"foobar", b"barfoo"})
1073n/a data = b""
1074n/a for info in infos:
1075n/a data += zipfp.read(info)
1076n/a self.assertIn(data, {b"foobar", b"barfoo"})
1077n/a
1078n/a def test_writestr_extended_local_header_issue1202(self):
1079n/a with zipfile.ZipFile(TESTFN2, 'w') as orig_zip:
1080n/a for data in 'abcdefghijklmnop':
1081n/a zinfo = zipfile.ZipInfo(data)
1082n/a zinfo.flag_bits |= 0x08 # Include an extended local header.
1083n/a orig_zip.writestr(zinfo, data)
1084n/a
1085n/a def test_close(self):
1086n/a """Check that the zipfile is closed after the 'with' block."""
1087n/a with zipfile.ZipFile(TESTFN2, "w") as zipfp:
1088n/a for fpath, fdata in SMALL_TEST_DATA:
1089n/a zipfp.writestr(fpath, fdata)
1090n/a self.assertIsNotNone(zipfp.fp, 'zipfp is not open')
1091n/a self.assertIsNone(zipfp.fp, 'zipfp is not closed')
1092n/a
1093n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
1094n/a self.assertIsNotNone(zipfp.fp, 'zipfp is not open')
1095n/a self.assertIsNone(zipfp.fp, 'zipfp is not closed')
1096n/a
1097n/a def test_close_on_exception(self):
1098n/a """Check that the zipfile is closed if an exception is raised in the
1099n/a 'with' block."""
1100n/a with zipfile.ZipFile(TESTFN2, "w") as zipfp:
1101n/a for fpath, fdata in SMALL_TEST_DATA:
1102n/a zipfp.writestr(fpath, fdata)
1103n/a
1104n/a try:
1105n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp2:
1106n/a raise zipfile.BadZipFile()
1107n/a except zipfile.BadZipFile:
1108n/a self.assertIsNone(zipfp2.fp, 'zipfp is not closed')
1109n/a
1110n/a def test_unsupported_version(self):
1111n/a # File has an extract_version of 120
1112n/a data = (b'PK\x03\x04x\x00\x00\x00\x00\x00!p\xa1@\x00\x00\x00\x00\x00\x00'
1113n/a b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00xPK\x01\x02x\x03x\x00\x00\x00\x00'
1114n/a b'\x00!p\xa1@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00'
1115n/a b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00xPK\x05\x06'
1116n/a b'\x00\x00\x00\x00\x01\x00\x01\x00/\x00\x00\x00\x1f\x00\x00\x00\x00\x00')
1117n/a
1118n/a self.assertRaises(NotImplementedError, zipfile.ZipFile,
1119n/a io.BytesIO(data), 'r')
1120n/a
1121n/a @requires_zlib
1122n/a def test_read_unicode_filenames(self):
1123n/a # bug #10801
1124n/a fname = findfile('zip_cp437_header.zip')
1125n/a with zipfile.ZipFile(fname) as zipfp:
1126n/a for name in zipfp.namelist():
1127n/a zipfp.open(name).close()
1128n/a
1129n/a def test_write_unicode_filenames(self):
1130n/a with zipfile.ZipFile(TESTFN, "w") as zf:
1131n/a zf.writestr("foo.txt", "Test for unicode filename")
1132n/a zf.writestr("\xf6.txt", "Test for unicode filename")
1133n/a self.assertIsInstance(zf.infolist()[0].filename, str)
1134n/a
1135n/a with zipfile.ZipFile(TESTFN, "r") as zf:
1136n/a self.assertEqual(zf.filelist[0].filename, "foo.txt")
1137n/a self.assertEqual(zf.filelist[1].filename, "\xf6.txt")
1138n/a
1139n/a def test_exclusive_create_zip_file(self):
1140n/a """Test exclusive creating a new zipfile."""
1141n/a unlink(TESTFN2)
1142n/a filename = 'testfile.txt'
1143n/a content = b'hello, world. this is some content.'
1144n/a with zipfile.ZipFile(TESTFN2, "x", zipfile.ZIP_STORED) as zipfp:
1145n/a zipfp.writestr(filename, content)
1146n/a with self.assertRaises(FileExistsError):
1147n/a zipfile.ZipFile(TESTFN2, "x", zipfile.ZIP_STORED)
1148n/a with zipfile.ZipFile(TESTFN2, "r") as zipfp:
1149n/a self.assertEqual(zipfp.namelist(), [filename])
1150n/a self.assertEqual(zipfp.read(filename), content)
1151n/a
1152n/a def test_create_non_existent_file_for_append(self):
1153n/a if os.path.exists(TESTFN):
1154n/a os.unlink(TESTFN)
1155n/a
1156n/a filename = 'testfile.txt'
1157n/a content = b'hello, world. this is some content.'
1158n/a
1159n/a try:
1160n/a with zipfile.ZipFile(TESTFN, 'a') as zf:
1161n/a zf.writestr(filename, content)
1162n/a except OSError:
1163n/a self.fail('Could not append data to a non-existent zip file.')
1164n/a
1165n/a self.assertTrue(os.path.exists(TESTFN))
1166n/a
1167n/a with zipfile.ZipFile(TESTFN, 'r') as zf:
1168n/a self.assertEqual(zf.read(filename), content)
1169n/a
1170n/a def test_close_erroneous_file(self):
1171n/a # This test checks that the ZipFile constructor closes the file object
1172n/a # it opens if there's an error in the file. If it doesn't, the
1173n/a # traceback holds a reference to the ZipFile object and, indirectly,
1174n/a # the file object.
1175n/a # On Windows, this causes the os.unlink() call to fail because the
1176n/a # underlying file is still open. This is SF bug #412214.
1177n/a #
1178n/a with open(TESTFN, "w") as fp:
1179n/a fp.write("this is not a legal zip file\n")
1180n/a try:
1181n/a zf = zipfile.ZipFile(TESTFN)
1182n/a except zipfile.BadZipFile:
1183n/a pass
1184n/a
1185n/a def test_is_zip_erroneous_file(self):
1186n/a """Check that is_zipfile() correctly identifies non-zip files."""
1187n/a # - passing a filename
1188n/a with open(TESTFN, "w") as fp:
1189n/a fp.write("this is not a legal zip file\n")
1190n/a self.assertFalse(zipfile.is_zipfile(TESTFN))
1191n/a # - passing a file object
1192n/a with open(TESTFN, "rb") as fp:
1193n/a self.assertFalse(zipfile.is_zipfile(fp))
1194n/a # - passing a file-like object
1195n/a fp = io.BytesIO()
1196n/a fp.write(b"this is not a legal zip file\n")
1197n/a self.assertFalse(zipfile.is_zipfile(fp))
1198n/a fp.seek(0, 0)
1199n/a self.assertFalse(zipfile.is_zipfile(fp))
1200n/a
1201n/a def test_damaged_zipfile(self):
1202n/a """Check that zipfiles with missing bytes at the end raise BadZipFile."""
1203n/a # - Create a valid zip file
1204n/a fp = io.BytesIO()
1205n/a with zipfile.ZipFile(fp, mode="w") as zipf:
1206n/a zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
1207n/a zipfiledata = fp.getvalue()
1208n/a
1209n/a # - Now create copies of it missing the last N bytes and make sure
1210n/a # a BadZipFile exception is raised when we try to open it
1211n/a for N in range(len(zipfiledata)):
1212n/a fp = io.BytesIO(zipfiledata[:N])
1213n/a self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, fp)
1214n/a
1215n/a def test_is_zip_valid_file(self):
1216n/a """Check that is_zipfile() correctly identifies zip files."""
1217n/a # - passing a filename
1218n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1219n/a zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
1220n/a
1221n/a self.assertTrue(zipfile.is_zipfile(TESTFN))
1222n/a # - passing a file object
1223n/a with open(TESTFN, "rb") as fp:
1224n/a self.assertTrue(zipfile.is_zipfile(fp))
1225n/a fp.seek(0, 0)
1226n/a zip_contents = fp.read()
1227n/a # - passing a file-like object
1228n/a fp = io.BytesIO()
1229n/a fp.write(zip_contents)
1230n/a self.assertTrue(zipfile.is_zipfile(fp))
1231n/a fp.seek(0, 0)
1232n/a self.assertTrue(zipfile.is_zipfile(fp))
1233n/a
1234n/a def test_non_existent_file_raises_OSError(self):
1235n/a # make sure we don't raise an AttributeError when a partially-constructed
1236n/a # ZipFile instance is finalized; this tests for regression on SF tracker
1237n/a # bug #403871.
1238n/a
1239n/a # The bug we're testing for caused an AttributeError to be raised
1240n/a # when a ZipFile instance was created for a file that did not
1241n/a # exist; the .fp member was not initialized but was needed by the
1242n/a # __del__() method. Since the AttributeError is in the __del__(),
1243n/a # it is ignored, but the user should be sufficiently annoyed by
1244n/a # the message on the output that regression will be noticed
1245n/a # quickly.
1246n/a self.assertRaises(OSError, zipfile.ZipFile, TESTFN)
1247n/a
1248n/a def test_empty_file_raises_BadZipFile(self):
1249n/a f = open(TESTFN, 'w')
1250n/a f.close()
1251n/a self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
1252n/a
1253n/a with open(TESTFN, 'w') as fp:
1254n/a fp.write("short file")
1255n/a self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN)
1256n/a
1257n/a def test_closed_zip_raises_ValueError(self):
1258n/a """Verify that testzip() doesn't swallow inappropriate exceptions."""
1259n/a data = io.BytesIO()
1260n/a with zipfile.ZipFile(data, mode="w") as zipf:
1261n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1262n/a
1263n/a # This is correct; calling .read on a closed ZipFile should raise
1264n/a # a ValueError, and so should calling .testzip. An earlier
1265n/a # version of .testzip would swallow this exception (and any other)
1266n/a # and report that the first file in the archive was corrupt.
1267n/a self.assertRaises(ValueError, zipf.read, "foo.txt")
1268n/a self.assertRaises(ValueError, zipf.open, "foo.txt")
1269n/a self.assertRaises(ValueError, zipf.testzip)
1270n/a self.assertRaises(ValueError, zipf.writestr, "bogus.txt", "bogus")
1271n/a with open(TESTFN, 'w') as f:
1272n/a f.write('zipfile test data')
1273n/a self.assertRaises(ValueError, zipf.write, TESTFN)
1274n/a
1275n/a def test_bad_constructor_mode(self):
1276n/a """Check that bad modes passed to ZipFile constructor are caught."""
1277n/a self.assertRaises(ValueError, zipfile.ZipFile, TESTFN, "q")
1278n/a
1279n/a def test_bad_open_mode(self):
1280n/a """Check that bad modes passed to ZipFile.open are caught."""
1281n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1282n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1283n/a
1284n/a with zipfile.ZipFile(TESTFN, mode="r") as zipf:
1285n/a # read the data to make sure the file is there
1286n/a zipf.read("foo.txt")
1287n/a self.assertRaises(ValueError, zipf.open, "foo.txt", "q")
1288n/a # universal newlines support is removed
1289n/a self.assertRaises(ValueError, zipf.open, "foo.txt", "U")
1290n/a self.assertRaises(ValueError, zipf.open, "foo.txt", "rU")
1291n/a
1292n/a def test_read0(self):
1293n/a """Check that calling read(0) on a ZipExtFile object returns an empty
1294n/a string and doesn't advance file pointer."""
1295n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1296n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1297n/a # read the data to make sure the file is there
1298n/a with zipf.open("foo.txt") as f:
1299n/a for i in range(FIXEDTEST_SIZE):
1300n/a self.assertEqual(f.read(0), b'')
1301n/a
1302n/a self.assertEqual(f.read(), b"O, for a Muse of Fire!")
1303n/a
1304n/a def test_open_non_existent_item(self):
1305n/a """Check that attempting to call open() for an item that doesn't
1306n/a exist in the archive raises a RuntimeError."""
1307n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1308n/a self.assertRaises(KeyError, zipf.open, "foo.txt", "r")
1309n/a
1310n/a def test_bad_compression_mode(self):
1311n/a """Check that bad compression methods passed to ZipFile.open are
1312n/a caught."""
1313n/a self.assertRaises(NotImplementedError, zipfile.ZipFile, TESTFN, "w", -1)
1314n/a
1315n/a def test_unsupported_compression(self):
1316n/a # data is declared as shrunk, but actually deflated
1317n/a data = (b'PK\x03\x04.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00'
1318n/a b'\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00x\x03\x00PK\x01'
1319n/a b'\x02.\x03.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00\x00\x02\x00\x00'
1320n/a b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1321n/a b'\x80\x01\x00\x00\x00\x00xPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00'
1322n/a b'/\x00\x00\x00!\x00\x00\x00\x00\x00')
1323n/a with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
1324n/a self.assertRaises(NotImplementedError, zipf.open, 'x')
1325n/a
1326n/a def test_null_byte_in_filename(self):
1327n/a """Check that a filename containing a null byte is properly
1328n/a terminated."""
1329n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1330n/a zipf.writestr("foo.txt\x00qqq", b"O, for a Muse of Fire!")
1331n/a self.assertEqual(zipf.namelist(), ['foo.txt'])
1332n/a
1333n/a def test_struct_sizes(self):
1334n/a """Check that ZIP internal structure sizes are calculated correctly."""
1335n/a self.assertEqual(zipfile.sizeEndCentDir, 22)
1336n/a self.assertEqual(zipfile.sizeCentralDir, 46)
1337n/a self.assertEqual(zipfile.sizeEndCentDir64, 56)
1338n/a self.assertEqual(zipfile.sizeEndCentDir64Locator, 20)
1339n/a
1340n/a def test_comments(self):
1341n/a """Check that comments on the archive are handled properly."""
1342n/a
1343n/a # check default comment is empty
1344n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1345n/a self.assertEqual(zipf.comment, b'')
1346n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1347n/a
1348n/a with zipfile.ZipFile(TESTFN, mode="r") as zipfr:
1349n/a self.assertEqual(zipfr.comment, b'')
1350n/a
1351n/a # check a simple short comment
1352n/a comment = b'Bravely taking to his feet, he beat a very brave retreat.'
1353n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1354n/a zipf.comment = comment
1355n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1356n/a with zipfile.ZipFile(TESTFN, mode="r") as zipfr:
1357n/a self.assertEqual(zipf.comment, comment)
1358n/a
1359n/a # check a comment of max length
1360n/a comment2 = ''.join(['%d' % (i**3 % 10) for i in range((1 << 16)-1)])
1361n/a comment2 = comment2.encode("ascii")
1362n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1363n/a zipf.comment = comment2
1364n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1365n/a
1366n/a with zipfile.ZipFile(TESTFN, mode="r") as zipfr:
1367n/a self.assertEqual(zipfr.comment, comment2)
1368n/a
1369n/a # check a comment that is too long is truncated
1370n/a with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1371n/a with self.assertWarns(UserWarning):
1372n/a zipf.comment = comment2 + b'oops'
1373n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1374n/a with zipfile.ZipFile(TESTFN, mode="r") as zipfr:
1375n/a self.assertEqual(zipfr.comment, comment2)
1376n/a
1377n/a # check that comments are correctly modified in append mode
1378n/a with zipfile.ZipFile(TESTFN,mode="w") as zipf:
1379n/a zipf.comment = b"original comment"
1380n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1381n/a with zipfile.ZipFile(TESTFN,mode="a") as zipf:
1382n/a zipf.comment = b"an updated comment"
1383n/a with zipfile.ZipFile(TESTFN,mode="r") as zipf:
1384n/a self.assertEqual(zipf.comment, b"an updated comment")
1385n/a
1386n/a # check that comments are correctly shortened in append mode
1387n/a with zipfile.ZipFile(TESTFN,mode="w") as zipf:
1388n/a zipf.comment = b"original comment that's longer"
1389n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1390n/a with zipfile.ZipFile(TESTFN,mode="a") as zipf:
1391n/a zipf.comment = b"shorter comment"
1392n/a with zipfile.ZipFile(TESTFN,mode="r") as zipf:
1393n/a self.assertEqual(zipf.comment, b"shorter comment")
1394n/a
1395n/a def test_unicode_comment(self):
1396n/a with zipfile.ZipFile(TESTFN, "w", zipfile.ZIP_STORED) as zipf:
1397n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1398n/a with self.assertRaises(TypeError):
1399n/a zipf.comment = "this is an error"
1400n/a
1401n/a def test_change_comment_in_empty_archive(self):
1402n/a with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf:
1403n/a self.assertFalse(zipf.filelist)
1404n/a zipf.comment = b"this is a comment"
1405n/a with zipfile.ZipFile(TESTFN, "r") as zipf:
1406n/a self.assertEqual(zipf.comment, b"this is a comment")
1407n/a
1408n/a def test_change_comment_in_nonempty_archive(self):
1409n/a with zipfile.ZipFile(TESTFN, "w", zipfile.ZIP_STORED) as zipf:
1410n/a zipf.writestr("foo.txt", "O, for a Muse of Fire!")
1411n/a with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf:
1412n/a self.assertTrue(zipf.filelist)
1413n/a zipf.comment = b"this is a comment"
1414n/a with zipfile.ZipFile(TESTFN, "r") as zipf:
1415n/a self.assertEqual(zipf.comment, b"this is a comment")
1416n/a
1417n/a def test_empty_zipfile(self):
1418n/a # Check that creating a file in 'w' or 'a' mode and closing without
1419n/a # adding any files to the archives creates a valid empty ZIP file
1420n/a zipf = zipfile.ZipFile(TESTFN, mode="w")
1421n/a zipf.close()
1422n/a try:
1423n/a zipf = zipfile.ZipFile(TESTFN, mode="r")
1424n/a except zipfile.BadZipFile:
1425n/a self.fail("Unable to create empty ZIP file in 'w' mode")
1426n/a
1427n/a zipf = zipfile.ZipFile(TESTFN, mode="a")
1428n/a zipf.close()
1429n/a try:
1430n/a zipf = zipfile.ZipFile(TESTFN, mode="r")
1431n/a except:
1432n/a self.fail("Unable to create empty ZIP file in 'a' mode")
1433n/a
1434n/a def test_open_empty_file(self):
1435n/a # Issue 1710703: Check that opening a file with less than 22 bytes
1436n/a # raises a BadZipFile exception (rather than the previously unhelpful
1437n/a # OSError)
1438n/a f = open(TESTFN, 'w')
1439n/a f.close()
1440n/a self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN, 'r')
1441n/a
1442n/a def test_create_zipinfo_before_1980(self):
1443n/a self.assertRaises(ValueError,
1444n/a zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0))
1445n/a
1446n/a def test_zipfile_with_short_extra_field(self):
1447n/a """If an extra field in the header is less than 4 bytes, skip it."""
1448n/a zipdata = (
1449n/a b'PK\x03\x04\x14\x00\x00\x00\x00\x00\x93\x9b\xad@\x8b\x9e'
1450n/a b'\xd9\xd3\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x03\x00ab'
1451n/a b'c\x00\x00\x00APK\x01\x02\x14\x03\x14\x00\x00\x00\x00'
1452n/a b'\x00\x93\x9b\xad@\x8b\x9e\xd9\xd3\x01\x00\x00\x00\x01\x00\x00'
1453n/a b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00'
1454n/a b'\x00\x00\x00abc\x00\x00PK\x05\x06\x00\x00\x00\x00'
1455n/a b'\x01\x00\x01\x003\x00\x00\x00%\x00\x00\x00\x00\x00'
1456n/a )
1457n/a with zipfile.ZipFile(io.BytesIO(zipdata), 'r') as zipf:
1458n/a # testzip returns the name of the first corrupt file, or None
1459n/a self.assertIsNone(zipf.testzip())
1460n/a
1461n/a def test_open_conflicting_handles(self):
1462n/a # It's only possible to open one writable file handle at a time
1463n/a msg1 = b"It's fun to charter an accountant!"
1464n/a msg2 = b"And sail the wide accountant sea"
1465n/a msg3 = b"To find, explore the funds offshore"
1466n/a with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_STORED) as zipf:
1467n/a with zipf.open('foo', mode='w') as w2:
1468n/a w2.write(msg1)
1469n/a with zipf.open('bar', mode='w') as w1:
1470n/a with self.assertRaises(ValueError):
1471n/a zipf.open('handle', mode='w')
1472n/a with self.assertRaises(ValueError):
1473n/a zipf.open('foo', mode='r')
1474n/a with self.assertRaises(ValueError):
1475n/a zipf.writestr('str', 'abcde')
1476n/a with self.assertRaises(ValueError):
1477n/a zipf.write(__file__, 'file')
1478n/a with self.assertRaises(ValueError):
1479n/a zipf.close()
1480n/a w1.write(msg2)
1481n/a with zipf.open('baz', mode='w') as w2:
1482n/a w2.write(msg3)
1483n/a
1484n/a with zipfile.ZipFile(TESTFN2, 'r') as zipf:
1485n/a self.assertEqual(zipf.read('foo'), msg1)
1486n/a self.assertEqual(zipf.read('bar'), msg2)
1487n/a self.assertEqual(zipf.read('baz'), msg3)
1488n/a self.assertEqual(zipf.namelist(), ['foo', 'bar', 'baz'])
1489n/a
1490n/a def tearDown(self):
1491n/a unlink(TESTFN)
1492n/a unlink(TESTFN2)
1493n/a
1494n/a
1495n/aclass AbstractBadCrcTests:
1496n/a def test_testzip_with_bad_crc(self):
1497n/a """Tests that files with bad CRCs return their name from testzip."""
1498n/a zipdata = self.zip_with_bad_crc
1499n/a
1500n/a with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
1501n/a # testzip returns the name of the first corrupt file, or None
1502n/a self.assertEqual('afile', zipf.testzip())
1503n/a
1504n/a def test_read_with_bad_crc(self):
1505n/a """Tests that files with bad CRCs raise a BadZipFile exception when read."""
1506n/a zipdata = self.zip_with_bad_crc
1507n/a
1508n/a # Using ZipFile.read()
1509n/a with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
1510n/a self.assertRaises(zipfile.BadZipFile, zipf.read, 'afile')
1511n/a
1512n/a # Using ZipExtFile.read()
1513n/a with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
1514n/a with zipf.open('afile', 'r') as corrupt_file:
1515n/a self.assertRaises(zipfile.BadZipFile, corrupt_file.read)
1516n/a
1517n/a # Same with small reads (in order to exercise the buffering logic)
1518n/a with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
1519n/a with zipf.open('afile', 'r') as corrupt_file:
1520n/a corrupt_file.MIN_READ_SIZE = 2
1521n/a with self.assertRaises(zipfile.BadZipFile):
1522n/a while corrupt_file.read(2):
1523n/a pass
1524n/a
1525n/a
1526n/aclass StoredBadCrcTests(AbstractBadCrcTests, unittest.TestCase):
1527n/a compression = zipfile.ZIP_STORED
1528n/a zip_with_bad_crc = (
1529n/a b'PK\003\004\024\0\0\0\0\0 \213\212;:r'
1530n/a b'\253\377\f\0\0\0\f\0\0\0\005\0\0\000af'
1531n/a b'ilehello,AworldP'
1532n/a b'K\001\002\024\003\024\0\0\0\0\0 \213\212;:'
1533n/a b'r\253\377\f\0\0\0\f\0\0\0\005\0\0\0\0'
1534n/a b'\0\0\0\0\0\0\0\200\001\0\0\0\000afi'
1535n/a b'lePK\005\006\0\0\0\0\001\0\001\0003\000'
1536n/a b'\0\0/\0\0\0\0\0')
1537n/a
1538n/a@requires_zlib
1539n/aclass DeflateBadCrcTests(AbstractBadCrcTests, unittest.TestCase):
1540n/a compression = zipfile.ZIP_DEFLATED
1541n/a zip_with_bad_crc = (
1542n/a b'PK\x03\x04\x14\x00\x00\x00\x08\x00n}\x0c=FA'
1543n/a b'KE\x10\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00af'
1544n/a b'ile\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\xc9\xa0'
1545n/a b'=\x13\x00PK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00n'
1546n/a b'}\x0c=FAKE\x10\x00\x00\x00n\x00\x00\x00\x05'
1547n/a b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00'
1548n/a b'\x00afilePK\x05\x06\x00\x00\x00\x00\x01\x00'
1549n/a b'\x01\x003\x00\x00\x003\x00\x00\x00\x00\x00')
1550n/a
1551n/a@requires_bz2
1552n/aclass Bzip2BadCrcTests(AbstractBadCrcTests, unittest.TestCase):
1553n/a compression = zipfile.ZIP_BZIP2
1554n/a zip_with_bad_crc = (
1555n/a b'PK\x03\x04\x14\x03\x00\x00\x0c\x00nu\x0c=FA'
1556n/a b'KE8\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00af'
1557n/a b'ileBZh91AY&SY\xd4\xa8\xca'
1558n/a b'\x7f\x00\x00\x0f\x11\x80@\x00\x06D\x90\x80 \x00 \xa5'
1559n/a b'P\xd9!\x03\x03\x13\x13\x13\x89\xa9\xa9\xc2u5:\x9f'
1560n/a b'\x8b\xb9"\x9c(HjTe?\x80PK\x01\x02\x14'
1561n/a b'\x03\x14\x03\x00\x00\x0c\x00nu\x0c=FAKE8'
1562n/a b'\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00'
1563n/a b'\x00 \x80\x80\x81\x00\x00\x00\x00afilePK'
1564n/a b'\x05\x06\x00\x00\x00\x00\x01\x00\x01\x003\x00\x00\x00[\x00'
1565n/a b'\x00\x00\x00\x00')
1566n/a
1567n/a@requires_lzma
1568n/aclass LzmaBadCrcTests(AbstractBadCrcTests, unittest.TestCase):
1569n/a compression = zipfile.ZIP_LZMA
1570n/a zip_with_bad_crc = (
1571n/a b'PK\x03\x04\x14\x03\x00\x00\x0e\x00nu\x0c=FA'
1572n/a b'KE\x1b\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00af'
1573n/a b'ile\t\x04\x05\x00]\x00\x00\x00\x04\x004\x19I'
1574n/a b'\xee\x8d\xe9\x17\x89:3`\tq!.8\x00PK'
1575n/a b'\x01\x02\x14\x03\x14\x03\x00\x00\x0e\x00nu\x0c=FA'
1576n/a b'KE\x1b\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00\x00\x00'
1577n/a b'\x00\x00\x00\x00 \x80\x80\x81\x00\x00\x00\x00afil'
1578n/a b'ePK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x003\x00\x00'
1579n/a b'\x00>\x00\x00\x00\x00\x00')
1580n/a
1581n/a
1582n/aclass DecryptionTests(unittest.TestCase):
1583n/a """Check that ZIP decryption works. Since the library does not
1584n/a support encryption at the moment, we use a pre-generated encrypted
1585n/a ZIP file."""
1586n/a
1587n/a data = (
1588n/a b'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
1589n/a b'\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
1590n/a b'\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
1591n/a b'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
1592n/a b'\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
1593n/a b'\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
1594n/a b'\x00\x00L\x00\x00\x00\x00\x00' )
1595n/a data2 = (
1596n/a b'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02'
1597n/a b'\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04'
1598n/a b'\x00\xe8\x03\xe8\x03\xc7<M\xb5a\xceX\xa3Y&\x8b{oE\xd7\x9d\x8c\x98\x02\xc0'
1599n/a b'PK\x07\x08xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00PK\x01\x02\x17\x03'
1600n/a b'\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00'
1601n/a b'\x04\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00ze'
1602n/a b'roUT\x05\x00\x03\xd6\x8b\x92GUx\x00\x00PK\x05\x06\x00\x00\x00\x00\x01'
1603n/a b'\x00\x01\x00?\x00\x00\x00[\x00\x00\x00\x00\x00' )
1604n/a
1605n/a plain = b'zipfile.py encryption test'
1606n/a plain2 = b'\x00'*512
1607n/a
1608n/a def setUp(self):
1609n/a with open(TESTFN, "wb") as fp:
1610n/a fp.write(self.data)
1611n/a self.zip = zipfile.ZipFile(TESTFN, "r")
1612n/a with open(TESTFN2, "wb") as fp:
1613n/a fp.write(self.data2)
1614n/a self.zip2 = zipfile.ZipFile(TESTFN2, "r")
1615n/a
1616n/a def tearDown(self):
1617n/a self.zip.close()
1618n/a os.unlink(TESTFN)
1619n/a self.zip2.close()
1620n/a os.unlink(TESTFN2)
1621n/a
1622n/a def test_no_password(self):
1623n/a # Reading the encrypted file without password
1624n/a # must generate a RunTime exception
1625n/a self.assertRaises(RuntimeError, self.zip.read, "test.txt")
1626n/a self.assertRaises(RuntimeError, self.zip2.read, "zero")
1627n/a
1628n/a def test_bad_password(self):
1629n/a self.zip.setpassword(b"perl")
1630n/a self.assertRaises(RuntimeError, self.zip.read, "test.txt")
1631n/a self.zip2.setpassword(b"perl")
1632n/a self.assertRaises(RuntimeError, self.zip2.read, "zero")
1633n/a
1634n/a @requires_zlib
1635n/a def test_good_password(self):
1636n/a self.zip.setpassword(b"python")
1637n/a self.assertEqual(self.zip.read("test.txt"), self.plain)
1638n/a self.zip2.setpassword(b"12345")
1639n/a self.assertEqual(self.zip2.read("zero"), self.plain2)
1640n/a
1641n/a def test_unicode_password(self):
1642n/a self.assertRaises(TypeError, self.zip.setpassword, "unicode")
1643n/a self.assertRaises(TypeError, self.zip.read, "test.txt", "python")
1644n/a self.assertRaises(TypeError, self.zip.open, "test.txt", pwd="python")
1645n/a self.assertRaises(TypeError, self.zip.extract, "test.txt", pwd="python")
1646n/a
1647n/aclass AbstractTestsWithRandomBinaryFiles:
1648n/a @classmethod
1649n/a def setUpClass(cls):
1650n/a datacount = randint(16, 64)*1024 + randint(1, 1024)
1651n/a cls.data = b''.join(struct.pack('<f', random()*randint(-1000, 1000))
1652n/a for i in range(datacount))
1653n/a
1654n/a def setUp(self):
1655n/a # Make a source file with some lines
1656n/a with open(TESTFN, "wb") as fp:
1657n/a fp.write(self.data)
1658n/a
1659n/a def tearDown(self):
1660n/a unlink(TESTFN)
1661n/a unlink(TESTFN2)
1662n/a
1663n/a def make_test_archive(self, f, compression):
1664n/a # Create the ZIP archive
1665n/a with zipfile.ZipFile(f, "w", compression) as zipfp:
1666n/a zipfp.write(TESTFN, "another.name")
1667n/a zipfp.write(TESTFN, TESTFN)
1668n/a
1669n/a def zip_test(self, f, compression):
1670n/a self.make_test_archive(f, compression)
1671n/a
1672n/a # Read the ZIP archive
1673n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
1674n/a testdata = zipfp.read(TESTFN)
1675n/a self.assertEqual(len(testdata), len(self.data))
1676n/a self.assertEqual(testdata, self.data)
1677n/a self.assertEqual(zipfp.read("another.name"), self.data)
1678n/a
1679n/a def test_read(self):
1680n/a for f in get_files(self):
1681n/a self.zip_test(f, self.compression)
1682n/a
1683n/a def zip_open_test(self, f, compression):
1684n/a self.make_test_archive(f, compression)
1685n/a
1686n/a # Read the ZIP archive
1687n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
1688n/a zipdata1 = []
1689n/a with zipfp.open(TESTFN) as zipopen1:
1690n/a while True:
1691n/a read_data = zipopen1.read(256)
1692n/a if not read_data:
1693n/a break
1694n/a zipdata1.append(read_data)
1695n/a
1696n/a zipdata2 = []
1697n/a with zipfp.open("another.name") as zipopen2:
1698n/a while True:
1699n/a read_data = zipopen2.read(256)
1700n/a if not read_data:
1701n/a break
1702n/a zipdata2.append(read_data)
1703n/a
1704n/a testdata1 = b''.join(zipdata1)
1705n/a self.assertEqual(len(testdata1), len(self.data))
1706n/a self.assertEqual(testdata1, self.data)
1707n/a
1708n/a testdata2 = b''.join(zipdata2)
1709n/a self.assertEqual(len(testdata2), len(self.data))
1710n/a self.assertEqual(testdata2, self.data)
1711n/a
1712n/a def test_open(self):
1713n/a for f in get_files(self):
1714n/a self.zip_open_test(f, self.compression)
1715n/a
1716n/a def zip_random_open_test(self, f, compression):
1717n/a self.make_test_archive(f, compression)
1718n/a
1719n/a # Read the ZIP archive
1720n/a with zipfile.ZipFile(f, "r", compression) as zipfp:
1721n/a zipdata1 = []
1722n/a with zipfp.open(TESTFN) as zipopen1:
1723n/a while True:
1724n/a read_data = zipopen1.read(randint(1, 1024))
1725n/a if not read_data:
1726n/a break
1727n/a zipdata1.append(read_data)
1728n/a
1729n/a testdata = b''.join(zipdata1)
1730n/a self.assertEqual(len(testdata), len(self.data))
1731n/a self.assertEqual(testdata, self.data)
1732n/a
1733n/a def test_random_open(self):
1734n/a for f in get_files(self):
1735n/a self.zip_random_open_test(f, self.compression)
1736n/a
1737n/a
1738n/aclass StoredTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles,
1739n/a unittest.TestCase):
1740n/a compression = zipfile.ZIP_STORED
1741n/a
1742n/a@requires_zlib
1743n/aclass DeflateTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles,
1744n/a unittest.TestCase):
1745n/a compression = zipfile.ZIP_DEFLATED
1746n/a
1747n/a@requires_bz2
1748n/aclass Bzip2TestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles,
1749n/a unittest.TestCase):
1750n/a compression = zipfile.ZIP_BZIP2
1751n/a
1752n/a@requires_lzma
1753n/aclass LzmaTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles,
1754n/a unittest.TestCase):
1755n/a compression = zipfile.ZIP_LZMA
1756n/a
1757n/a
1758n/a# Privide the tell() method but not seek()
1759n/aclass Tellable:
1760n/a def __init__(self, fp):
1761n/a self.fp = fp
1762n/a self.offset = 0
1763n/a
1764n/a def write(self, data):
1765n/a n = self.fp.write(data)
1766n/a self.offset += n
1767n/a return n
1768n/a
1769n/a def tell(self):
1770n/a return self.offset
1771n/a
1772n/a def flush(self):
1773n/a self.fp.flush()
1774n/a
1775n/aclass Unseekable:
1776n/a def __init__(self, fp):
1777n/a self.fp = fp
1778n/a
1779n/a def write(self, data):
1780n/a return self.fp.write(data)
1781n/a
1782n/a def flush(self):
1783n/a self.fp.flush()
1784n/a
1785n/aclass UnseekableTests(unittest.TestCase):
1786n/a def test_writestr(self):
1787n/a for wrapper in (lambda f: f), Tellable, Unseekable:
1788n/a with self.subTest(wrapper=wrapper):
1789n/a f = io.BytesIO()
1790n/a f.write(b'abc')
1791n/a bf = io.BufferedWriter(f)
1792n/a with zipfile.ZipFile(wrapper(bf), 'w', zipfile.ZIP_STORED) as zipfp:
1793n/a zipfp.writestr('ones', b'111')
1794n/a zipfp.writestr('twos', b'222')
1795n/a self.assertEqual(f.getvalue()[:5], b'abcPK')
1796n/a with zipfile.ZipFile(f, mode='r') as zipf:
1797n/a with zipf.open('ones') as zopen:
1798n/a self.assertEqual(zopen.read(), b'111')
1799n/a with zipf.open('twos') as zopen:
1800n/a self.assertEqual(zopen.read(), b'222')
1801n/a
1802n/a def test_write(self):
1803n/a for wrapper in (lambda f: f), Tellable, Unseekable:
1804n/a with self.subTest(wrapper=wrapper):
1805n/a f = io.BytesIO()
1806n/a f.write(b'abc')
1807n/a bf = io.BufferedWriter(f)
1808n/a with zipfile.ZipFile(wrapper(bf), 'w', zipfile.ZIP_STORED) as zipfp:
1809n/a self.addCleanup(unlink, TESTFN)
1810n/a with open(TESTFN, 'wb') as f2:
1811n/a f2.write(b'111')
1812n/a zipfp.write(TESTFN, 'ones')
1813n/a with open(TESTFN, 'wb') as f2:
1814n/a f2.write(b'222')
1815n/a zipfp.write(TESTFN, 'twos')
1816n/a self.assertEqual(f.getvalue()[:5], b'abcPK')
1817n/a with zipfile.ZipFile(f, mode='r') as zipf:
1818n/a with zipf.open('ones') as zopen:
1819n/a self.assertEqual(zopen.read(), b'111')
1820n/a with zipf.open('twos') as zopen:
1821n/a self.assertEqual(zopen.read(), b'222')
1822n/a
1823n/a def test_open_write(self):
1824n/a for wrapper in (lambda f: f), Tellable, Unseekable:
1825n/a with self.subTest(wrapper=wrapper):
1826n/a f = io.BytesIO()
1827n/a f.write(b'abc')
1828n/a bf = io.BufferedWriter(f)
1829n/a with zipfile.ZipFile(wrapper(bf), 'w', zipfile.ZIP_STORED) as zipf:
1830n/a with zipf.open('ones', 'w') as zopen:
1831n/a zopen.write(b'111')
1832n/a with zipf.open('twos', 'w') as zopen:
1833n/a zopen.write(b'222')
1834n/a self.assertEqual(f.getvalue()[:5], b'abcPK')
1835n/a with zipfile.ZipFile(f) as zipf:
1836n/a self.assertEqual(zipf.read('ones'), b'111')
1837n/a self.assertEqual(zipf.read('twos'), b'222')
1838n/a
1839n/a
1840n/a@requires_zlib
1841n/aclass TestsWithMultipleOpens(unittest.TestCase):
1842n/a @classmethod
1843n/a def setUpClass(cls):
1844n/a cls.data1 = b'111' + getrandbytes(10000)
1845n/a cls.data2 = b'222' + getrandbytes(10000)
1846n/a
1847n/a def make_test_archive(self, f):
1848n/a # Create the ZIP archive
1849n/a with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipfp:
1850n/a zipfp.writestr('ones', self.data1)
1851n/a zipfp.writestr('twos', self.data2)
1852n/a
1853n/a def test_same_file(self):
1854n/a # Verify that (when the ZipFile is in control of creating file objects)
1855n/a # multiple open() calls can be made without interfering with each other.
1856n/a for f in get_files(self):
1857n/a self.make_test_archive(f)
1858n/a with zipfile.ZipFile(f, mode="r") as zipf:
1859n/a with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2:
1860n/a data1 = zopen1.read(500)
1861n/a data2 = zopen2.read(500)
1862n/a data1 += zopen1.read()
1863n/a data2 += zopen2.read()
1864n/a self.assertEqual(data1, data2)
1865n/a self.assertEqual(data1, self.data1)
1866n/a
1867n/a def test_different_file(self):
1868n/a # Verify that (when the ZipFile is in control of creating file objects)
1869n/a # multiple open() calls can be made without interfering with each other.
1870n/a for f in get_files(self):
1871n/a self.make_test_archive(f)
1872n/a with zipfile.ZipFile(f, mode="r") as zipf:
1873n/a with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
1874n/a data1 = zopen1.read(500)
1875n/a data2 = zopen2.read(500)
1876n/a data1 += zopen1.read()
1877n/a data2 += zopen2.read()
1878n/a self.assertEqual(data1, self.data1)
1879n/a self.assertEqual(data2, self.data2)
1880n/a
1881n/a def test_interleaved(self):
1882n/a # Verify that (when the ZipFile is in control of creating file objects)
1883n/a # multiple open() calls can be made without interfering with each other.
1884n/a for f in get_files(self):
1885n/a self.make_test_archive(f)
1886n/a with zipfile.ZipFile(f, mode="r") as zipf:
1887n/a with zipf.open('ones') as zopen1:
1888n/a data1 = zopen1.read(500)
1889n/a with zipf.open('twos') as zopen2:
1890n/a data2 = zopen2.read(500)
1891n/a data1 += zopen1.read()
1892n/a data2 += zopen2.read()
1893n/a self.assertEqual(data1, self.data1)
1894n/a self.assertEqual(data2, self.data2)
1895n/a
1896n/a def test_read_after_close(self):
1897n/a for f in get_files(self):
1898n/a self.make_test_archive(f)
1899n/a with contextlib.ExitStack() as stack:
1900n/a with zipfile.ZipFile(f, 'r') as zipf:
1901n/a zopen1 = stack.enter_context(zipf.open('ones'))
1902n/a zopen2 = stack.enter_context(zipf.open('twos'))
1903n/a data1 = zopen1.read(500)
1904n/a data2 = zopen2.read(500)
1905n/a data1 += zopen1.read()
1906n/a data2 += zopen2.read()
1907n/a self.assertEqual(data1, self.data1)
1908n/a self.assertEqual(data2, self.data2)
1909n/a
1910n/a def test_read_after_write(self):
1911n/a for f in get_files(self):
1912n/a with zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED) as zipf:
1913n/a zipf.writestr('ones', self.data1)
1914n/a zipf.writestr('twos', self.data2)
1915n/a with zipf.open('ones') as zopen1:
1916n/a data1 = zopen1.read(500)
1917n/a self.assertEqual(data1, self.data1[:500])
1918n/a with zipfile.ZipFile(f, 'r') as zipf:
1919n/a data1 = zipf.read('ones')
1920n/a data2 = zipf.read('twos')
1921n/a self.assertEqual(data1, self.data1)
1922n/a self.assertEqual(data2, self.data2)
1923n/a
1924n/a def test_write_after_read(self):
1925n/a for f in get_files(self):
1926n/a with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipf:
1927n/a zipf.writestr('ones', self.data1)
1928n/a with zipf.open('ones') as zopen1:
1929n/a zopen1.read(500)
1930n/a zipf.writestr('twos', self.data2)
1931n/a with zipfile.ZipFile(f, 'r') as zipf:
1932n/a data1 = zipf.read('ones')
1933n/a data2 = zipf.read('twos')
1934n/a self.assertEqual(data1, self.data1)
1935n/a self.assertEqual(data2, self.data2)
1936n/a
1937n/a def test_many_opens(self):
1938n/a # Verify that read() and open() promptly close the file descriptor,
1939n/a # and don't rely on the garbage collector to free resources.
1940n/a self.make_test_archive(TESTFN2)
1941n/a with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
1942n/a for x in range(100):
1943n/a zipf.read('ones')
1944n/a with zipf.open('ones') as zopen1:
1945n/a pass
1946n/a with open(os.devnull) as f:
1947n/a self.assertLess(f.fileno(), 100)
1948n/a
1949n/a def test_write_while_reading(self):
1950n/a with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_DEFLATED) as zipf:
1951n/a zipf.writestr('ones', self.data1)
1952n/a with zipfile.ZipFile(TESTFN2, 'a', zipfile.ZIP_DEFLATED) as zipf:
1953n/a with zipf.open('ones', 'r') as r1:
1954n/a data1 = r1.read(500)
1955n/a with zipf.open('twos', 'w') as w1:
1956n/a w1.write(self.data2)
1957n/a data1 += r1.read()
1958n/a self.assertEqual(data1, self.data1)
1959n/a with zipfile.ZipFile(TESTFN2) as zipf:
1960n/a self.assertEqual(zipf.read('twos'), self.data2)
1961n/a
1962n/a def tearDown(self):
1963n/a unlink(TESTFN2)
1964n/a
1965n/a
1966n/aclass TestWithDirectory(unittest.TestCase):
1967n/a def setUp(self):
1968n/a os.mkdir(TESTFN2)
1969n/a
1970n/a def test_extract_dir(self):
1971n/a with zipfile.ZipFile(findfile("zipdir.zip")) as zipf:
1972n/a zipf.extractall(TESTFN2)
1973n/a self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a")))
1974n/a self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b")))
1975n/a self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c")))
1976n/a
1977n/a def test_bug_6050(self):
1978n/a # Extraction should succeed if directories already exist
1979n/a os.mkdir(os.path.join(TESTFN2, "a"))
1980n/a self.test_extract_dir()
1981n/a
1982n/a def test_write_dir(self):
1983n/a dirpath = os.path.join(TESTFN2, "x")
1984n/a os.mkdir(dirpath)
1985n/a mode = os.stat(dirpath).st_mode & 0xFFFF
1986n/a with zipfile.ZipFile(TESTFN, "w") as zipf:
1987n/a zipf.write(dirpath)
1988n/a zinfo = zipf.filelist[0]
1989n/a self.assertTrue(zinfo.filename.endswith("/x/"))
1990n/a self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10)
1991n/a zipf.write(dirpath, "y")
1992n/a zinfo = zipf.filelist[1]
1993n/a self.assertTrue(zinfo.filename, "y/")
1994n/a self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10)
1995n/a with zipfile.ZipFile(TESTFN, "r") as zipf:
1996n/a zinfo = zipf.filelist[0]
1997n/a self.assertTrue(zinfo.filename.endswith("/x/"))
1998n/a self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10)
1999n/a zinfo = zipf.filelist[1]
2000n/a self.assertTrue(zinfo.filename, "y/")
2001n/a self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10)
2002n/a target = os.path.join(TESTFN2, "target")
2003n/a os.mkdir(target)
2004n/a zipf.extractall(target)
2005n/a self.assertTrue(os.path.isdir(os.path.join(target, "y")))
2006n/a self.assertEqual(len(os.listdir(target)), 2)
2007n/a
2008n/a def test_writestr_dir(self):
2009n/a os.mkdir(os.path.join(TESTFN2, "x"))
2010n/a with zipfile.ZipFile(TESTFN, "w") as zipf:
2011n/a zipf.writestr("x/", b'')
2012n/a zinfo = zipf.filelist[0]
2013n/a self.assertEqual(zinfo.filename, "x/")
2014n/a self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10)
2015n/a with zipfile.ZipFile(TESTFN, "r") as zipf:
2016n/a zinfo = zipf.filelist[0]
2017n/a self.assertTrue(zinfo.filename.endswith("x/"))
2018n/a self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10)
2019n/a target = os.path.join(TESTFN2, "target")
2020n/a os.mkdir(target)
2021n/a zipf.extractall(target)
2022n/a self.assertTrue(os.path.isdir(os.path.join(target, "x")))
2023n/a self.assertEqual(os.listdir(target), ["x"])
2024n/a
2025n/a def tearDown(self):
2026n/a rmtree(TESTFN2)
2027n/a if os.path.exists(TESTFN):
2028n/a unlink(TESTFN)
2029n/a
2030n/a
2031n/aclass ZipInfoTests(unittest.TestCase):
2032n/a def test_from_file(self):
2033n/a zi = zipfile.ZipInfo.from_file(__file__)
2034n/a self.assertEqual(posixpath.basename(zi.filename), 'test_zipfile.py')
2035n/a self.assertFalse(zi.is_dir())
2036n/a
2037n/a def test_from_dir(self):
2038n/a dirpath = os.path.dirname(os.path.abspath(__file__))
2039n/a zi = zipfile.ZipInfo.from_file(dirpath, 'stdlib_tests')
2040n/a self.assertEqual(zi.filename, 'stdlib_tests/')
2041n/a self.assertTrue(zi.is_dir())
2042n/a self.assertEqual(zi.compress_type, zipfile.ZIP_STORED)
2043n/a self.assertEqual(zi.file_size, 0)
2044n/a
2045n/a
2046n/aclass CommandLineTest(unittest.TestCase):
2047n/a
2048n/a def zipfilecmd(self, *args, **kwargs):
2049n/a rc, out, err = script_helper.assert_python_ok('-m', 'zipfile', *args,
2050n/a **kwargs)
2051n/a return out.replace(os.linesep.encode(), b'\n')
2052n/a
2053n/a def zipfilecmd_failure(self, *args):
2054n/a return script_helper.assert_python_failure('-m', 'zipfile', *args)
2055n/a
2056n/a def test_test_command(self):
2057n/a zip_name = findfile('zipdir.zip')
2058n/a for opt in '-t', '--test':
2059n/a out = self.zipfilecmd(opt, zip_name)
2060n/a self.assertEqual(out.rstrip(), b'Done testing')
2061n/a zip_name = findfile('testtar.tar')
2062n/a rc, out, err = self.zipfilecmd_failure('-t', zip_name)
2063n/a self.assertEqual(out, b'')
2064n/a
2065n/a def test_list_command(self):
2066n/a zip_name = findfile('zipdir.zip')
2067n/a t = io.StringIO()
2068n/a with zipfile.ZipFile(zip_name, 'r') as tf:
2069n/a tf.printdir(t)
2070n/a expected = t.getvalue().encode('ascii', 'backslashreplace')
2071n/a for opt in '-l', '--list':
2072n/a out = self.zipfilecmd(opt, zip_name,
2073n/a PYTHONIOENCODING='ascii:backslashreplace')
2074n/a self.assertEqual(out, expected)
2075n/a
2076n/a @requires_zlib
2077n/a def test_create_command(self):
2078n/a self.addCleanup(unlink, TESTFN)
2079n/a with open(TESTFN, 'w') as f:
2080n/a f.write('test 1')
2081n/a os.mkdir(TESTFNDIR)
2082n/a self.addCleanup(rmtree, TESTFNDIR)
2083n/a with open(os.path.join(TESTFNDIR, 'file.txt'), 'w') as f:
2084n/a f.write('test 2')
2085n/a files = [TESTFN, TESTFNDIR]
2086n/a namelist = [TESTFN, TESTFNDIR + '/', TESTFNDIR + '/file.txt']
2087n/a for opt in '-c', '--create':
2088n/a try:
2089n/a out = self.zipfilecmd(opt, TESTFN2, *files)
2090n/a self.assertEqual(out, b'')
2091n/a with zipfile.ZipFile(TESTFN2) as zf:
2092n/a self.assertEqual(zf.namelist(), namelist)
2093n/a self.assertEqual(zf.read(namelist[0]), b'test 1')
2094n/a self.assertEqual(zf.read(namelist[2]), b'test 2')
2095n/a finally:
2096n/a unlink(TESTFN2)
2097n/a
2098n/a def test_extract_command(self):
2099n/a zip_name = findfile('zipdir.zip')
2100n/a for opt in '-e', '--extract':
2101n/a with temp_dir() as extdir:
2102n/a out = self.zipfilecmd(opt, zip_name, extdir)
2103n/a self.assertEqual(out, b'')
2104n/a with zipfile.ZipFile(zip_name) as zf:
2105n/a for zi in zf.infolist():
2106n/a path = os.path.join(extdir,
2107n/a zi.filename.replace('/', os.sep))
2108n/a if zi.is_dir():
2109n/a self.assertTrue(os.path.isdir(path))
2110n/a else:
2111n/a self.assertTrue(os.path.isfile(path))
2112n/a with open(path, 'rb') as f:
2113n/a self.assertEqual(f.read(), zf.read(zi))
2114n/a
2115n/aif __name__ == "__main__":
2116n/a unittest.main()