test_zipfile.py revision c328d11ef184e706e42149d740d99044d7d8981a
1# We can test part of the module without zlib. 2try: 3 import zlib 4except ImportError: 5 zlib = None 6 7import os 8import io 9import sys 10import time 11import struct 12import zipfile 13import unittest 14 15from StringIO import StringIO 16from tempfile import TemporaryFile 17from random import randint, random, getrandbits 18from unittest import skipUnless 19 20from test.test_support import TESTFN, TESTFN_UNICODE, TESTFN_ENCODING, \ 21 run_unittest, findfile, unlink, rmtree, check_warnings 22try: 23 TESTFN_UNICODE.encode(TESTFN_ENCODING) 24except (UnicodeError, TypeError): 25 # Either the file system encoding is None, or the file name 26 # cannot be encoded in the file system encoding. 27 TESTFN_UNICODE = None 28 29TESTFN2 = TESTFN + "2" 30TESTFNDIR = TESTFN + "d" 31FIXEDTEST_SIZE = 1000 32 33SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'), 34 ('ziptest2dir/_ziptest2', 'qawsedrftg'), 35 ('ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'), 36 ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')] 37 38def getrandbytes(size): 39 return bytes(bytearray.fromhex('%0*x' % (2 * size, getrandbits(8 * size)))) 40 41class TestsWithSourceFile(unittest.TestCase): 42 def setUp(self): 43 self.line_gen = ["Zipfile test line %d. random float: %f" % (i, random()) 44 for i in xrange(FIXEDTEST_SIZE)] 45 self.data = '\n'.join(self.line_gen) + '\n' 46 47 # Make a source file with some lines 48 with open(TESTFN, "wb") as fp: 49 fp.write(self.data) 50 51 def make_test_archive(self, f, compression): 52 # Create the ZIP archive 53 with zipfile.ZipFile(f, "w", compression) as zipfp: 54 zipfp.write(TESTFN, "another.name") 55 zipfp.write(TESTFN, TESTFN) 56 zipfp.writestr("strfile", self.data) 57 58 def zip_test(self, f, compression): 59 self.make_test_archive(f, compression) 60 61 # Read the ZIP archive 62 with zipfile.ZipFile(f, "r", compression) as zipfp: 63 self.assertEqual(zipfp.read(TESTFN), self.data) 64 self.assertEqual(zipfp.read("another.name"), self.data) 65 self.assertEqual(zipfp.read("strfile"), self.data) 66 67 # Print the ZIP directory 68 fp = StringIO() 69 stdout = sys.stdout 70 try: 71 sys.stdout = fp 72 zipfp.printdir() 73 finally: 74 sys.stdout = stdout 75 76 directory = fp.getvalue() 77 lines = directory.splitlines() 78 self.assertEqual(len(lines), 4) # Number of files + header 79 80 self.assertIn('File Name', lines[0]) 81 self.assertIn('Modified', lines[0]) 82 self.assertIn('Size', lines[0]) 83 84 fn, date, time_, size = lines[1].split() 85 self.assertEqual(fn, 'another.name') 86 self.assertTrue(time.strptime(date, '%Y-%m-%d')) 87 self.assertTrue(time.strptime(time_, '%H:%M:%S')) 88 self.assertEqual(size, str(len(self.data))) 89 90 # Check the namelist 91 names = zipfp.namelist() 92 self.assertEqual(len(names), 3) 93 self.assertIn(TESTFN, names) 94 self.assertIn("another.name", names) 95 self.assertIn("strfile", names) 96 97 # Check infolist 98 infos = zipfp.infolist() 99 names = [i.filename for i in infos] 100 self.assertEqual(len(names), 3) 101 self.assertIn(TESTFN, names) 102 self.assertIn("another.name", names) 103 self.assertIn("strfile", names) 104 for i in infos: 105 self.assertEqual(i.file_size, len(self.data)) 106 107 # check getinfo 108 for nm in (TESTFN, "another.name", "strfile"): 109 info = zipfp.getinfo(nm) 110 self.assertEqual(info.filename, nm) 111 self.assertEqual(info.file_size, len(self.data)) 112 113 # Check that testzip doesn't raise an exception 114 zipfp.testzip() 115 116 def test_stored(self): 117 for f in (TESTFN2, TemporaryFile(), StringIO()): 118 self.zip_test(f, zipfile.ZIP_STORED) 119 120 def zip_open_test(self, f, compression): 121 self.make_test_archive(f, compression) 122 123 # Read the ZIP archive 124 with zipfile.ZipFile(f, "r", compression) as zipfp: 125 zipdata1 = [] 126 with zipfp.open(TESTFN) as zipopen1: 127 while True: 128 read_data = zipopen1.read(256) 129 if not read_data: 130 break 131 zipdata1.append(read_data) 132 133 zipdata2 = [] 134 with zipfp.open("another.name") as zipopen2: 135 while True: 136 read_data = zipopen2.read(256) 137 if not read_data: 138 break 139 zipdata2.append(read_data) 140 141 self.assertEqual(''.join(zipdata1), self.data) 142 self.assertEqual(''.join(zipdata2), self.data) 143 144 def test_open_stored(self): 145 for f in (TESTFN2, TemporaryFile(), StringIO()): 146 self.zip_open_test(f, zipfile.ZIP_STORED) 147 148 def test_open_via_zip_info(self): 149 # Create the ZIP archive 150 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 151 zipfp.writestr("name", "foo") 152 with check_warnings(('', UserWarning)): 153 zipfp.writestr("name", "bar") 154 self.assertEqual(zipfp.namelist(), ["name"] * 2) 155 156 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 157 infos = zipfp.infolist() 158 data = "" 159 for info in infos: 160 with zipfp.open(info) as f: 161 data += f.read() 162 self.assertTrue(data == "foobar" or data == "barfoo") 163 data = "" 164 for info in infos: 165 data += zipfp.read(info) 166 self.assertTrue(data == "foobar" or data == "barfoo") 167 168 def zip_random_open_test(self, f, compression): 169 self.make_test_archive(f, compression) 170 171 # Read the ZIP archive 172 with zipfile.ZipFile(f, "r", compression) as zipfp: 173 zipdata1 = [] 174 with zipfp.open(TESTFN) as zipopen1: 175 while True: 176 read_data = zipopen1.read(randint(1, 1024)) 177 if not read_data: 178 break 179 zipdata1.append(read_data) 180 181 self.assertEqual(''.join(zipdata1), self.data) 182 183 def test_random_open_stored(self): 184 for f in (TESTFN2, TemporaryFile(), StringIO()): 185 self.zip_random_open_test(f, zipfile.ZIP_STORED) 186 187 def test_univeral_readaheads(self): 188 f = StringIO() 189 190 data = 'a\r\n' * 16 * 1024 191 with zipfile.ZipFile(f, 'w', zipfile.ZIP_STORED) as zipfp: 192 zipfp.writestr(TESTFN, data) 193 194 data2 = '' 195 with zipfile.ZipFile(f, 'r') as zipfp: 196 with zipfp.open(TESTFN, 'rU') as zipopen: 197 for line in zipopen: 198 data2 += line 199 200 self.assertEqual(data, data2.replace('\n', '\r\n')) 201 202 def zip_readline_read_test(self, f, compression): 203 self.make_test_archive(f, compression) 204 205 # Read the ZIP archive 206 with zipfile.ZipFile(f, "r") as zipfp: 207 with zipfp.open(TESTFN) as zipopen: 208 data = '' 209 while True: 210 read = zipopen.readline() 211 if not read: 212 break 213 data += read 214 215 read = zipopen.read(100) 216 if not read: 217 break 218 data += read 219 220 self.assertEqual(data, self.data) 221 222 def zip_readline_test(self, f, compression): 223 self.make_test_archive(f, compression) 224 225 # Read the ZIP archive 226 with zipfile.ZipFile(f, "r") as zipfp: 227 with zipfp.open(TESTFN) as zipopen: 228 for line in self.line_gen: 229 linedata = zipopen.readline() 230 self.assertEqual(linedata, line + '\n') 231 232 def zip_readlines_test(self, f, compression): 233 self.make_test_archive(f, compression) 234 235 # Read the ZIP archive 236 with zipfile.ZipFile(f, "r") as zipfp: 237 with zipfp.open(TESTFN) as zo: 238 ziplines = zo.readlines() 239 for line, zipline in zip(self.line_gen, ziplines): 240 self.assertEqual(zipline, line + '\n') 241 242 def zip_iterlines_test(self, f, compression): 243 self.make_test_archive(f, compression) 244 245 # Read the ZIP archive 246 with zipfile.ZipFile(f, "r") as zipfp: 247 for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)): 248 self.assertEqual(zipline, line + '\n') 249 250 def test_readline_read_stored(self): 251 # Issue #7610: calls to readline() interleaved with calls to read(). 252 for f in (TESTFN2, TemporaryFile(), StringIO()): 253 self.zip_readline_read_test(f, zipfile.ZIP_STORED) 254 255 def test_readline_stored(self): 256 for f in (TESTFN2, TemporaryFile(), StringIO()): 257 self.zip_readline_test(f, zipfile.ZIP_STORED) 258 259 def test_readlines_stored(self): 260 for f in (TESTFN2, TemporaryFile(), StringIO()): 261 self.zip_readlines_test(f, zipfile.ZIP_STORED) 262 263 def test_iterlines_stored(self): 264 for f in (TESTFN2, TemporaryFile(), StringIO()): 265 self.zip_iterlines_test(f, zipfile.ZIP_STORED) 266 267 @skipUnless(zlib, "requires zlib") 268 def test_deflated(self): 269 for f in (TESTFN2, TemporaryFile(), StringIO()): 270 self.zip_test(f, zipfile.ZIP_DEFLATED) 271 272 @skipUnless(zlib, "requires zlib") 273 def test_open_deflated(self): 274 for f in (TESTFN2, TemporaryFile(), StringIO()): 275 self.zip_open_test(f, zipfile.ZIP_DEFLATED) 276 277 @skipUnless(zlib, "requires zlib") 278 def test_random_open_deflated(self): 279 for f in (TESTFN2, TemporaryFile(), StringIO()): 280 self.zip_random_open_test(f, zipfile.ZIP_DEFLATED) 281 282 @skipUnless(zlib, "requires zlib") 283 def test_readline_read_deflated(self): 284 # Issue #7610: calls to readline() interleaved with calls to read(). 285 for f in (TESTFN2, TemporaryFile(), StringIO()): 286 self.zip_readline_read_test(f, zipfile.ZIP_DEFLATED) 287 288 @skipUnless(zlib, "requires zlib") 289 def test_readline_deflated(self): 290 for f in (TESTFN2, TemporaryFile(), StringIO()): 291 self.zip_readline_test(f, zipfile.ZIP_DEFLATED) 292 293 @skipUnless(zlib, "requires zlib") 294 def test_readlines_deflated(self): 295 for f in (TESTFN2, TemporaryFile(), StringIO()): 296 self.zip_readlines_test(f, zipfile.ZIP_DEFLATED) 297 298 @skipUnless(zlib, "requires zlib") 299 def test_iterlines_deflated(self): 300 for f in (TESTFN2, TemporaryFile(), StringIO()): 301 self.zip_iterlines_test(f, zipfile.ZIP_DEFLATED) 302 303 @skipUnless(zlib, "requires zlib") 304 def test_low_compression(self): 305 """Check for cases where compressed data is larger than original.""" 306 # Create the ZIP archive 307 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: 308 zipfp.writestr("strfile", '12') 309 310 # Get an open object for strfile 311 with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) as zipfp: 312 with zipfp.open("strfile") as openobj: 313 self.assertEqual(openobj.read(1), '1') 314 self.assertEqual(openobj.read(1), '2') 315 316 def test_absolute_arcnames(self): 317 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 318 zipfp.write(TESTFN, "/absolute") 319 320 with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: 321 self.assertEqual(zipfp.namelist(), ["absolute"]) 322 323 def test_append_to_zip_file(self): 324 """Test appending to an existing zipfile.""" 325 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 326 zipfp.write(TESTFN, TESTFN) 327 328 with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: 329 zipfp.writestr("strfile", self.data) 330 self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) 331 332 def test_append_to_non_zip_file(self): 333 """Test appending to an existing file that is not a zipfile.""" 334 # NOTE: this test fails if len(d) < 22 because of the first 335 # line "fpin.seek(-22, 2)" in _EndRecData 336 data = 'I am not a ZipFile!'*10 337 with open(TESTFN2, 'wb') as f: 338 f.write(data) 339 340 with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: 341 zipfp.write(TESTFN, TESTFN) 342 343 with open(TESTFN2, 'rb') as f: 344 f.seek(len(data)) 345 with zipfile.ZipFile(f, "r") as zipfp: 346 self.assertEqual(zipfp.namelist(), [TESTFN]) 347 348 def test_ignores_newline_at_end(self): 349 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 350 zipfp.write(TESTFN, TESTFN) 351 with open(TESTFN2, 'a') as f: 352 f.write("\r\n\00\00\00") 353 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 354 self.assertIsInstance(zipfp, zipfile.ZipFile) 355 356 def test_ignores_stuff_appended_past_comments(self): 357 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 358 zipfp.comment = b"this is a comment" 359 zipfp.write(TESTFN, TESTFN) 360 with open(TESTFN2, 'a') as f: 361 f.write("abcdef\r\n") 362 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 363 self.assertIsInstance(zipfp, zipfile.ZipFile) 364 self.assertEqual(zipfp.comment, b"this is a comment") 365 366 def test_write_default_name(self): 367 """Check that calling ZipFile.write without arcname specified 368 produces the expected result.""" 369 with zipfile.ZipFile(TESTFN2, "w") as zipfp: 370 zipfp.write(TESTFN) 371 with open(TESTFN,'r') as fid: 372 self.assertEqual(zipfp.read(TESTFN), fid.read()) 373 374 @skipUnless(zlib, "requires zlib") 375 def test_per_file_compression(self): 376 """Check that files within a Zip archive can have different 377 compression options.""" 378 with zipfile.ZipFile(TESTFN2, "w") as zipfp: 379 zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) 380 zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) 381 sinfo = zipfp.getinfo('storeme') 382 dinfo = zipfp.getinfo('deflateme') 383 self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) 384 self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) 385 386 def test_write_to_readonly(self): 387 """Check that trying to call write() on a readonly ZipFile object 388 raises a RuntimeError.""" 389 with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: 390 zipfp.writestr("somefile.txt", "bogus") 391 392 with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: 393 self.assertRaises(RuntimeError, zipfp.write, TESTFN) 394 395 def test_extract(self): 396 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 397 for fpath, fdata in SMALL_TEST_DATA: 398 zipfp.writestr(fpath, fdata) 399 400 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 401 for fpath, fdata in SMALL_TEST_DATA: 402 writtenfile = zipfp.extract(fpath) 403 404 # make sure it was written to the right place 405 correctfile = os.path.join(os.getcwd(), fpath) 406 correctfile = os.path.normpath(correctfile) 407 408 self.assertEqual(writtenfile, correctfile) 409 410 # make sure correct data is in correct file 411 with open(writtenfile, "rb") as fid: 412 self.assertEqual(fdata, fid.read()) 413 os.remove(writtenfile) 414 415 # remove the test file subdirectories 416 rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) 417 418 def test_extract_all(self): 419 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 420 for fpath, fdata in SMALL_TEST_DATA: 421 zipfp.writestr(fpath, fdata) 422 423 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 424 zipfp.extractall() 425 for fpath, fdata in SMALL_TEST_DATA: 426 outfile = os.path.join(os.getcwd(), fpath) 427 428 with open(outfile, "rb") as fid: 429 self.assertEqual(fdata, fid.read()) 430 os.remove(outfile) 431 432 # remove the test file subdirectories 433 rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) 434 435 def check_file(self, filename, content): 436 self.assertTrue(os.path.isfile(filename)) 437 with open(filename, 'rb') as f: 438 self.assertEqual(f.read(), content) 439 440 @skipUnless(TESTFN_UNICODE, "No Unicode filesystem semantics on this platform.") 441 def test_extract_unicode_filenames(self): 442 fnames = [u'foo.txt', os.path.basename(TESTFN_UNICODE)] 443 content = 'Test for unicode filename' 444 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: 445 for fname in fnames: 446 zipfp.writestr(fname, content) 447 448 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 449 for fname in fnames: 450 writtenfile = zipfp.extract(fname) 451 452 # make sure it was written to the right place 453 correctfile = os.path.join(os.getcwd(), fname) 454 correctfile = os.path.normpath(correctfile) 455 self.assertEqual(writtenfile, correctfile) 456 457 self.check_file(writtenfile, content) 458 os.remove(writtenfile) 459 460 def test_extract_hackers_arcnames(self): 461 hacknames = [ 462 ('../foo/bar', 'foo/bar'), 463 ('foo/../bar', 'foo/bar'), 464 ('foo/../../bar', 'foo/bar'), 465 ('foo/bar/..', 'foo/bar'), 466 ('./../foo/bar', 'foo/bar'), 467 ('/foo/bar', 'foo/bar'), 468 ('/foo/../bar', 'foo/bar'), 469 ('/foo/../../bar', 'foo/bar'), 470 ] 471 if os.path.sep == '\\': 472 hacknames.extend([ 473 (r'..\foo\bar', 'foo/bar'), 474 (r'..\/foo\/bar', 'foo/bar'), 475 (r'foo/\..\/bar', 'foo/bar'), 476 (r'foo\/../\bar', 'foo/bar'), 477 (r'C:foo/bar', 'foo/bar'), 478 (r'C:/foo/bar', 'foo/bar'), 479 (r'C://foo/bar', 'foo/bar'), 480 (r'C:\foo\bar', 'foo/bar'), 481 (r'//conky/mountpoint/foo/bar', 'foo/bar'), 482 (r'\\conky\mountpoint\foo\bar', 'foo/bar'), 483 (r'///conky/mountpoint/foo/bar', 'conky/mountpoint/foo/bar'), 484 (r'\\\conky\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'), 485 (r'//conky//mountpoint/foo/bar', 'conky/mountpoint/foo/bar'), 486 (r'\\conky\\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'), 487 (r'//?/C:/foo/bar', 'foo/bar'), 488 (r'\\?\C:\foo\bar', 'foo/bar'), 489 (r'C:/../C:/foo/bar', 'C_/foo/bar'), 490 (r'a:b\c<d>e|f"g?h*i', 'b/c_d_e_f_g_h_i'), 491 ('../../foo../../ba..r', 'foo/ba..r'), 492 ]) 493 else: # Unix 494 hacknames.extend([ 495 ('//foo/bar', 'foo/bar'), 496 ('../../foo../../ba..r', 'foo../ba..r'), 497 (r'foo/..\bar', r'foo/..\bar'), 498 ]) 499 500 for arcname, fixedname in hacknames: 501 content = b'foobar' + arcname.encode() 502 with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_STORED) as zipfp: 503 zinfo = zipfile.ZipInfo() 504 # preserve backslashes 505 zinfo.filename = arcname 506 zinfo.external_attr = 0o600 << 16 507 zipfp.writestr(zinfo, content) 508 509 arcname = arcname.replace(os.sep, "/") 510 targetpath = os.path.join('target', 'subdir', 'subsub') 511 correctfile = os.path.join(targetpath, *fixedname.split('/')) 512 513 with zipfile.ZipFile(TESTFN2, 'r') as zipfp: 514 writtenfile = zipfp.extract(arcname, targetpath) 515 self.assertEqual(writtenfile, correctfile, 516 msg="extract %r" % arcname) 517 self.check_file(correctfile, content) 518 rmtree('target') 519 520 with zipfile.ZipFile(TESTFN2, 'r') as zipfp: 521 zipfp.extractall(targetpath) 522 self.check_file(correctfile, content) 523 rmtree('target') 524 525 correctfile = os.path.join(os.getcwd(), *fixedname.split('/')) 526 527 with zipfile.ZipFile(TESTFN2, 'r') as zipfp: 528 writtenfile = zipfp.extract(arcname) 529 self.assertEqual(writtenfile, correctfile, 530 msg="extract %r" % arcname) 531 self.check_file(correctfile, content) 532 rmtree(fixedname.split('/')[0]) 533 534 with zipfile.ZipFile(TESTFN2, 'r') as zipfp: 535 zipfp.extractall() 536 self.check_file(correctfile, content) 537 rmtree(fixedname.split('/')[0]) 538 539 os.remove(TESTFN2) 540 541 def test_writestr_compression(self): 542 zipfp = zipfile.ZipFile(TESTFN2, "w") 543 zipfp.writestr("a.txt", "hello world", compress_type=zipfile.ZIP_STORED) 544 if zlib: 545 zipfp.writestr("b.txt", "hello world", compress_type=zipfile.ZIP_DEFLATED) 546 547 info = zipfp.getinfo('a.txt') 548 self.assertEqual(info.compress_type, zipfile.ZIP_STORED) 549 550 if zlib: 551 info = zipfp.getinfo('b.txt') 552 self.assertEqual(info.compress_type, zipfile.ZIP_DEFLATED) 553 554 555 def zip_test_writestr_permissions(self, f, compression): 556 # Make sure that writestr creates files with mode 0600, 557 # when it is passed a name rather than a ZipInfo instance. 558 559 self.make_test_archive(f, compression) 560 with zipfile.ZipFile(f, "r") as zipfp: 561 zinfo = zipfp.getinfo('strfile') 562 self.assertEqual(zinfo.external_attr, 0600 << 16) 563 564 def test_writestr_permissions(self): 565 for f in (TESTFN2, TemporaryFile(), StringIO()): 566 self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED) 567 568 def test_close(self): 569 """Check that the zipfile is closed after the 'with' block.""" 570 with zipfile.ZipFile(TESTFN2, "w") as zipfp: 571 for fpath, fdata in SMALL_TEST_DATA: 572 zipfp.writestr(fpath, fdata) 573 self.assertTrue(zipfp.fp is not None, 'zipfp is not open') 574 self.assertTrue(zipfp.fp is None, 'zipfp is not closed') 575 576 with zipfile.ZipFile(TESTFN2, "r") as zipfp: 577 self.assertTrue(zipfp.fp is not None, 'zipfp is not open') 578 self.assertTrue(zipfp.fp is None, 'zipfp is not closed') 579 580 def test_close_on_exception(self): 581 """Check that the zipfile is closed if an exception is raised in the 582 'with' block.""" 583 with zipfile.ZipFile(TESTFN2, "w") as zipfp: 584 for fpath, fdata in SMALL_TEST_DATA: 585 zipfp.writestr(fpath, fdata) 586 587 try: 588 with zipfile.ZipFile(TESTFN2, "r") as zipfp2: 589 raise zipfile.BadZipfile() 590 except zipfile.BadZipfile: 591 self.assertTrue(zipfp2.fp is None, 'zipfp is not closed') 592 593 def test_add_file_before_1980(self): 594 # Set atime and mtime to 1970-01-01 595 os.utime(TESTFN, (0, 0)) 596 with zipfile.ZipFile(TESTFN2, "w") as zipfp: 597 self.assertRaises(ValueError, zipfp.write, TESTFN) 598 599 def tearDown(self): 600 unlink(TESTFN) 601 unlink(TESTFN2) 602 603 604class TestZip64InSmallFiles(unittest.TestCase): 605 # These tests test the ZIP64 functionality without using large files, 606 # see test_zipfile64 for proper tests. 607 608 def setUp(self): 609 self._limit = zipfile.ZIP64_LIMIT 610 self._filecount_limit = zipfile.ZIP_FILECOUNT_LIMIT 611 zipfile.ZIP64_LIMIT = 1000 612 zipfile.ZIP_FILECOUNT_LIMIT = 9 613 614 line_gen = ("Test of zipfile line %d." % i 615 for i in range(0, FIXEDTEST_SIZE)) 616 self.data = '\n'.join(line_gen) 617 618 # Make a source file with some lines 619 with open(TESTFN, "wb") as fp: 620 fp.write(self.data) 621 622 def large_file_exception_test(self, f, compression): 623 with zipfile.ZipFile(f, "w", compression) as zipfp: 624 self.assertRaises(zipfile.LargeZipFile, 625 zipfp.write, TESTFN, "another.name") 626 627 def large_file_exception_test2(self, f, compression): 628 with zipfile.ZipFile(f, "w", compression) as zipfp: 629 self.assertRaises(zipfile.LargeZipFile, 630 zipfp.writestr, "another.name", self.data) 631 632 def test_large_file_exception(self): 633 for f in (TESTFN2, TemporaryFile(), StringIO()): 634 self.large_file_exception_test(f, zipfile.ZIP_STORED) 635 self.large_file_exception_test2(f, zipfile.ZIP_STORED) 636 637 def zip_test(self, f, compression): 638 # Create the ZIP archive 639 with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp: 640 zipfp.write(TESTFN, "another.name") 641 zipfp.write(TESTFN, TESTFN) 642 zipfp.writestr("strfile", self.data) 643 644 # Read the ZIP archive 645 with zipfile.ZipFile(f, "r", compression) as zipfp: 646 self.assertEqual(zipfp.read(TESTFN), self.data) 647 self.assertEqual(zipfp.read("another.name"), self.data) 648 self.assertEqual(zipfp.read("strfile"), self.data) 649 650 # Print the ZIP directory 651 fp = StringIO() 652 stdout = sys.stdout 653 try: 654 sys.stdout = fp 655 zipfp.printdir() 656 finally: 657 sys.stdout = stdout 658 659 directory = fp.getvalue() 660 lines = directory.splitlines() 661 self.assertEqual(len(lines), 4) # Number of files + header 662 663 self.assertIn('File Name', lines[0]) 664 self.assertIn('Modified', lines[0]) 665 self.assertIn('Size', lines[0]) 666 667 fn, date, time_, size = lines[1].split() 668 self.assertEqual(fn, 'another.name') 669 self.assertTrue(time.strptime(date, '%Y-%m-%d')) 670 self.assertTrue(time.strptime(time_, '%H:%M:%S')) 671 self.assertEqual(size, str(len(self.data))) 672 673 # Check the namelist 674 names = zipfp.namelist() 675 self.assertEqual(len(names), 3) 676 self.assertIn(TESTFN, names) 677 self.assertIn("another.name", names) 678 self.assertIn("strfile", names) 679 680 # Check infolist 681 infos = zipfp.infolist() 682 names = [i.filename for i in infos] 683 self.assertEqual(len(names), 3) 684 self.assertIn(TESTFN, names) 685 self.assertIn("another.name", names) 686 self.assertIn("strfile", names) 687 for i in infos: 688 self.assertEqual(i.file_size, len(self.data)) 689 690 # check getinfo 691 for nm in (TESTFN, "another.name", "strfile"): 692 info = zipfp.getinfo(nm) 693 self.assertEqual(info.filename, nm) 694 self.assertEqual(info.file_size, len(self.data)) 695 696 # Check that testzip doesn't raise an exception 697 zipfp.testzip() 698 699 def test_stored(self): 700 for f in (TESTFN2, TemporaryFile(), StringIO()): 701 self.zip_test(f, zipfile.ZIP_STORED) 702 703 @skipUnless(zlib, "requires zlib") 704 def test_deflated(self): 705 for f in (TESTFN2, TemporaryFile(), StringIO()): 706 self.zip_test(f, zipfile.ZIP_DEFLATED) 707 708 def test_absolute_arcnames(self): 709 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, 710 allowZip64=True) as zipfp: 711 zipfp.write(TESTFN, "/absolute") 712 713 with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: 714 self.assertEqual(zipfp.namelist(), ["absolute"]) 715 716 def test_too_many_files(self): 717 # This test checks that more than 64k files can be added to an archive, 718 # and that the resulting archive can be read properly by ZipFile 719 zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) 720 zipf.debug = 100 721 numfiles = 15 722 for i in range(numfiles): 723 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) 724 self.assertEqual(len(zipf.namelist()), numfiles) 725 zipf.close() 726 727 zipf2 = zipfile.ZipFile(TESTFN, mode="r") 728 self.assertEqual(len(zipf2.namelist()), numfiles) 729 for i in range(numfiles): 730 content = zipf2.read("foo%08d" % i) 731 self.assertEqual(content, "%d" % (i**3 % 57)) 732 zipf2.close() 733 734 def test_too_many_files_append(self): 735 zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) 736 zipf.debug = 100 737 numfiles = 9 738 for i in range(numfiles): 739 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) 740 self.assertEqual(len(zipf.namelist()), numfiles) 741 with self.assertRaises(zipfile.LargeZipFile): 742 zipf.writestr("foo%08d" % numfiles, b'') 743 self.assertEqual(len(zipf.namelist()), numfiles) 744 zipf.close() 745 746 zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) 747 zipf.debug = 100 748 self.assertEqual(len(zipf.namelist()), numfiles) 749 with self.assertRaises(zipfile.LargeZipFile): 750 zipf.writestr("foo%08d" % numfiles, b'') 751 self.assertEqual(len(zipf.namelist()), numfiles) 752 zipf.close() 753 754 zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) 755 zipf.debug = 100 756 self.assertEqual(len(zipf.namelist()), numfiles) 757 numfiles2 = 15 758 for i in range(numfiles, numfiles2): 759 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) 760 self.assertEqual(len(zipf.namelist()), numfiles2) 761 zipf.close() 762 763 zipf2 = zipfile.ZipFile(TESTFN, mode="r") 764 self.assertEqual(len(zipf2.namelist()), numfiles2) 765 for i in range(numfiles2): 766 content = zipf2.read("foo%08d" % i) 767 self.assertEqual(content, "%d" % (i**3 % 57)) 768 zipf2.close() 769 770 def tearDown(self): 771 zipfile.ZIP64_LIMIT = self._limit 772 zipfile.ZIP_FILECOUNT_LIMIT = self._filecount_limit 773 unlink(TESTFN) 774 unlink(TESTFN2) 775 776 777class PyZipFileTests(unittest.TestCase): 778 def test_write_pyfile(self): 779 with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: 780 fn = __file__ 781 if fn.endswith('.pyc') or fn.endswith('.pyo'): 782 fn = fn[:-1] 783 784 zipfp.writepy(fn) 785 786 bn = os.path.basename(fn) 787 self.assertNotIn(bn, zipfp.namelist()) 788 self.assertTrue(bn + 'o' in zipfp.namelist() or 789 bn + 'c' in zipfp.namelist()) 790 791 with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: 792 fn = __file__ 793 if fn.endswith(('.pyc', '.pyo')): 794 fn = fn[:-1] 795 796 zipfp.writepy(fn, "testpackage") 797 798 bn = "%s/%s" % ("testpackage", os.path.basename(fn)) 799 self.assertNotIn(bn, zipfp.namelist()) 800 self.assertTrue(bn + 'o' in zipfp.namelist() or 801 bn + 'c' in zipfp.namelist()) 802 803 def test_write_python_package(self): 804 import email 805 packagedir = os.path.dirname(email.__file__) 806 807 with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: 808 zipfp.writepy(packagedir) 809 810 # Check for a couple of modules at different levels of the 811 # hierarchy 812 names = zipfp.namelist() 813 self.assertTrue('email/__init__.pyo' in names or 814 'email/__init__.pyc' in names) 815 self.assertTrue('email/mime/text.pyo' in names or 816 'email/mime/text.pyc' in names) 817 818 def test_write_python_directory(self): 819 os.mkdir(TESTFN2) 820 try: 821 with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: 822 fp.write("print(42)\n") 823 824 with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: 825 fp.write("print(42 * 42)\n") 826 827 with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp: 828 fp.write("bla bla bla\n") 829 830 zipfp = zipfile.PyZipFile(TemporaryFile(), "w") 831 zipfp.writepy(TESTFN2) 832 833 names = zipfp.namelist() 834 self.assertTrue('mod1.pyc' in names or 'mod1.pyo' in names) 835 self.assertTrue('mod2.pyc' in names or 'mod2.pyo' in names) 836 self.assertNotIn('mod2.txt', names) 837 838 finally: 839 rmtree(TESTFN2) 840 841 def test_write_non_pyfile(self): 842 with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: 843 with open(TESTFN, 'w') as fid: 844 fid.write('most definitely not a python file') 845 self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) 846 os.remove(TESTFN) 847 848 849class OtherTests(unittest.TestCase): 850 zips_with_bad_crc = { 851 zipfile.ZIP_STORED: ( 852 b'PK\003\004\024\0\0\0\0\0 \213\212;:r' 853 b'\253\377\f\0\0\0\f\0\0\0\005\0\0\000af' 854 b'ilehello,AworldP' 855 b'K\001\002\024\003\024\0\0\0\0\0 \213\212;:' 856 b'r\253\377\f\0\0\0\f\0\0\0\005\0\0\0\0' 857 b'\0\0\0\0\0\0\0\200\001\0\0\0\000afi' 858 b'lePK\005\006\0\0\0\0\001\0\001\0003\000' 859 b'\0\0/\0\0\0\0\0'), 860 zipfile.ZIP_DEFLATED: ( 861 b'PK\x03\x04\x14\x00\x00\x00\x08\x00n}\x0c=FA' 862 b'KE\x10\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00af' 863 b'ile\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\xc9\xa0' 864 b'=\x13\x00PK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00n' 865 b'}\x0c=FAKE\x10\x00\x00\x00n\x00\x00\x00\x05' 866 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00' 867 b'\x00afilePK\x05\x06\x00\x00\x00\x00\x01\x00' 868 b'\x01\x003\x00\x00\x003\x00\x00\x00\x00\x00'), 869 } 870 871 def test_unicode_filenames(self): 872 with zipfile.ZipFile(TESTFN, "w") as zf: 873 zf.writestr(u"foo.txt", "Test for unicode filename") 874 zf.writestr(u"\xf6.txt", "Test for unicode filename") 875 self.assertIsInstance(zf.infolist()[0].filename, unicode) 876 877 with zipfile.ZipFile(TESTFN, "r") as zf: 878 self.assertEqual(zf.filelist[0].filename, "foo.txt") 879 self.assertEqual(zf.filelist[1].filename, u"\xf6.txt") 880 881 def test_create_non_existent_file_for_append(self): 882 if os.path.exists(TESTFN): 883 os.unlink(TESTFN) 884 885 filename = 'testfile.txt' 886 content = 'hello, world. this is some content.' 887 888 try: 889 with zipfile.ZipFile(TESTFN, 'a') as zf: 890 zf.writestr(filename, content) 891 except IOError: 892 self.fail('Could not append data to a non-existent zip file.') 893 894 self.assertTrue(os.path.exists(TESTFN)) 895 896 with zipfile.ZipFile(TESTFN, 'r') as zf: 897 self.assertEqual(zf.read(filename), content) 898 899 def test_close_erroneous_file(self): 900 # This test checks that the ZipFile constructor closes the file object 901 # it opens if there's an error in the file. If it doesn't, the 902 # traceback holds a reference to the ZipFile object and, indirectly, 903 # the file object. 904 # On Windows, this causes the os.unlink() call to fail because the 905 # underlying file is still open. This is SF bug #412214. 906 # 907 with open(TESTFN, "w") as fp: 908 fp.write("this is not a legal zip file\n") 909 try: 910 zf = zipfile.ZipFile(TESTFN) 911 except zipfile.BadZipfile: 912 pass 913 914 def test_is_zip_erroneous_file(self): 915 """Check that is_zipfile() correctly identifies non-zip files.""" 916 # - passing a filename 917 with open(TESTFN, "w") as fp: 918 fp.write("this is not a legal zip file\n") 919 chk = zipfile.is_zipfile(TESTFN) 920 self.assertFalse(chk) 921 # - passing a file object 922 with open(TESTFN, "rb") as fp: 923 chk = zipfile.is_zipfile(fp) 924 self.assertTrue(not chk) 925 # - passing a file-like object 926 fp = StringIO() 927 fp.write("this is not a legal zip file\n") 928 chk = zipfile.is_zipfile(fp) 929 self.assertTrue(not chk) 930 fp.seek(0, 0) 931 chk = zipfile.is_zipfile(fp) 932 self.assertTrue(not chk) 933 934 def test_damaged_zipfile(self): 935 """Check that zipfiles with missing bytes at the end raise BadZipFile.""" 936 # - Create a valid zip file 937 fp = io.BytesIO() 938 with zipfile.ZipFile(fp, mode="w") as zipf: 939 zipf.writestr("foo.txt", b"O, for a Muse of Fire!") 940 zipfiledata = fp.getvalue() 941 942 # - Now create copies of it missing the last N bytes and make sure 943 # a BadZipFile exception is raised when we try to open it 944 for N in range(len(zipfiledata)): 945 fp = io.BytesIO(zipfiledata[:N]) 946 self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, fp) 947 948 def test_is_zip_valid_file(self): 949 """Check that is_zipfile() correctly identifies zip files.""" 950 # - passing a filename 951 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 952 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 953 chk = zipfile.is_zipfile(TESTFN) 954 self.assertTrue(chk) 955 # - passing a file object 956 with open(TESTFN, "rb") as fp: 957 chk = zipfile.is_zipfile(fp) 958 self.assertTrue(chk) 959 fp.seek(0, 0) 960 zip_contents = fp.read() 961 # - passing a file-like object 962 fp = StringIO() 963 fp.write(zip_contents) 964 chk = zipfile.is_zipfile(fp) 965 self.assertTrue(chk) 966 fp.seek(0, 0) 967 chk = zipfile.is_zipfile(fp) 968 self.assertTrue(chk) 969 970 def test_non_existent_file_raises_IOError(self): 971 # make sure we don't raise an AttributeError when a partially-constructed 972 # ZipFile instance is finalized; this tests for regression on SF tracker 973 # bug #403871. 974 975 # The bug we're testing for caused an AttributeError to be raised 976 # when a ZipFile instance was created for a file that did not 977 # exist; the .fp member was not initialized but was needed by the 978 # __del__() method. Since the AttributeError is in the __del__(), 979 # it is ignored, but the user should be sufficiently annoyed by 980 # the message on the output that regression will be noticed 981 # quickly. 982 self.assertRaises(IOError, zipfile.ZipFile, TESTFN) 983 984 def test_empty_file_raises_BadZipFile(self): 985 with open(TESTFN, 'w') as f: 986 pass 987 self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) 988 989 with open(TESTFN, 'w') as fp: 990 fp.write("short file") 991 self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) 992 993 def test_closed_zip_raises_RuntimeError(self): 994 """Verify that testzip() doesn't swallow inappropriate exceptions.""" 995 data = StringIO() 996 with zipfile.ZipFile(data, mode="w") as zipf: 997 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 998 999 # This is correct; calling .read on a closed ZipFile should raise 1000 # a RuntimeError, and so should calling .testzip. An earlier 1001 # version of .testzip would swallow this exception (and any other) 1002 # and report that the first file in the archive was corrupt. 1003 self.assertRaises(RuntimeError, zipf.read, "foo.txt") 1004 self.assertRaises(RuntimeError, zipf.open, "foo.txt") 1005 self.assertRaises(RuntimeError, zipf.testzip) 1006 self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus") 1007 with open(TESTFN, 'w') as fid: 1008 fid.write('zipfile test data') 1009 self.assertRaises(RuntimeError, zipf.write, TESTFN) 1010 1011 def test_bad_constructor_mode(self): 1012 """Check that bad modes passed to ZipFile constructor are caught.""" 1013 self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q") 1014 1015 def test_bad_open_mode(self): 1016 """Check that bad modes passed to ZipFile.open are caught.""" 1017 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1018 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1019 1020 with zipfile.ZipFile(TESTFN, mode="r") as zipf: 1021 # read the data to make sure the file is there 1022 zipf.read("foo.txt") 1023 self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") 1024 1025 def test_read0(self): 1026 """Check that calling read(0) on a ZipExtFile object returns an empty 1027 string and doesn't advance file pointer.""" 1028 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1029 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1030 # read the data to make sure the file is there 1031 with zipf.open("foo.txt") as f: 1032 for i in xrange(FIXEDTEST_SIZE): 1033 self.assertEqual(f.read(0), '') 1034 1035 self.assertEqual(f.read(), "O, for a Muse of Fire!") 1036 1037 def test_open_non_existent_item(self): 1038 """Check that attempting to call open() for an item that doesn't 1039 exist in the archive raises a RuntimeError.""" 1040 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1041 self.assertRaises(KeyError, zipf.open, "foo.txt", "r") 1042 1043 def test_bad_compression_mode(self): 1044 """Check that bad compression methods passed to ZipFile.open are 1045 caught.""" 1046 self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1) 1047 1048 def test_unsupported_compression(self): 1049 # data is declared as shrunk, but actually deflated 1050 data = (b'PK\x03\x04.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00' 1051 b'\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00x\x03\x00PK\x01' 1052 b'\x02.\x03.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00\x00\x02\x00\x00' 1053 b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 1054 b'\x80\x01\x00\x00\x00\x00xPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00' 1055 b'/\x00\x00\x00!\x00\x00\x00\x00\x00') 1056 with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf: 1057 self.assertRaises(NotImplementedError, zipf.open, 'x') 1058 1059 def test_null_byte_in_filename(self): 1060 """Check that a filename containing a null byte is properly 1061 terminated.""" 1062 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1063 zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!") 1064 self.assertEqual(zipf.namelist(), ['foo.txt']) 1065 1066 def test_struct_sizes(self): 1067 """Check that ZIP internal structure sizes are calculated correctly.""" 1068 self.assertEqual(zipfile.sizeEndCentDir, 22) 1069 self.assertEqual(zipfile.sizeCentralDir, 46) 1070 self.assertEqual(zipfile.sizeEndCentDir64, 56) 1071 self.assertEqual(zipfile.sizeEndCentDir64Locator, 20) 1072 1073 def test_comments(self): 1074 """Check that comments on the archive are handled properly.""" 1075 1076 # check default comment is empty 1077 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1078 self.assertEqual(zipf.comment, '') 1079 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1080 1081 with zipfile.ZipFile(TESTFN, mode="r") as zipf: 1082 self.assertEqual(zipf.comment, '') 1083 1084 # check a simple short comment 1085 comment = 'Bravely taking to his feet, he beat a very brave retreat.' 1086 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1087 zipf.comment = comment 1088 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1089 with zipfile.ZipFile(TESTFN, mode="r") as zipf: 1090 self.assertEqual(zipf.comment, comment) 1091 1092 # check a comment of max length 1093 comment2 = ''.join(['%d' % (i**3 % 10) for i in xrange((1 << 16)-1)]) 1094 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1095 zipf.comment = comment2 1096 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1097 1098 with zipfile.ZipFile(TESTFN, mode="r") as zipf: 1099 self.assertEqual(zipf.comment, comment2) 1100 1101 # check a comment that is too long is truncated 1102 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1103 with check_warnings(('', UserWarning)): 1104 zipf.comment = comment2 + 'oops' 1105 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1106 with zipfile.ZipFile(TESTFN, mode="r") as zipf: 1107 self.assertEqual(zipf.comment, comment2) 1108 1109 def test_change_comment_in_empty_archive(self): 1110 with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf: 1111 self.assertFalse(zipf.filelist) 1112 zipf.comment = b"this is a comment" 1113 with zipfile.ZipFile(TESTFN, "r") as zipf: 1114 self.assertEqual(zipf.comment, b"this is a comment") 1115 1116 def test_change_comment_in_nonempty_archive(self): 1117 with zipfile.ZipFile(TESTFN, "w", zipfile.ZIP_STORED) as zipf: 1118 zipf.writestr("foo.txt", "O, for a Muse of Fire!") 1119 with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf: 1120 self.assertTrue(zipf.filelist) 1121 zipf.comment = b"this is a comment" 1122 with zipfile.ZipFile(TESTFN, "r") as zipf: 1123 self.assertEqual(zipf.comment, b"this is a comment") 1124 1125 def check_testzip_with_bad_crc(self, compression): 1126 """Tests that files with bad CRCs return their name from testzip.""" 1127 zipdata = self.zips_with_bad_crc[compression] 1128 1129 with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf: 1130 # testzip returns the name of the first corrupt file, or None 1131 self.assertEqual('afile', zipf.testzip()) 1132 1133 def test_testzip_with_bad_crc_stored(self): 1134 self.check_testzip_with_bad_crc(zipfile.ZIP_STORED) 1135 1136 @skipUnless(zlib, "requires zlib") 1137 def test_testzip_with_bad_crc_deflated(self): 1138 self.check_testzip_with_bad_crc(zipfile.ZIP_DEFLATED) 1139 1140 def check_read_with_bad_crc(self, compression): 1141 """Tests that files with bad CRCs raise a BadZipfile exception when read.""" 1142 zipdata = self.zips_with_bad_crc[compression] 1143 1144 # Using ZipFile.read() 1145 with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf: 1146 self.assertRaises(zipfile.BadZipfile, zipf.read, 'afile') 1147 1148 # Using ZipExtFile.read() 1149 with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf: 1150 with zipf.open('afile', 'r') as corrupt_file: 1151 self.assertRaises(zipfile.BadZipfile, corrupt_file.read) 1152 1153 # Same with small reads (in order to exercise the buffering logic) 1154 with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf: 1155 with zipf.open('afile', 'r') as corrupt_file: 1156 corrupt_file.MIN_READ_SIZE = 2 1157 with self.assertRaises(zipfile.BadZipfile): 1158 while corrupt_file.read(2): 1159 pass 1160 1161 def test_read_with_bad_crc_stored(self): 1162 self.check_read_with_bad_crc(zipfile.ZIP_STORED) 1163 1164 @skipUnless(zlib, "requires zlib") 1165 def test_read_with_bad_crc_deflated(self): 1166 self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED) 1167 1168 def check_read_return_size(self, compression): 1169 # Issue #9837: ZipExtFile.read() shouldn't return more bytes 1170 # than requested. 1171 for test_size in (1, 4095, 4096, 4097, 16384): 1172 file_size = test_size + 1 1173 junk = getrandbytes(file_size) 1174 with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf: 1175 zipf.writestr('foo', junk) 1176 with zipf.open('foo', 'r') as fp: 1177 buf = fp.read(test_size) 1178 self.assertEqual(len(buf), test_size) 1179 1180 def test_read_return_size_stored(self): 1181 self.check_read_return_size(zipfile.ZIP_STORED) 1182 1183 @skipUnless(zlib, "requires zlib") 1184 def test_read_return_size_deflated(self): 1185 self.check_read_return_size(zipfile.ZIP_DEFLATED) 1186 1187 def test_empty_zipfile(self): 1188 # Check that creating a file in 'w' or 'a' mode and closing without 1189 # adding any files to the archives creates a valid empty ZIP file 1190 with zipfile.ZipFile(TESTFN, mode="w") as zipf: 1191 pass 1192 try: 1193 zipf = zipfile.ZipFile(TESTFN, mode="r") 1194 zipf.close() 1195 except zipfile.BadZipfile: 1196 self.fail("Unable to create empty ZIP file in 'w' mode") 1197 1198 with zipfile.ZipFile(TESTFN, mode="a") as zipf: 1199 pass 1200 try: 1201 zipf = zipfile.ZipFile(TESTFN, mode="r") 1202 zipf.close() 1203 except: 1204 self.fail("Unable to create empty ZIP file in 'a' mode") 1205 1206 def test_open_empty_file(self): 1207 # Issue 1710703: Check that opening a file with less than 22 bytes 1208 # raises a BadZipfile exception (rather than the previously unhelpful 1209 # IOError) 1210 with open(TESTFN, 'w') as f: 1211 pass 1212 self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN, 'r') 1213 1214 def test_create_zipinfo_before_1980(self): 1215 self.assertRaises(ValueError, 1216 zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0)) 1217 1218 def test_zipfile_with_short_extra_field(self): 1219 """If an extra field in the header is less than 4 bytes, skip it.""" 1220 zipdata = ( 1221 b'PK\x03\x04\x14\x00\x00\x00\x00\x00\x93\x9b\xad@\x8b\x9e' 1222 b'\xd9\xd3\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x03\x00ab' 1223 b'c\x00\x00\x00APK\x01\x02\x14\x03\x14\x00\x00\x00\x00' 1224 b'\x00\x93\x9b\xad@\x8b\x9e\xd9\xd3\x01\x00\x00\x00\x01\x00\x00' 1225 b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00' 1226 b'\x00\x00\x00abc\x00\x00PK\x05\x06\x00\x00\x00\x00' 1227 b'\x01\x00\x01\x003\x00\x00\x00%\x00\x00\x00\x00\x00' 1228 ) 1229 with zipfile.ZipFile(io.BytesIO(zipdata), 'r') as zipf: 1230 # testzip returns the name of the first corrupt file, or None 1231 self.assertIsNone(zipf.testzip()) 1232 1233 def tearDown(self): 1234 unlink(TESTFN) 1235 unlink(TESTFN2) 1236 1237 1238class DecryptionTests(unittest.TestCase): 1239 """Check that ZIP decryption works. Since the library does not 1240 support encryption at the moment, we use a pre-generated encrypted 1241 ZIP file.""" 1242 1243 data = ( 1244 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00' 1245 '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y' 1246 '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl' 1247 'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00' 1248 '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81' 1249 '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00' 1250 '\x00\x00L\x00\x00\x00\x00\x00' ) 1251 data2 = ( 1252 'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02' 1253 '\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04' 1254 '\x00\xe8\x03\xe8\x03\xc7<M\xb5a\xceX\xa3Y&\x8b{oE\xd7\x9d\x8c\x98\x02\xc0' 1255 'PK\x07\x08xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00PK\x01\x02\x17\x03' 1256 '\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00' 1257 '\x04\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00ze' 1258 'roUT\x05\x00\x03\xd6\x8b\x92GUx\x00\x00PK\x05\x06\x00\x00\x00\x00\x01' 1259 '\x00\x01\x00?\x00\x00\x00[\x00\x00\x00\x00\x00' ) 1260 1261 plain = 'zipfile.py encryption test' 1262 plain2 = '\x00'*512 1263 1264 def setUp(self): 1265 with open(TESTFN, "wb") as fp: 1266 fp.write(self.data) 1267 self.zip = zipfile.ZipFile(TESTFN, "r") 1268 with open(TESTFN2, "wb") as fp: 1269 fp.write(self.data2) 1270 self.zip2 = zipfile.ZipFile(TESTFN2, "r") 1271 1272 def tearDown(self): 1273 self.zip.close() 1274 os.unlink(TESTFN) 1275 self.zip2.close() 1276 os.unlink(TESTFN2) 1277 1278 def test_no_password(self): 1279 # Reading the encrypted file without password 1280 # must generate a RunTime exception 1281 self.assertRaises(RuntimeError, self.zip.read, "test.txt") 1282 self.assertRaises(RuntimeError, self.zip2.read, "zero") 1283 1284 def test_bad_password(self): 1285 self.zip.setpassword("perl") 1286 self.assertRaises(RuntimeError, self.zip.read, "test.txt") 1287 self.zip2.setpassword("perl") 1288 self.assertRaises(RuntimeError, self.zip2.read, "zero") 1289 1290 @skipUnless(zlib, "requires zlib") 1291 def test_good_password(self): 1292 self.zip.setpassword("python") 1293 self.assertEqual(self.zip.read("test.txt"), self.plain) 1294 self.zip2.setpassword("12345") 1295 self.assertEqual(self.zip2.read("zero"), self.plain2) 1296 1297 1298class TestsWithRandomBinaryFiles(unittest.TestCase): 1299 def setUp(self): 1300 datacount = randint(16, 64)*1024 + randint(1, 1024) 1301 self.data = ''.join(struct.pack('<f', random()*randint(-1000, 1000)) 1302 for i in xrange(datacount)) 1303 1304 # Make a source file with some lines 1305 with open(TESTFN, "wb") as fp: 1306 fp.write(self.data) 1307 1308 def tearDown(self): 1309 unlink(TESTFN) 1310 unlink(TESTFN2) 1311 1312 def make_test_archive(self, f, compression): 1313 # Create the ZIP archive 1314 with zipfile.ZipFile(f, "w", compression) as zipfp: 1315 zipfp.write(TESTFN, "another.name") 1316 zipfp.write(TESTFN, TESTFN) 1317 1318 def zip_test(self, f, compression): 1319 self.make_test_archive(f, compression) 1320 1321 # Read the ZIP archive 1322 with zipfile.ZipFile(f, "r", compression) as zipfp: 1323 testdata = zipfp.read(TESTFN) 1324 self.assertEqual(len(testdata), len(self.data)) 1325 self.assertEqual(testdata, self.data) 1326 self.assertEqual(zipfp.read("another.name"), self.data) 1327 1328 def test_stored(self): 1329 for f in (TESTFN2, TemporaryFile(), StringIO()): 1330 self.zip_test(f, zipfile.ZIP_STORED) 1331 1332 @skipUnless(zlib, "requires zlib") 1333 def test_deflated(self): 1334 for f in (TESTFN2, TemporaryFile(), io.BytesIO()): 1335 self.zip_test(f, zipfile.ZIP_DEFLATED) 1336 1337 def zip_open_test(self, f, compression): 1338 self.make_test_archive(f, compression) 1339 1340 # Read the ZIP archive 1341 with zipfile.ZipFile(f, "r", compression) as zipfp: 1342 zipdata1 = [] 1343 with zipfp.open(TESTFN) as zipopen1: 1344 while True: 1345 read_data = zipopen1.read(256) 1346 if not read_data: 1347 break 1348 zipdata1.append(read_data) 1349 1350 zipdata2 = [] 1351 with zipfp.open("another.name") as zipopen2: 1352 while True: 1353 read_data = zipopen2.read(256) 1354 if not read_data: 1355 break 1356 zipdata2.append(read_data) 1357 1358 testdata1 = ''.join(zipdata1) 1359 self.assertEqual(len(testdata1), len(self.data)) 1360 self.assertEqual(testdata1, self.data) 1361 1362 testdata2 = ''.join(zipdata2) 1363 self.assertEqual(len(testdata2), len(self.data)) 1364 self.assertEqual(testdata2, self.data) 1365 1366 def test_open_stored(self): 1367 for f in (TESTFN2, TemporaryFile(), StringIO()): 1368 self.zip_open_test(f, zipfile.ZIP_STORED) 1369 1370 @skipUnless(zlib, "requires zlib") 1371 def test_open_deflated(self): 1372 for f in (TESTFN2, TemporaryFile(), io.BytesIO()): 1373 self.zip_open_test(f, zipfile.ZIP_DEFLATED) 1374 1375 def zip_random_open_test(self, f, compression): 1376 self.make_test_archive(f, compression) 1377 1378 # Read the ZIP archive 1379 with zipfile.ZipFile(f, "r", compression) as zipfp: 1380 zipdata1 = [] 1381 with zipfp.open(TESTFN) as zipopen1: 1382 while True: 1383 read_data = zipopen1.read(randint(1, 1024)) 1384 if not read_data: 1385 break 1386 zipdata1.append(read_data) 1387 1388 testdata = ''.join(zipdata1) 1389 self.assertEqual(len(testdata), len(self.data)) 1390 self.assertEqual(testdata, self.data) 1391 1392 def test_random_open_stored(self): 1393 for f in (TESTFN2, TemporaryFile(), StringIO()): 1394 self.zip_random_open_test(f, zipfile.ZIP_STORED) 1395 1396 @skipUnless(zlib, "requires zlib") 1397 def test_random_open_deflated(self): 1398 for f in (TESTFN2, TemporaryFile(), io.BytesIO()): 1399 self.zip_random_open_test(f, zipfile.ZIP_DEFLATED) 1400 1401 1402@skipUnless(zlib, "requires zlib") 1403class TestsWithMultipleOpens(unittest.TestCase): 1404 @classmethod 1405 def setUpClass(cls): 1406 cls.data1 = b'111' + getrandbytes(10000) 1407 cls.data2 = b'222' + getrandbytes(10000) 1408 1409 def make_test_archive(self, f): 1410 # Create the ZIP archive 1411 with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipfp: 1412 zipfp.writestr('ones', self.data1) 1413 zipfp.writestr('twos', self.data2) 1414 1415 def test_same_file(self): 1416 # Verify that (when the ZipFile is in control of creating file objects) 1417 # multiple open() calls can be made without interfering with each other. 1418 self.make_test_archive(TESTFN2) 1419 with zipfile.ZipFile(TESTFN2, mode="r") as zipf: 1420 with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2: 1421 data1 = zopen1.read(500) 1422 data2 = zopen2.read(500) 1423 data1 += zopen1.read() 1424 data2 += zopen2.read() 1425 self.assertEqual(data1, data2) 1426 self.assertEqual(data1, self.data1) 1427 1428 def test_different_file(self): 1429 # Verify that (when the ZipFile is in control of creating file objects) 1430 # multiple open() calls can be made without interfering with each other. 1431 self.make_test_archive(TESTFN2) 1432 with zipfile.ZipFile(TESTFN2, mode="r") as zipf: 1433 with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: 1434 data1 = zopen1.read(500) 1435 data2 = zopen2.read(500) 1436 data1 += zopen1.read() 1437 data2 += zopen2.read() 1438 self.assertEqual(data1, self.data1) 1439 self.assertEqual(data2, self.data2) 1440 1441 def test_interleaved(self): 1442 # Verify that (when the ZipFile is in control of creating file objects) 1443 # multiple open() calls can be made without interfering with each other. 1444 self.make_test_archive(TESTFN2) 1445 with zipfile.ZipFile(TESTFN2, mode="r") as zipf: 1446 with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: 1447 data1 = zopen1.read(500) 1448 data2 = zopen2.read(500) 1449 data1 += zopen1.read() 1450 data2 += zopen2.read() 1451 self.assertEqual(data1, self.data1) 1452 self.assertEqual(data2, self.data2) 1453 1454 def test_read_after_close(self): 1455 self.make_test_archive(TESTFN2) 1456 zopen1 = zopen2 = None 1457 try: 1458 with zipfile.ZipFile(TESTFN2, 'r') as zipf: 1459 zopen1 = zipf.open('ones') 1460 zopen2 = zipf.open('twos') 1461 data1 = zopen1.read(500) 1462 data2 = zopen2.read(500) 1463 data1 += zopen1.read() 1464 data2 += zopen2.read() 1465 finally: 1466 if zopen1: 1467 zopen1.close() 1468 if zopen2: 1469 zopen2.close() 1470 self.assertEqual(data1, self.data1) 1471 self.assertEqual(data2, self.data2) 1472 1473 def test_read_after_write(self): 1474 with zipfile.ZipFile(TESTFN2, 'w', zipfile.ZIP_DEFLATED) as zipf: 1475 zipf.writestr('ones', self.data1) 1476 zipf.writestr('twos', self.data2) 1477 with zipf.open('ones') as zopen1: 1478 data1 = zopen1.read(500) 1479 self.assertEqual(data1, self.data1[:500]) 1480 with zipfile.ZipFile(TESTFN2, 'r') as zipf: 1481 data1 = zipf.read('ones') 1482 data2 = zipf.read('twos') 1483 self.assertEqual(data1, self.data1) 1484 self.assertEqual(data2, self.data2) 1485 1486 def test_write_after_read(self): 1487 with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipf: 1488 zipf.writestr('ones', self.data1) 1489 with zipf.open('ones') as zopen1: 1490 zopen1.read(500) 1491 zipf.writestr('twos', self.data2) 1492 with zipfile.ZipFile(TESTFN2, 'r') as zipf: 1493 data1 = zipf.read('ones') 1494 data2 = zipf.read('twos') 1495 self.assertEqual(data1, self.data1) 1496 self.assertEqual(data2, self.data2) 1497 1498 def test_many_opens(self): 1499 # Verify that read() and open() promptly close the file descriptor, 1500 # and don't rely on the garbage collector to free resources. 1501 self.make_test_archive(TESTFN2) 1502 with zipfile.ZipFile(TESTFN2, mode="r") as zipf: 1503 for x in range(100): 1504 zipf.read('ones') 1505 with zipf.open('ones') as zopen1: 1506 pass 1507 with open(os.devnull) as f: 1508 self.assertLess(f.fileno(), 100) 1509 1510 def tearDown(self): 1511 unlink(TESTFN2) 1512 1513 1514class TestWithDirectory(unittest.TestCase): 1515 def setUp(self): 1516 os.mkdir(TESTFN2) 1517 1518 def test_extract_dir(self): 1519 with zipfile.ZipFile(findfile("zipdir.zip")) as zipf: 1520 zipf.extractall(TESTFN2) 1521 self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a"))) 1522 self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b"))) 1523 self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c"))) 1524 1525 def test_bug_6050(self): 1526 # Extraction should succeed if directories already exist 1527 os.mkdir(os.path.join(TESTFN2, "a")) 1528 self.test_extract_dir() 1529 1530 def test_write_dir(self): 1531 dirpath = os.path.join(TESTFN2, "x") 1532 os.mkdir(dirpath) 1533 mode = os.stat(dirpath).st_mode & 0xFFFF 1534 with zipfile.ZipFile(TESTFN, "w") as zipf: 1535 zipf.write(dirpath) 1536 zinfo = zipf.filelist[0] 1537 self.assertTrue(zinfo.filename.endswith("/x/")) 1538 self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) 1539 zipf.write(dirpath, "y") 1540 zinfo = zipf.filelist[1] 1541 self.assertTrue(zinfo.filename, "y/") 1542 self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) 1543 with zipfile.ZipFile(TESTFN, "r") as zipf: 1544 zinfo = zipf.filelist[0] 1545 self.assertTrue(zinfo.filename.endswith("/x/")) 1546 self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) 1547 zinfo = zipf.filelist[1] 1548 self.assertTrue(zinfo.filename, "y/") 1549 self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) 1550 target = os.path.join(TESTFN2, "target") 1551 os.mkdir(target) 1552 zipf.extractall(target) 1553 self.assertTrue(os.path.isdir(os.path.join(target, "y"))) 1554 self.assertEqual(len(os.listdir(target)), 2) 1555 1556 def test_writestr_dir(self): 1557 os.mkdir(os.path.join(TESTFN2, "x")) 1558 with zipfile.ZipFile(TESTFN, "w") as zipf: 1559 zipf.writestr("x/", b'') 1560 zinfo = zipf.filelist[0] 1561 self.assertEqual(zinfo.filename, "x/") 1562 self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) 1563 with zipfile.ZipFile(TESTFN, "r") as zipf: 1564 zinfo = zipf.filelist[0] 1565 self.assertTrue(zinfo.filename.endswith("x/")) 1566 self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) 1567 target = os.path.join(TESTFN2, "target") 1568 os.mkdir(target) 1569 zipf.extractall(target) 1570 self.assertTrue(os.path.isdir(os.path.join(target, "x"))) 1571 self.assertEqual(os.listdir(target), ["x"]) 1572 1573 def tearDown(self): 1574 rmtree(TESTFN2) 1575 if os.path.exists(TESTFN): 1576 unlink(TESTFN) 1577 1578 1579class UniversalNewlineTests(unittest.TestCase): 1580 def setUp(self): 1581 self.line_gen = ["Test of zipfile line %d." % i 1582 for i in xrange(FIXEDTEST_SIZE)] 1583 self.seps = ('\r', '\r\n', '\n') 1584 self.arcdata, self.arcfiles = {}, {} 1585 for n, s in enumerate(self.seps): 1586 self.arcdata[s] = s.join(self.line_gen) + s 1587 self.arcfiles[s] = '%s-%d' % (TESTFN, n) 1588 with open(self.arcfiles[s], "wb") as fid: 1589 fid.write(self.arcdata[s]) 1590 1591 def make_test_archive(self, f, compression): 1592 # Create the ZIP archive 1593 with zipfile.ZipFile(f, "w", compression) as zipfp: 1594 for fn in self.arcfiles.values(): 1595 zipfp.write(fn, fn) 1596 1597 def read_test(self, f, compression): 1598 self.make_test_archive(f, compression) 1599 1600 # Read the ZIP archive 1601 with zipfile.ZipFile(f, "r") as zipfp: 1602 for sep, fn in self.arcfiles.items(): 1603 with zipfp.open(fn, "rU") as fp: 1604 zipdata = fp.read() 1605 self.assertEqual(self.arcdata[sep], zipdata) 1606 1607 def readline_read_test(self, f, compression): 1608 self.make_test_archive(f, compression) 1609 1610 # Read the ZIP archive 1611 zipfp = zipfile.ZipFile(f, "r") 1612 for sep, fn in self.arcfiles.items(): 1613 with zipfp.open(fn, "rU") as zipopen: 1614 data = '' 1615 while True: 1616 read = zipopen.readline() 1617 if not read: 1618 break 1619 data += read 1620 1621 read = zipopen.read(5) 1622 if not read: 1623 break 1624 data += read 1625 1626 self.assertEqual(data, self.arcdata['\n']) 1627 1628 zipfp.close() 1629 1630 def readline_test(self, f, compression): 1631 self.make_test_archive(f, compression) 1632 1633 # Read the ZIP archive 1634 with zipfile.ZipFile(f, "r") as zipfp: 1635 for sep, fn in self.arcfiles.items(): 1636 with zipfp.open(fn, "rU") as zipopen: 1637 for line in self.line_gen: 1638 linedata = zipopen.readline() 1639 self.assertEqual(linedata, line + '\n') 1640 1641 def readlines_test(self, f, compression): 1642 self.make_test_archive(f, compression) 1643 1644 # Read the ZIP archive 1645 with zipfile.ZipFile(f, "r") as zipfp: 1646 for sep, fn in self.arcfiles.items(): 1647 with zipfp.open(fn, "rU") as fp: 1648 ziplines = fp.readlines() 1649 for line, zipline in zip(self.line_gen, ziplines): 1650 self.assertEqual(zipline, line + '\n') 1651 1652 def iterlines_test(self, f, compression): 1653 self.make_test_archive(f, compression) 1654 1655 # Read the ZIP archive 1656 with zipfile.ZipFile(f, "r") as zipfp: 1657 for sep, fn in self.arcfiles.items(): 1658 with zipfp.open(fn, "rU") as fid: 1659 for line, zipline in zip(self.line_gen, fid): 1660 self.assertEqual(zipline, line + '\n') 1661 1662 def test_read_stored(self): 1663 for f in (TESTFN2, TemporaryFile(), StringIO()): 1664 self.read_test(f, zipfile.ZIP_STORED) 1665 1666 def test_readline_read_stored(self): 1667 # Issue #7610: calls to readline() interleaved with calls to read(). 1668 for f in (TESTFN2, TemporaryFile(), StringIO()): 1669 self.readline_read_test(f, zipfile.ZIP_STORED) 1670 1671 def test_readline_stored(self): 1672 for f in (TESTFN2, TemporaryFile(), StringIO()): 1673 self.readline_test(f, zipfile.ZIP_STORED) 1674 1675 def test_readlines_stored(self): 1676 for f in (TESTFN2, TemporaryFile(), StringIO()): 1677 self.readlines_test(f, zipfile.ZIP_STORED) 1678 1679 def test_iterlines_stored(self): 1680 for f in (TESTFN2, TemporaryFile(), StringIO()): 1681 self.iterlines_test(f, zipfile.ZIP_STORED) 1682 1683 @skipUnless(zlib, "requires zlib") 1684 def test_read_deflated(self): 1685 for f in (TESTFN2, TemporaryFile(), StringIO()): 1686 self.read_test(f, zipfile.ZIP_DEFLATED) 1687 1688 @skipUnless(zlib, "requires zlib") 1689 def test_readline_read_deflated(self): 1690 # Issue #7610: calls to readline() interleaved with calls to read(). 1691 for f in (TESTFN2, TemporaryFile(), StringIO()): 1692 self.readline_read_test(f, zipfile.ZIP_DEFLATED) 1693 1694 @skipUnless(zlib, "requires zlib") 1695 def test_readline_deflated(self): 1696 for f in (TESTFN2, TemporaryFile(), StringIO()): 1697 self.readline_test(f, zipfile.ZIP_DEFLATED) 1698 1699 @skipUnless(zlib, "requires zlib") 1700 def test_readlines_deflated(self): 1701 for f in (TESTFN2, TemporaryFile(), StringIO()): 1702 self.readlines_test(f, zipfile.ZIP_DEFLATED) 1703 1704 @skipUnless(zlib, "requires zlib") 1705 def test_iterlines_deflated(self): 1706 for f in (TESTFN2, TemporaryFile(), StringIO()): 1707 self.iterlines_test(f, zipfile.ZIP_DEFLATED) 1708 1709 def tearDown(self): 1710 for sep, fn in self.arcfiles.items(): 1711 os.remove(fn) 1712 unlink(TESTFN) 1713 unlink(TESTFN2) 1714 1715 1716def test_main(): 1717 run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests, 1718 PyZipFileTests, DecryptionTests, TestsWithMultipleOpens, 1719 TestWithDirectory, UniversalNewlineTests, 1720 TestsWithRandomBinaryFiles) 1721 1722if __name__ == "__main__": 1723 test_main() 1724