test_zipfile.py revision 0be506a5baf8b86c519e6074af43a0f91af603c6
1022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson# We can test part of the module without zlib.
2022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssontry:
3022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson    import zlib
4022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonexcept ImportError:
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner    zlib = None
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner
7022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport os
8022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport io
9022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport sys
10022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport time
11022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport shutil
12022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport struct
13022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport zipfile
14022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonimport unittest
15022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson
16ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonfrom StringIO import StringIO
17bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattnerfrom tempfile import TemporaryFile
18c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbarfrom random import randint, random
19564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlssonfrom unittest import skipUnless
20793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson
21022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonfrom test.test_support import TESTFN, run_unittest, findfile, unlink
22022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson
23ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders CarlssonTESTFN2 = TESTFN + "2"
24ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders CarlssonTESTFNDIR = TESTFN + "d"
251ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P WangFIXEDTEST_SIZE = 1000
261ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
271ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P WangSMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'),
281ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang                   ('ziptest2dir/_ziptest2', 'qawsedrftg'),
29c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang                   ('/ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'),
30c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang                   ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')]
31c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang
32c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang
331ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wangclass TestsWithSourceFile(unittest.TestCase):
341ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    def setUp(self):
351ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        self.line_gen = ["Zipfile test line %d. random float: %f" % (i, random())
361ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang                         for i in xrange(FIXEDTEST_SIZE)]
371ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        self.data = '\n'.join(self.line_gen) + '\n'
386de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
396de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner        # Make a source file with some lines
40b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with open(TESTFN, "wb") as fp:
41ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson            fp.write(self.data)
426de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
436de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    def make_test_archive(self, f, compression):
446de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner        # Create the ZIP archive
45d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson        with zipfile.ZipFile(f, "w", compression) as zipfp:
46d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson            zipfp.write(TESTFN, "another.name")
47d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson            zipfp.write(TESTFN, TESTFN)
48d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson            zipfp.writestr("strfile", self.data)
49d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson
50d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson    def zip_test(self, f, compression):
51d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson        self.make_test_archive(f, compression)
52d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson
536de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner        # Read the ZIP archive
546de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner        with zipfile.ZipFile(f, "r", compression) as zipfp:
556de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner            self.assertEqual(zipfp.read(TESTFN), self.data)
566de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner            self.assertEqual(zipfp.read("another.name"), self.data)
576de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner            self.assertEqual(zipfp.read("strfile"), self.data)
58793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson
596a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner            # Print the ZIP directory
60793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson            fp = StringIO()
61793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson            stdout = sys.stdout
621feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            try:
63ddc23f3e6fdc4f83dd46ef7e20394cfbd6063ff9Christopher Lamb                sys.stdout = fp
64ddc23f3e6fdc4f83dd46ef7e20394cfbd6063ff9Christopher Lamb                zipfp.printdir()
65793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson            finally:
66793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson                sys.stdout = stdout
67793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson
68793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson            directory = fp.getvalue()
696a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner            lines = directory.splitlines()
706a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner            self.assertEqual(len(lines), 4) # Number of files + header
717acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner
72793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson            self.assertIn('File Name', lines[0])
73a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertIn('Modified', lines[0])
74a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertIn('Size', lines[0])
75a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
76a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            fn, date, time_, size = lines[1].split()
77a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertEqual(fn, 'another.name')
78a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertTrue(time.strptime(date, '%Y-%m-%d'))
79a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertTrue(time.strptime(time_, '%H:%M:%S'))
80a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertEqual(size, str(len(self.data)))
81a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
82a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            # Check the namelist
83a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            names = zipfp.namelist()
84a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertEqual(len(names), 3)
85a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertIn(TESTFN, names)
86a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            self.assertIn("another.name", names)
873eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner            self.assertIn("strfile", names)
883eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner
89a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson            # Check infolist
9089799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson            infos = zipfp.infolist()
911feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            names = [i.filename for i in infos]
9289799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson            self.assertEqual(len(names), 3)
9389799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson            self.assertIn(TESTFN, names)
941feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            self.assertIn("another.name", names)
9589799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson            self.assertIn("strfile", names)
96d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson            for i in infos:
971feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                self.assertEqual(i.file_size, len(self.data))
98d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson
99d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson            # check getinfo
1001feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            for nm in (TESTFN, "another.name", "strfile"):
101d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson                info = zipfp.getinfo(nm)
102c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson                self.assertEqual(info.filename, nm)
1031feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                self.assertEqual(info.file_size, len(self.data))
104c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
1059a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner            # Check that testzip doesn't raise an exception
1061feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            zipfp.testzip()
1079a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner
1089a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner    def test_stored(self):
1091feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
110c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson            self.zip_test(f, zipfile.ZIP_STORED)
111c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
112c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson    def zip_open_test(self, f, compression):
113c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson        self.make_test_archive(f, compression)
1143a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1153a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson        # Read the ZIP archive
1163a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson        with zipfile.ZipFile(f, "r", compression) as zipfp:
1173a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson            zipdata1 = []
1183a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson            with zipfp.open(TESTFN) as zipopen1:
1193a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                while True:
1203a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                    read_data = zipopen1.read(256)
1213a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                    if not read_data:
1223a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                        break
1233a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                    zipdata1.append(read_data)
1243a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1253a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson            zipdata2 = []
1263a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson            with zipfp.open("another.name") as zipopen2:
1273a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson                while True:
128f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman                    read_data = zipopen2.read(256)
129f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman                    if not read_data:
130f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman                        break
131f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman                    zipdata2.append(read_data)
132f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman
133f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman            self.assertEqual(''.join(zipdata1), self.data)
134f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman            self.assertEqual(''.join(zipdata2), self.data)
135f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman
136f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    def test_open_stored(self):
137f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman        for f in (TESTFN2, TemporaryFile(), StringIO()):
138f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman            self.zip_open_test(f, zipfile.ZIP_STORED)
139f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman
140f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    def test_open_via_zip_info(self):
141f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman        # Create the ZIP archive
14204b290030eee33295600728450f348989d1a627eDaniel Dunbar        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
14304b290030eee33295600728450f348989d1a627eDaniel Dunbar            zipfp.writestr("name", "foo")
14404b290030eee33295600728450f348989d1a627eDaniel Dunbar            zipfp.writestr("name", "bar")
14504b290030eee33295600728450f348989d1a627eDaniel Dunbar
14604b290030eee33295600728450f348989d1a627eDaniel Dunbar        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
14704b290030eee33295600728450f348989d1a627eDaniel Dunbar            infos = zipfp.infolist()
14804b290030eee33295600728450f348989d1a627eDaniel Dunbar            data = ""
14904b290030eee33295600728450f348989d1a627eDaniel Dunbar            for info in infos:
15004b290030eee33295600728450f348989d1a627eDaniel Dunbar                with zipfp.open(info) as f:
15104b290030eee33295600728450f348989d1a627eDaniel Dunbar                    data += f.read()
15204b290030eee33295600728450f348989d1a627eDaniel Dunbar            self.assertTrue(data == "foobar" or data == "barfoo")
15304b290030eee33295600728450f348989d1a627eDaniel Dunbar            data = ""
15404b290030eee33295600728450f348989d1a627eDaniel Dunbar            for info in infos:
15504b290030eee33295600728450f348989d1a627eDaniel Dunbar                data += zipfp.read(info)
15604b290030eee33295600728450f348989d1a627eDaniel Dunbar            self.assertTrue(data == "foobar" or data == "barfoo")
15704b290030eee33295600728450f348989d1a627eDaniel Dunbar
15804b290030eee33295600728450f348989d1a627eDaniel Dunbar    def zip_random_open_test(self, f, compression):
15904b290030eee33295600728450f348989d1a627eDaniel Dunbar        self.make_test_archive(f, compression)
16004b290030eee33295600728450f348989d1a627eDaniel Dunbar
16104b290030eee33295600728450f348989d1a627eDaniel Dunbar        # Read the ZIP archive
16204b290030eee33295600728450f348989d1a627eDaniel Dunbar        with zipfile.ZipFile(f, "r", compression) as zipfp:
16304b290030eee33295600728450f348989d1a627eDaniel Dunbar            zipdata1 = []
16404b290030eee33295600728450f348989d1a627eDaniel Dunbar            with zipfp.open(TESTFN) as zipopen1:
16504b290030eee33295600728450f348989d1a627eDaniel Dunbar                while True:
16604b290030eee33295600728450f348989d1a627eDaniel Dunbar                    read_data = zipopen1.read(randint(1, 1024))
16704b290030eee33295600728450f348989d1a627eDaniel Dunbar                    if not read_data:
16804b290030eee33295600728450f348989d1a627eDaniel Dunbar                        break
16904b290030eee33295600728450f348989d1a627eDaniel Dunbar                    zipdata1.append(read_data)
17004b290030eee33295600728450f348989d1a627eDaniel Dunbar
17104b290030eee33295600728450f348989d1a627eDaniel Dunbar            self.assertEqual(''.join(zipdata1), self.data)
17204b290030eee33295600728450f348989d1a627eDaniel Dunbar
17304b290030eee33295600728450f348989d1a627eDaniel Dunbar    def test_random_open_stored(self):
17404b290030eee33295600728450f348989d1a627eDaniel Dunbar        for f in (TESTFN2, TemporaryFile(), StringIO()):
17504b290030eee33295600728450f348989d1a627eDaniel Dunbar            self.zip_random_open_test(f, zipfile.ZIP_STORED)
17604b290030eee33295600728450f348989d1a627eDaniel Dunbar
17704b290030eee33295600728450f348989d1a627eDaniel Dunbar    def test_univeral_readaheads(self):
17804b290030eee33295600728450f348989d1a627eDaniel Dunbar        f = StringIO()
17904b290030eee33295600728450f348989d1a627eDaniel Dunbar
18004b290030eee33295600728450f348989d1a627eDaniel Dunbar        data = 'a\r\n' * 16 * 1024
18104b290030eee33295600728450f348989d1a627eDaniel Dunbar        with zipfile.ZipFile(f, 'w', zipfile.ZIP_STORED) as zipfp:
18204b290030eee33295600728450f348989d1a627eDaniel Dunbar            zipfp.writestr(TESTFN, data)
18304b290030eee33295600728450f348989d1a627eDaniel Dunbar
18404b290030eee33295600728450f348989d1a627eDaniel Dunbar        data2 = ''
18504b290030eee33295600728450f348989d1a627eDaniel Dunbar        with zipfile.ZipFile(f, 'r') as zipfp:
18604b290030eee33295600728450f348989d1a627eDaniel Dunbar            with zipfp.open(TESTFN, 'rU') as zipopen:
18704b290030eee33295600728450f348989d1a627eDaniel Dunbar                for line in zipopen:
18804b290030eee33295600728450f348989d1a627eDaniel Dunbar                    data2 += line
18904b290030eee33295600728450f348989d1a627eDaniel Dunbar
19004b290030eee33295600728450f348989d1a627eDaniel Dunbar        self.assertEqual(data, data2.replace('\n', '\r\n'))
19104b290030eee33295600728450f348989d1a627eDaniel Dunbar
1921feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    def zip_readline_read_test(self, f, compression):
193a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar        self.make_test_archive(f, compression)
1941feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner
195df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson        # Read the ZIP archive
196df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson        with zipfile.ZipFile(f, "r") as zipfp:
1971feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            with zipfp.open(TESTFN) as zipopen:
198df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson                data = ''
1997acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner                while True:
2001feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                    read = zipopen.readline()
2014493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                    if not read:
2024493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                        break
2034493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                    data += read
2044493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar
2054493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                    read = zipopen.read(100)
2064493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                    if not read:
2074493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                        break
2084493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar                    data += read
2094493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar
2104493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar        self.assertEqual(data, self.data)
2114493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar
2124493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    def zip_readline_test(self, f, compression):
2134493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar        self.make_test_archive(f, compression)
2144493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar
215df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson        # Read the ZIP archive
2164493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar        with zipfile.ZipFile(f, "r") as zipfp:
217478547cd2163d86ed9d691aa8fe45949eebf6cbfAnders Carlsson            with zipfp.open(TESTFN) as zipopen:
21804b290030eee33295600728450f348989d1a627eDaniel Dunbar                for line in self.line_gen:
21904b290030eee33295600728450f348989d1a627eDaniel Dunbar                    linedata = zipopen.readline()
220c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson                    self.assertEqual(linedata, line + '\n')
22104b290030eee33295600728450f348989d1a627eDaniel Dunbar
222c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson    def zip_readlines_test(self, f, compression):
223b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        self.make_test_archive(f, compression)
224b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
225b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        # Read the ZIP archive
226b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(f, "r") as zipfp:
227b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            with zipfp.open(TESTFN) as zo:
22804b290030eee33295600728450f348989d1a627eDaniel Dunbar                ziplines = zo.readlines()
229b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                for line, zipline in zip(self.line_gen, ziplines):
230b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                    self.assertEqual(zipline, line + '\n')
231b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
232b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def zip_iterlines_test(self, f, compression):
233b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        self.make_test_archive(f, compression)
234b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
235b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        # Read the ZIP archive
236b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(f, "r") as zipfp:
237b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)):
238b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                self.assertEqual(zipline, line + '\n')
239b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
240b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def test_readline_read_stored(self):
241b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        # Issue #7610: calls to readline() interleaved with calls to read().
242c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson        for f in (TESTFN2, TemporaryFile(), StringIO()):
243a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar            self.zip_readline_read_test(f, zipfile.ZIP_STORED)
244a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar
245a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    def test_readline_stored(self):
246a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar        for f in (TESTFN2, TemporaryFile(), StringIO()):
247a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar            self.zip_readline_test(f, zipfile.ZIP_STORED)
248a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar
249a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    def test_readlines_stored(self):
250a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar        for f in (TESTFN2, TemporaryFile(), StringIO()):
251a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar            self.zip_readlines_test(f, zipfile.ZIP_STORED)
252a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar
253fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_iterlines_stored(self):
254fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
255fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_iterlines_test(f, zipfile.ZIP_STORED)
256fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
257fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
258fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_deflated(self):
259fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
260fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_test(f, zipfile.ZIP_DEFLATED)
261fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
262fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
263fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_open_deflated(self):
264fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
265fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_open_test(f, zipfile.ZIP_DEFLATED)
266fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
267fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
268fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_random_open_deflated(self):
269fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
270fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_random_open_test(f, zipfile.ZIP_DEFLATED)
271fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
272fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
273fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_readline_read_deflated(self):
274fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        # Issue #7610: calls to readline() interleaved with calls to read().
275fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
276fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_readline_read_test(f, zipfile.ZIP_DEFLATED)
277fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
278fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
279fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_readline_deflated(self):
280fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
281fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_readline_test(f, zipfile.ZIP_DEFLATED)
282fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
283fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
284fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    def test_readlines_deflated(self):
285fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
286fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner            self.zip_readlines_test(f, zipfile.ZIP_DEFLATED)
287fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
288fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    @skipUnless(zlib, "requires zlib")
2899e800e3dd80d77f6c47054738177bf824089f55aChris Lattner    def test_iterlines_deflated(self):
2909e800e3dd80d77f6c47054738177bf824089f55aChris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
2919e800e3dd80d77f6c47054738177bf824089f55aChris Lattner            self.zip_iterlines_test(f, zipfile.ZIP_DEFLATED)
2929e800e3dd80d77f6c47054738177bf824089f55aChris Lattner
2931caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    @skipUnless(zlib, "requires zlib")
2941caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    def test_low_compression(self):
2951caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        """Check for cases where compressed data is larger than original."""
2961caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        # Create the ZIP archive
2971caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp:
2981caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            zipfp.writestr("strfile", '12')
2991caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3001caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        # Get an open object for strfile
3011caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) as zipfp:
3029e800e3dd80d77f6c47054738177bf824089f55aChris Lattner            with zipfp.open("strfile") as openobj:
303d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman                self.assertEqual(openobj.read(1), '1')
3041caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                self.assertEqual(openobj.read(1), '2')
3051caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3061caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    def test_absolute_arcnames(self):
3071caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
3081caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            zipfp.write(TESTFN, "/absolute")
3091caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3101caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp:
3111caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            self.assertEqual(zipfp.namelist(), ["absolute"])
3121caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3131caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    def test_append_to_zip_file(self):
3141caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        """Test appending to an existing zipfile."""
3151caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
3161caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            zipfp.write(TESTFN, TESTFN)
3171caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3181caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp:
3191caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            zipfp.writestr("strfile", self.data)
3201caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar            self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"])
3211caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar
3221caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    def test_append_to_non_zip_file(self):
3231caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        """Test appending to an existing file that is not a zipfile."""
3241caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        # NOTE: this test fails if len(d) < 22 because of the first
3251caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar        # line "fpin.seek(-22, 2)" in _EndRecData
326d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman        data = 'I am not a ZipFile!'*10
327256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman        with open(TESTFN2, 'wb') as f:
328256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman            f.write(data)
329256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman
330256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman        with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp:
331256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman            zipfp.write(TESTFN, TESTFN)
332256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman
333256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman        with open(TESTFN2, 'rb') as f:
334256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman            f.seek(len(data))
3351ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            with zipfile.ZipFile(f, "r") as zipfp:
33609b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang                self.assertEqual(zipfp.namelist(), [TESTFN])
3371ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
33809b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang    def test_ignores_newline_at_end(self):
3391ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
3401ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            zipfp.write(TESTFN, TESTFN)
3411ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with open(TESTFN2, 'a') as f:
3421ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            f.write("\r\n\00\00\00")
3431ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
3441ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            self.assertIsInstance(zipfp, zipfile.ZipFile)
3451ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
3461ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    def test_ignores_stuff_appended_past_comments(self):
3471ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
3481ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            zipfp.comment = b"this is a comment"
3491ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            zipfp.write(TESTFN, TESTFN)
3501ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with open(TESTFN2, 'a') as f:
3511ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            f.write("abcdef\r\n")
3521ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
3531ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            self.assertIsInstance(zipfp, zipfile.ZipFile)
3541ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang            self.assertEqual(zipfp.comment, b"this is a comment")
3551ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
3561ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    def test_write_default_name(self):
3571ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang        """Check that calling ZipFile.write without arcname specified
358c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang        produces the expected result."""
359c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang        with zipfile.ZipFile(TESTFN2, "w") as zipfp:
360c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang            zipfp.write(TESTFN)
361c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang            self.assertEqual(zipfp.read(TESTFN), open(TESTFN).read())
3621ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
363022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson    @skipUnless(zlib, "requires zlib")
3641ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    def test_per_file_compression(self):
3657ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman        """Check that files within a Zip archive can have different
3667ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman        compression options."""
367b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, "w") as zipfp:
368b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED)
369b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED)
370b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            sinfo = zipfp.getinfo('storeme')
371b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            dinfo = zipfp.getinfo('deflateme')
372b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED)
373b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED)
374b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
375b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def test_write_to_readonly(self):
376b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        """Check that trying to call write() on a readonly ZipFile object
377b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        raises a RuntimeError."""
378b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
379b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            zipfp.writestr("somefile.txt", "bogus")
380b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
381b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
382b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            self.assertRaises(RuntimeError, zipfp.write, TESTFN)
383b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
384b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def test_extract(self):
385b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
386b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            for fpath, fdata in SMALL_TEST_DATA:
387b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                zipfp.writestr(fpath, fdata)
388b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
389b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
390b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            for fpath, fdata in SMALL_TEST_DATA:
391b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                writtenfile = zipfp.extract(fpath)
392b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
393b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                # make sure it was written to the right place
394b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                if os.path.isabs(fpath):
395b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                    correctfile = os.path.join(os.getcwd(), fpath[1:])
396b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                else:
397b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                    correctfile = os.path.join(os.getcwd(), fpath)
398b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                correctfile = os.path.normpath(correctfile)
399b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
400b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                self.assertEqual(writtenfile, correctfile)
401b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
402b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                # make sure correct data is in correct file
403b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                self.assertEqual(fdata, open(writtenfile, "rb").read())
404b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                os.remove(writtenfile)
405b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
406b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        # remove the test file subdirectories
407b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
408b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
409b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def test_extract_all(self):
410b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
411b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            for fpath, fdata in SMALL_TEST_DATA:
412b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                zipfp.writestr(fpath, fdata)
413b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
414b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
415b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            zipfp.extractall()
416b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            for fpath, fdata in SMALL_TEST_DATA:
417b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                if os.path.isabs(fpath):
418b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                    outfile = os.path.join(os.getcwd(), fpath[1:])
419b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                else:
420b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                    outfile = os.path.join(os.getcwd(), fpath)
421b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
422b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                self.assertEqual(fdata, open(outfile, "rb").read())
423b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner                os.remove(outfile)
424b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
425b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        # remove the test file subdirectories
426b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
427b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
428b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    def test_writestr_compression(self):
429b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        zipfp = zipfile.ZipFile(TESTFN2, "w")
430488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar        zipfp.writestr("a.txt", "hello world", compress_type=zipfile.ZIP_STORED)
431b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        if zlib:
432b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner            zipfp.writestr("b.txt", "hello world", compress_type=zipfile.ZIP_DEFLATED)
433b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
434b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        info = zipfp.getinfo('a.txt')
435b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        self.assertEqual(info.compress_type, zipfile.ZIP_STORED)
436b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
437564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson        if zlib:
4381feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            info = zipfp.getinfo('b.txt')
4391feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner            self.assertEqual(info.compress_type, zipfile.ZIP_DEFLATED)
4402929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
4412929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
4422929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def zip_test_writestr_permissions(self, f, compression):
4432929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        # Make sure that writestr creates files with mode 0600,
4442929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        # when it is passed a name rather than a ZipInfo instance.
4452929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
446564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson        self.make_test_archive(f, compression)
44746a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson        with zipfile.ZipFile(f, "r") as zipfp:
44846a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson            zinfo = zipfp.getinfo('strfile')
4492929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertEqual(zinfo.external_attr, 0600 << 16)
450e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
451e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_writestr_permissions(self):
4524e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        for f in (TESTFN2, TemporaryFile(), StringIO()):
453e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED)
4542929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
4554e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson    def test_close(self):
456e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that the zipfile is closed after the 'with' block."""
457e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN2, "w") as zipfp:
4584e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson            for fpath, fdata in SMALL_TEST_DATA:
459e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                zipfp.writestr(fpath, fdata)
460e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                self.assertTrue(zipfp.fp is not None, 'zipfp is not open')
461e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertTrue(zipfp.fp is None, 'zipfp is not closed')
462e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
4632929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
4642929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertTrue(zipfp.fp is not None, 'zipfp is not open')
4654e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        self.assertTrue(zipfp.fp is None, 'zipfp is not closed')
466e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
4674e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson    def test_close_on_exception(self):
468e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that the zipfile is closed if an exception is raised in the
4694e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        'with' block."""
470e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN2, "w") as zipfp:
4714e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson            for fpath, fdata in SMALL_TEST_DATA:
472e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                zipfp.writestr(fpath, fdata)
473cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
474e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        try:
475cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            with zipfile.ZipFile(TESTFN2, "r") as zipfp2:
4764e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson                raise zipfile.BadZipfile()
477e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        except zipfile.BadZipfile:
4784e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson            self.assertTrue(zipfp2.fp is None, 'zipfp is not closed')
479e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
4804e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson    def test_add_file_before_1980(self):
481e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # Set atime and mtime to 1970-01-01
4824e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        os.utime(TESTFN, (0, 0))
483e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN2, "w") as zipfp:
484cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            self.assertRaises(ValueError, zipfp.write, TESTFN)
485e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
486cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def tearDown(self):
487cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        unlink(TESTFN)
488cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        unlink(TESTFN2)
489e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
490e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
491db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlssonclass TestZip64InSmallFiles(unittest.TestCase):
492e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    # These tests test the ZIP64 functionality without using large files,
4932929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    # see test_zipfile64 for proper tests.
494db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson
4957acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    def setUp(self):
496db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson        self._limit = zipfile.ZIP64_LIMIT
497e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        zipfile.ZIP64_LIMIT = 5
498e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
499e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        line_gen = ("Test of zipfile line %d." % i
500e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                    for i in range(0, FIXEDTEST_SIZE))
501db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson        self.data = '\n'.join(line_gen)
5027acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner
503e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # Make a source file with some lines
504e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with open(TESTFN, "wb") as fp:
505e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fp.write(self.data)
506db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson
5077acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    def large_file_exception_test(self, f, compression):
508e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(f, "w", compression) as zipfp:
509e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertRaises(zipfile.LargeZipFile,
510abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman                              zipfp.write, TESTFN, "another.name")
511abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman
512db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson    def large_file_exception_test2(self, f, compression):
5137acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner        with zipfile.ZipFile(f, "w", compression) as zipfp:
514db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson            self.assertRaises(zipfile.LargeZipFile,
515db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson                              zipfp.writestr, "another.name", self.data)
5167acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner
517db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson    def test_large_file_exception(self):
5187acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner        for f in (TESTFN2, TemporaryFile(), StringIO()):
519e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.large_file_exception_test(f, zipfile.ZIP_STORED)
520e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.large_file_exception_test2(f, zipfile.ZIP_STORED)
521abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman
522abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman    def zip_test(self, f, compression):
523e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # Create the ZIP archive
524e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp:
525e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipfp.write(TESTFN, "another.name")
526e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipfp.write(TESTFN, TESTFN)
527e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipfp.writestr("strfile", self.data)
528e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
529e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # Read the ZIP archive
530e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(f, "r", compression) as zipfp:
531e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipfp.read(TESTFN), self.data)
532e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipfp.read("another.name"), self.data)
533e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipfp.read("strfile"), self.data)
534e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
535e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # Print the ZIP directory
536e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fp = StringIO()
537e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            stdout = sys.stdout
538e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            try:
539e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                sys.stdout = fp
540e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                zipfp.printdir()
541e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            finally:
542e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                sys.stdout = stdout
543e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
544e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            directory = fp.getvalue()
545e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            lines = directory.splitlines()
546e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(len(lines), 4) # Number of files + header
547e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
548e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn('File Name', lines[0])
549e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn('Modified', lines[0])
550e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn('Size', lines[0])
551e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
552e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fn, date, time_, size = lines[1].split()
553e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(fn, 'another.name')
554e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue(time.strptime(date, '%Y-%m-%d'))
555e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue(time.strptime(time_, '%H:%M:%S'))
556e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(size, str(len(self.data)))
557e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
558e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # Check the namelist
559e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            names = zipfp.namelist()
560e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(len(names), 3)
561e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn(TESTFN, names)
562e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn("another.name", names)
563e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn("strfile", names)
564e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
565e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # Check infolist
566e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            infos = zipfp.infolist()
567e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            names = [i.filename for i in infos]
568e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(len(names), 3)
569e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn(TESTFN, names)
570e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn("another.name", names)
571e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIn("strfile", names)
572e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            for i in infos:
573e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                self.assertEqual(i.file_size, len(self.data))
574e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
575e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # check getinfo
576e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            for nm in (TESTFN, "another.name", "strfile"):
577e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                info = zipfp.getinfo(nm)
5782929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                self.assertEqual(info.filename, nm)
5792929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                self.assertEqual(info.file_size, len(self.data))
5802929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
5812929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            # Check that testzip doesn't raise an exception
5822929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            zipfp.testzip()
5832929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
5842929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def test_stored(self):
5852929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        for f in (TESTFN2, TemporaryFile(), StringIO()):
5862929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.zip_test(f, zipfile.ZIP_STORED)
5872929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
5882929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    @skipUnless(zlib, "requires zlib")
5892929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def test_deflated(self):
5902929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        for f in (TESTFN2, TemporaryFile(), StringIO()):
5914e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson            self.zip_test(f, zipfile.ZIP_DEFLATED)
5922929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
5932929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def test_absolute_arcnames(self):
5942929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED,
5952929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                             allowZip64=True) as zipfp:
5962929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            zipfp.write(TESTFN, "/absolute")
5972929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
5982929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp:
5992929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertEqual(zipfp.namelist(), ["absolute"])
6002929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def tearDown(self):
6022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        zipfile.ZIP64_LIMIT = self._limit
6032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        unlink(TESTFN)
6042929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        unlink(TESTFN2)
6052929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6062929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6072929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlssonclass PyZipFileTests(unittest.TestCase):
6082929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    def test_write_pyfile(self):
6092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp:
6102929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            fn = __file__
6112929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            if fn.endswith('.pyc') or fn.endswith('.pyo'):
6122929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                fn = fn[:-1]
6132929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6142929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            zipfp.writepy(fn)
6152929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6162929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            bn = os.path.basename(fn)
6172929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertNotIn(bn, zipfp.namelist())
6182929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertTrue(bn + 'o' in zipfp.namelist() or
6192929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                            bn + 'c' in zipfp.namelist())
6202929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6212929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson        with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp:
6222929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            fn = __file__
6232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            if fn.endswith(('.pyc', '.pyo')):
6242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                fn = fn[:-1]
6252929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6262929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            zipfp.writepy(fn, "testpackage")
6277acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner
6282929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            bn = "%s/%s" % ("testpackage", os.path.basename(fn))
6292929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson            self.assertNotIn(bn, zipfp.namelist())
6307ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            self.assertTrue(bn + 'o' in zipfp.namelist() or
6317ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                            bn + 'c' in zipfp.namelist())
6327ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman
6337ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    def test_write_python_package(self):
6347ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman        import email
6357ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman        packagedir = os.path.dirname(email.__file__)
6367ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman
6377ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman        with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp:
6387ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            zipfp.writepy(packagedir)
6397ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman
6407ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            # Check for a couple of modules at different levels of the
6417ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            # hierarchy
6427ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            names = zipfp.namelist()
6437ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman            self.assertTrue('email/__init__.pyo' in names or
6442929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                            'email/__init__.pyc' in names)
6457acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner            self.assertTrue('email/mime/text.pyo' in names or
6462929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson                            'email/mime/text.pyc' in names)
6474e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson
6484e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson    def test_write_python_directory(self):
6494e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        os.mkdir(TESTFN2)
6504e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson        try:
6516086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson            with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp:
6526086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson                fp.write("print(42)\n")
6536086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson
6546086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson            with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp:
6556086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson                fp.write("print(42 * 42)\n")
656e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
657e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp:
658e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                fp.write("bla bla bla\n")
659e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
6606086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson            zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
661cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            zipfp.writepy(TESTFN2)
662e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
663cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            names = zipfp.namelist()
664e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue('mod1.pyc' in names or 'mod1.pyo' in names)
665e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue('mod2.pyc' in names or 'mod2.pyo' in names)
666e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertNotIn('mod2.txt', names)
667e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
668e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        finally:
669cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            shutil.rmtree(TESTFN2)
670e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
671cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_write_non_pyfile(self):
672e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp:
673e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            open(TESTFN, 'w').write('most definitely not a python file')
674e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertRaises(RuntimeError, zipfp.writepy, TESTFN)
675e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            os.remove(TESTFN)
676e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
6777acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner
678cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlssonclass OtherTests(unittest.TestCase):
679cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    zips_with_bad_crc = {
680cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        zipfile.ZIP_STORED: (
681cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'PK\003\004\024\0\0\0\0\0 \213\212;:r'
682e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'\253\377\f\0\0\0\f\0\0\0\005\0\0\000af'
683cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'ilehello,AworldP'
684e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'K\001\002\024\003\024\0\0\0\0\0 \213\212;:'
685cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'r\253\377\f\0\0\0\f\0\0\0\005\0\0\0\0'
686cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'\0\0\0\0\0\0\0\200\001\0\0\0\000afi'
687e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'lePK\005\006\0\0\0\0\001\0\001\0003\000'
688cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'\0\0/\0\0\0\0\0'),
689e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        zipfile.ZIP_DEFLATED: (
690cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'PK\x03\x04\x14\x00\x00\x00\x08\x00n}\x0c=FA'
691cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'KE\x10\x00\x00\x00n\x00\x00\x00\x05\x00\x00\x00af'
692e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'ile\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\xc9\xa0'
693cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'=\x13\x00PK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00n'
694e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'}\x0c=FAKE\x10\x00\x00\x00n\x00\x00\x00\x05'
695cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00'
696cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            b'\x00afilePK\x05\x06\x00\x00\x00\x00\x01\x00'
697e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            b'\x01\x003\x00\x00\x003\x00\x00\x00\x00\x00'),
698cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    }
699e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
700cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_unicode_filenames(self):
701cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with zipfile.ZipFile(TESTFN, "w") as zf:
702e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zf.writestr(u"foo.txt", "Test for unicode filename")
703cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            zf.writestr(u"\xf6.txt", "Test for unicode filename")
704e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertIsInstance(zf.infolist()[0].filename, unicode)
705cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
706cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with zipfile.ZipFile(TESTFN, "r") as zf:
707e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zf.filelist[0].filename, "foo.txt")
708cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            self.assertEqual(zf.filelist[1].filename, u"\xf6.txt")
709e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
710cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_create_non_existent_file_for_append(self):
711cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        if os.path.exists(TESTFN):
712e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            os.unlink(TESTFN)
713cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
714e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        filename = 'testfile.txt'
715cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        content = 'hello, world. this is some content.'
716cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
717e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        try:
718cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            with zipfile.ZipFile(TESTFN, 'a') as zf:
719e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                zf.writestr(filename, content)
720cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        except IOError:
721cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            self.fail('Could not append data to a non-existent zip file.')
722cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
723e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertTrue(os.path.exists(TESTFN))
724e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
725e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, 'r') as zf:
726e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zf.read(filename), content)
727e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
728e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_close_erroneous_file(self):
729e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # This test checks that the ZipFile constructor closes the file object
730cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # it opens if there's an error in the file.  If it doesn't, the
731cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # traceback holds a reference to the ZipFile object and, indirectly,
732cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # the file object.
733e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # On Windows, this causes the os.unlink() call to fail because the
734e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # underlying file is still open.  This is SF bug #412214.
735e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        #
736e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with open(TESTFN, "w") as fp:
737e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fp.write("this is not a legal zip file\n")
738e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        try:
7393eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner            zf = zipfile.ZipFile(TESTFN)
740e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        except zipfile.BadZipfile:
741e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            pass
742e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
743e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_is_zip_erroneous_file(self):
744e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that is_zipfile() correctly identifies non-zip files."""
745e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a filename
7463eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner        with open(TESTFN, "w") as fp:
747e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fp.write("this is not a legal zip file\n")
748e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        chk = zipfile.is_zipfile(TESTFN)
749cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertFalse(chk)
750e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a file object
751cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with open(TESTFN, "rb") as fp:
752e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            chk = zipfile.is_zipfile(fp)
753cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            self.assertTrue(not chk)
754e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a file-like object
755cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        fp = StringIO()
756e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        fp.write("this is not a legal zip file\n")
757cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        chk = zipfile.is_zipfile(fp)
758e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertTrue(not chk)
759cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        fp.seek(0, 0)
760e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        chk = zipfile.is_zipfile(fp)
761cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertTrue(not chk)
762e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
763cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_damaged_zipfile(self):
764e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that zipfiles with missing bytes at the end raise BadZipFile."""
765cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # - Create a valid zip file
766e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        fp = io.BytesIO()
767cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with zipfile.ZipFile(fp, mode="w") as zipf:
768e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
769cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        zipfiledata = fp.getvalue()
770e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
771e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - Now create copies of it missing the last N bytes and make sure
772e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        #   a BadZipFile exception is raised when we try to open it
7737acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner        for N in range(len(zipfiledata)):
774cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            fp = io.BytesIO(zipfiledata[:N])
775cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, fp)
776cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
777cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_is_zip_valid_file(self):
778e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that is_zipfile() correctly identifies zip files."""
779e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a filename
780e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
781e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
782e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        chk = zipfile.is_zipfile(TESTFN)
783e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertTrue(chk)
784e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a file object
785e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with open(TESTFN, "rb") as fp:
786e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            chk = zipfile.is_zipfile(fp)
787e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue(chk)
788e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            fp.seek(0, 0)
789e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zip_contents = fp.read()
790e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # - passing a file-like object
791e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        fp = StringIO()
792e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        fp.write(zip_contents)
793e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        chk = zipfile.is_zipfile(fp)
794cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertTrue(chk)
795e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        fp.seek(0, 0)
7967acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner        chk = zipfile.is_zipfile(fp)
797cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertTrue(chk)
798e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
799cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_non_existent_file_raises_IOError(self):
800cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # make sure we don't raise an AttributeError when a partially-constructed
801e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # ZipFile instance is finalized; this tests for regression on SF tracker
802cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # bug #403871.
803e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
804cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # The bug we're testing for caused an AttributeError to be raised
805cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # when a ZipFile instance was created for a file that did not
806cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # exist; the .fp member was not initialized but was needed by the
807e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # __del__() method.  Since the AttributeError is in the __del__(),
808cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # it is ignored, but the user should be sufficiently annoyed by
809e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # the message on the output that regression will be noticed
810cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # quickly.
811cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(IOError, zipfile.ZipFile, TESTFN)
812cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
813e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_empty_file_raises_BadZipFile(self):
814cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with open(TESTFN, 'w') as f:
815e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            pass
816cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN)
817cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
818cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        with open(TESTFN, 'w') as fp:
819cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson            fp.write("short file")
820cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN)
821cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
822e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_closed_zip_raises_RuntimeError(self):
823e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Verify that testzip() doesn't swallow inappropriate exceptions."""
824e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        data = StringIO()
825e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(data, mode="w") as zipf:
826e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
827e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
828e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # This is correct; calling .read on a closed ZipFile should raise
829cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # a RuntimeError, and so should calling .testzip.  An earlier
830cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # version of .testzip would swallow this exception (and any other)
831cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        # and report that the first file in the archive was corrupt.
832cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(RuntimeError, zipf.read, "foo.txt")
833cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(RuntimeError, zipf.open, "foo.txt")
834cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(RuntimeError, zipf.testzip)
835730f2c13e8ff0a2a3cc54fce9913add68107cb51Torok Edwin        self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus")
8367acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner        open(TESTFN, 'w').write('zipfile test data')
837cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson        self.assertRaises(RuntimeError, zipf.write, TESTFN)
838cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
839cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    def test_bad_constructor_mode(self):
84009b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang        """Check that bad modes passed to ZipFile constructor are caught."""
841730f2c13e8ff0a2a3cc54fce9913add68107cb51Torok Edwin        self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q")
8426c5df7f54f40090df6032a74e650b8e4d1c96207Mon P Wang
8436c5df7f54f40090df6032a74e650b8e4d1c96207Mon P Wang    def test_bad_open_mode(self):
8446c5df7f54f40090df6032a74e650b8e4d1c96207Mon P Wang        """Check that bad modes passed to ZipFile.open are caught."""
8456c5df7f54f40090df6032a74e650b8e4d1c96207Mon P Wang        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
846dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
847dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman
848dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman        with zipfile.ZipFile(TESTFN, mode="r") as zipf:
849dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman        # read the data to make sure the file is there
850dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman            zipf.read("foo.txt")
851dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman            self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q")
852dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman
853e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_read0(self):
854e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that calling read(0) on a ZipExtFile object returns an empty
855e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        string and doesn't advance file pointer."""
856e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
857e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
858e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # read the data to make sure the file is there
859e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            with zipf.open("foo.txt") as f:
860e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                for i in xrange(FIXEDTEST_SIZE):
861abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman                    self.assertEqual(f.read(0), '')
862abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman
863abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman                self.assertEqual(f.read(), "O, for a Muse of Fire!")
864abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman
865abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman    def test_open_non_existent_item(self):
866abfaf9984eee3d076ded8770bf9fce156f10c185Nate Begeman        """Check that attempting to call open() for an item that doesn't
867e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        exist in the archive raises a RuntimeError."""
868e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
869e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertRaises(KeyError, zipf.open, "foo.txt", "r")
870e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
871e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_bad_compression_mode(self):
872e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that bad compression methods passed to ZipFile.open are
873e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        caught."""
874e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
875e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
876e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_unsupported_compression(self):
877e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # data is declared as shrunk, but actually deflated
878e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        data = (b'PK\x03\x04.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00'
879e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        b'\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00x\x03\x00PK\x01'
880e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        b'\x02.\x03.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00\x00\x02\x00\x00'
881e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
882e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        b'\x80\x01\x00\x00\x00\x00xPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00'
883e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        b'/\x00\x00\x00!\x00\x00\x00\x00\x00')
884e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
885e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertRaises(NotImplementedError, zipf.open, 'x')
886e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
887e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_null_byte_in_filename(self):
888e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that a filename containing a null byte is properly
889e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        terminated."""
890e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
891e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!")
892e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.namelist(), ['foo.txt'])
893e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
894e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_struct_sizes(self):
895e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that ZIP internal structure sizes are calculated correctly."""
896e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertEqual(zipfile.sizeEndCentDir, 22)
897e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertEqual(zipfile.sizeCentralDir, 46)
898e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertEqual(zipfile.sizeEndCentDir64, 56)
899e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.assertEqual(zipfile.sizeEndCentDir64Locator, 20)
900e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
901e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_comments(self):
902e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Check that comments on the archive are handled properly."""
903e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
904e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # check default comment is empty
905e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
906e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, '')
907e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
908e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
909e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="r") as zipf:
910e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, '')
911e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
912e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # check a simple short comment
913e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        comment = 'Bravely taking to his feet, he beat a very brave retreat.'
914e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
915e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.comment = comment
916e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
917e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="r") as zipf:
918e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, comment)
919e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
920e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # check a comment of max length
921e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        comment2 = ''.join(['%d' % (i**3 % 10) for i in xrange((1 << 16)-1)])
922e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
923e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.comment = comment2
924e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
925e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
926e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="r") as zipf:
92724512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman            self.assertEqual(zipf.comment, comment2)
92824512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman
92924512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman        # check a comment that is too long is truncated
930e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
931e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.comment = comment2 + 'oops'
932e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
933e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, mode="r") as zipf:
934e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, comment2)
935e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
936e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_change_comment_in_empty_archive(self):
937e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf:
938e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertFalse(zipf.filelist)
939e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.comment = b"this is a comment"
940e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, "r") as zipf:
941e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, b"this is a comment")
942e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
943e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_change_comment_in_nonempty_archive(self):
944e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, "w", zipfile.ZIP_STORED) as zipf:
945e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.writestr("foo.txt", "O, for a Muse of Fire!")
946e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, "a", zipfile.ZIP_STORED) as zipf:
947e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertTrue(zipf.filelist)
948e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            zipf.comment = b"this is a comment"
949e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(TESTFN, "r") as zipf:
950e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual(zipf.comment, b"this is a comment")
951e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
952e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def check_testzip_with_bad_crc(self, compression):
953e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Tests that files with bad CRCs return their name from testzip."""
954e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        zipdata = self.zips_with_bad_crc[compression]
955e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
956e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
957e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            # testzip returns the name of the first corrupt file, or None
958e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman            self.assertEqual('afile', zipf.testzip())
959e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
960e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_testzip_with_bad_crc_stored(self):
961e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.check_testzip_with_bad_crc(zipfile.ZIP_STORED)
962e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
963e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    @skipUnless(zlib, "requires zlib")
964e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def test_testzip_with_bad_crc_deflated(self):
965e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        self.check_testzip_with_bad_crc(zipfile.ZIP_DEFLATED)
966e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
967e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    def check_read_with_bad_crc(self, compression):
968e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        """Tests that files with bad CRCs raise a BadZipfile exception when read."""
969e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        zipdata = self.zips_with_bad_crc[compression]
970e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
971e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        # Using ZipFile.read()
972564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson        with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
973564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson            self.assertRaises(zipfile.BadZipfile, zipf.read, 'afile')
974564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
9751feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner        # Using ZipExtFile.read()
9761feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner        with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
977564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson            with zipf.open('afile', 'r') as corrupt_file:
97846a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson                self.assertRaises(zipfile.BadZipfile, corrupt_file.read)
979564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
980564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson        # Same with small reads (in order to exercise the buffering logic)
981        with zipfile.ZipFile(io.BytesIO(zipdata), mode="r") as zipf:
982            with zipf.open('afile', 'r') as corrupt_file:
983                corrupt_file.MIN_READ_SIZE = 2
984                with self.assertRaises(zipfile.BadZipfile):
985                    while corrupt_file.read(2):
986                        pass
987
988    def test_read_with_bad_crc_stored(self):
989        self.check_read_with_bad_crc(zipfile.ZIP_STORED)
990
991    @skipUnless(zlib, "requires zlib")
992    def test_read_with_bad_crc_deflated(self):
993        self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED)
994
995    def check_read_return_size(self, compression):
996        # Issue #9837: ZipExtFile.read() shouldn't return more bytes
997        # than requested.
998        for test_size in (1, 4095, 4096, 4097, 16384):
999            file_size = test_size + 1
1000            junk = b''.join(struct.pack('B', randint(0, 255))
1001                            for x in range(file_size))
1002            with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf:
1003                zipf.writestr('foo', junk)
1004                with zipf.open('foo', 'r') as fp:
1005                    buf = fp.read(test_size)
1006                    self.assertEqual(len(buf), test_size)
1007
1008    def test_read_return_size_stored(self):
1009        self.check_read_return_size(zipfile.ZIP_STORED)
1010
1011    @skipUnless(zlib, "requires zlib")
1012    def test_read_return_size_deflated(self):
1013        self.check_read_return_size(zipfile.ZIP_DEFLATED)
1014
1015    def test_empty_zipfile(self):
1016        # Check that creating a file in 'w' or 'a' mode and closing without
1017        # adding any files to the archives creates a valid empty ZIP file
1018        with zipfile.ZipFile(TESTFN, mode="w") as zipf:
1019            pass
1020        try:
1021            zipf = zipfile.ZipFile(TESTFN, mode="r")
1022        except zipfile.BadZipfile:
1023            self.fail("Unable to create empty ZIP file in 'w' mode")
1024
1025        with zipfile.ZipFile(TESTFN, mode="a") as zipf:
1026            pass
1027        try:
1028            zipf = zipfile.ZipFile(TESTFN, mode="r")
1029        except:
1030            self.fail("Unable to create empty ZIP file in 'a' mode")
1031
1032    def test_open_empty_file(self):
1033        # Issue 1710703: Check that opening a file with less than 22 bytes
1034        # raises a BadZipfile exception (rather than the previously unhelpful
1035        # IOError)
1036        with open(TESTFN, 'w') as f:
1037            pass
1038        self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN, 'r')
1039
1040    def test_create_zipinfo_before_1980(self):
1041        self.assertRaises(ValueError,
1042                          zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0))
1043
1044    def tearDown(self):
1045        unlink(TESTFN)
1046        unlink(TESTFN2)
1047
1048
1049class DecryptionTests(unittest.TestCase):
1050    """Check that ZIP decryption works. Since the library does not
1051    support encryption at the moment, we use a pre-generated encrypted
1052    ZIP file."""
1053
1054    data = (
1055    'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
1056    '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
1057    '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
1058    'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
1059    '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
1060    '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
1061    '\x00\x00L\x00\x00\x00\x00\x00' )
1062    data2 = (
1063    'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02'
1064    '\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04'
1065    '\x00\xe8\x03\xe8\x03\xc7<M\xb5a\xceX\xa3Y&\x8b{oE\xd7\x9d\x8c\x98\x02\xc0'
1066    'PK\x07\x08xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00PK\x01\x02\x17\x03'
1067    '\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02\x00\x00'
1068    '\x04\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00ze'
1069    'roUT\x05\x00\x03\xd6\x8b\x92GUx\x00\x00PK\x05\x06\x00\x00\x00\x00\x01'
1070    '\x00\x01\x00?\x00\x00\x00[\x00\x00\x00\x00\x00' )
1071
1072    plain = 'zipfile.py encryption test'
1073    plain2 = '\x00'*512
1074
1075    def setUp(self):
1076        with open(TESTFN, "wb") as fp:
1077            fp.write(self.data)
1078        self.zip = zipfile.ZipFile(TESTFN, "r")
1079        with open(TESTFN2, "wb") as fp:
1080            fp.write(self.data2)
1081        self.zip2 = zipfile.ZipFile(TESTFN2, "r")
1082
1083    def tearDown(self):
1084        self.zip.close()
1085        os.unlink(TESTFN)
1086        self.zip2.close()
1087        os.unlink(TESTFN2)
1088
1089    def test_no_password(self):
1090        # Reading the encrypted file without password
1091        # must generate a RunTime exception
1092        self.assertRaises(RuntimeError, self.zip.read, "test.txt")
1093        self.assertRaises(RuntimeError, self.zip2.read, "zero")
1094
1095    def test_bad_password(self):
1096        self.zip.setpassword("perl")
1097        self.assertRaises(RuntimeError, self.zip.read, "test.txt")
1098        self.zip2.setpassword("perl")
1099        self.assertRaises(RuntimeError, self.zip2.read, "zero")
1100
1101    @skipUnless(zlib, "requires zlib")
1102    def test_good_password(self):
1103        self.zip.setpassword("python")
1104        self.assertEqual(self.zip.read("test.txt"), self.plain)
1105        self.zip2.setpassword("12345")
1106        self.assertEqual(self.zip2.read("zero"), self.plain2)
1107
1108
1109class TestsWithRandomBinaryFiles(unittest.TestCase):
1110    def setUp(self):
1111        datacount = randint(16, 64)*1024 + randint(1, 1024)
1112        self.data = ''.join(struct.pack('<f', random()*randint(-1000, 1000))
1113                            for i in xrange(datacount))
1114
1115        # Make a source file with some lines
1116        with open(TESTFN, "wb") as fp:
1117            fp.write(self.data)
1118
1119    def tearDown(self):
1120        unlink(TESTFN)
1121        unlink(TESTFN2)
1122
1123    def make_test_archive(self, f, compression):
1124        # Create the ZIP archive
1125        with zipfile.ZipFile(f, "w", compression) as zipfp:
1126            zipfp.write(TESTFN, "another.name")
1127            zipfp.write(TESTFN, TESTFN)
1128
1129    def zip_test(self, f, compression):
1130        self.make_test_archive(f, compression)
1131
1132        # Read the ZIP archive
1133        with zipfile.ZipFile(f, "r", compression) as zipfp:
1134            testdata = zipfp.read(TESTFN)
1135            self.assertEqual(len(testdata), len(self.data))
1136            self.assertEqual(testdata, self.data)
1137            self.assertEqual(zipfp.read("another.name"), self.data)
1138
1139    def test_stored(self):
1140        for f in (TESTFN2, TemporaryFile(), StringIO()):
1141            self.zip_test(f, zipfile.ZIP_STORED)
1142
1143    @skipUnless(zlib, "requires zlib")
1144    def test_deflated(self):
1145        for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
1146            self.zip_test(f, zipfile.ZIP_DEFLATED)
1147
1148    def zip_open_test(self, f, compression):
1149        self.make_test_archive(f, compression)
1150
1151        # Read the ZIP archive
1152        with zipfile.ZipFile(f, "r", compression) as zipfp:
1153            zipdata1 = []
1154            with zipfp.open(TESTFN) as zipopen1:
1155                while True:
1156                    read_data = zipopen1.read(256)
1157                    if not read_data:
1158                        break
1159                    zipdata1.append(read_data)
1160
1161            zipdata2 = []
1162            with zipfp.open("another.name") as zipopen2:
1163                while True:
1164                    read_data = zipopen2.read(256)
1165                    if not read_data:
1166                        break
1167                    zipdata2.append(read_data)
1168
1169            testdata1 = ''.join(zipdata1)
1170            self.assertEqual(len(testdata1), len(self.data))
1171            self.assertEqual(testdata1, self.data)
1172
1173            testdata2 = ''.join(zipdata2)
1174            self.assertEqual(len(testdata2), len(self.data))
1175            self.assertEqual(testdata2, self.data)
1176
1177    def test_open_stored(self):
1178        for f in (TESTFN2, TemporaryFile(), StringIO()):
1179            self.zip_open_test(f, zipfile.ZIP_STORED)
1180
1181    @skipUnless(zlib, "requires zlib")
1182    def test_open_deflated(self):
1183        for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
1184            self.zip_open_test(f, zipfile.ZIP_DEFLATED)
1185
1186    def zip_random_open_test(self, f, compression):
1187        self.make_test_archive(f, compression)
1188
1189        # Read the ZIP archive
1190        with zipfile.ZipFile(f, "r", compression) as zipfp:
1191            zipdata1 = []
1192            with zipfp.open(TESTFN) as zipopen1:
1193                while True:
1194                    read_data = zipopen1.read(randint(1, 1024))
1195                    if not read_data:
1196                        break
1197                    zipdata1.append(read_data)
1198
1199            testdata = ''.join(zipdata1)
1200            self.assertEqual(len(testdata), len(self.data))
1201            self.assertEqual(testdata, self.data)
1202
1203    def test_random_open_stored(self):
1204        for f in (TESTFN2, TemporaryFile(), StringIO()):
1205            self.zip_random_open_test(f, zipfile.ZIP_STORED)
1206
1207    @skipUnless(zlib, "requires zlib")
1208    def test_random_open_deflated(self):
1209        for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
1210            self.zip_random_open_test(f, zipfile.ZIP_DEFLATED)
1211
1212
1213@skipUnless(zlib, "requires zlib")
1214class TestsWithMultipleOpens(unittest.TestCase):
1215    def setUp(self):
1216        # Create the ZIP archive
1217        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp:
1218            zipfp.writestr('ones', '1'*FIXEDTEST_SIZE)
1219            zipfp.writestr('twos', '2'*FIXEDTEST_SIZE)
1220
1221    def test_same_file(self):
1222        # Verify that (when the ZipFile is in control of creating file objects)
1223        # multiple open() calls can be made without interfering with each other.
1224        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
1225            zopen1 = zipf.open('ones')
1226            zopen2 = zipf.open('ones')
1227            data1 = zopen1.read(500)
1228            data2 = zopen2.read(500)
1229            data1 += zopen1.read(500)
1230            data2 += zopen2.read(500)
1231            self.assertEqual(data1, data2)
1232
1233    def test_different_file(self):
1234        # Verify that (when the ZipFile is in control of creating file objects)
1235        # multiple open() calls can be made without interfering with each other.
1236        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
1237            with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
1238                data1 = zopen1.read(500)
1239                data2 = zopen2.read(500)
1240                data1 += zopen1.read(500)
1241                data2 += zopen2.read(500)
1242            self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
1243            self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
1244
1245    def test_interleaved(self):
1246        # Verify that (when the ZipFile is in control of creating file objects)
1247        # multiple open() calls can be made without interfering with each other.
1248        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
1249            with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
1250                data1 = zopen1.read(500)
1251                data2 = zopen2.read(500)
1252                data1 += zopen1.read(500)
1253                data2 += zopen2.read(500)
1254            self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
1255            self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
1256
1257    def tearDown(self):
1258        unlink(TESTFN2)
1259
1260
1261class TestWithDirectory(unittest.TestCase):
1262    def setUp(self):
1263        os.mkdir(TESTFN2)
1264
1265    def test_extract_dir(self):
1266        with zipfile.ZipFile(findfile("zipdir.zip")) as zipf:
1267            zipf.extractall(TESTFN2)
1268        self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a")))
1269        self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b")))
1270        self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c")))
1271
1272    def test_bug_6050(self):
1273        # Extraction should succeed if directories already exist
1274        os.mkdir(os.path.join(TESTFN2, "a"))
1275        self.test_extract_dir()
1276
1277    def test_store_dir(self):
1278        os.mkdir(os.path.join(TESTFN2, "x"))
1279        zipf = zipfile.ZipFile(TESTFN, "w")
1280        zipf.write(os.path.join(TESTFN2, "x"), "x")
1281        self.assertTrue(zipf.filelist[0].filename.endswith("x/"))
1282
1283    def tearDown(self):
1284        shutil.rmtree(TESTFN2)
1285        if os.path.exists(TESTFN):
1286            unlink(TESTFN)
1287
1288
1289class UniversalNewlineTests(unittest.TestCase):
1290    def setUp(self):
1291        self.line_gen = ["Test of zipfile line %d." % i
1292                         for i in xrange(FIXEDTEST_SIZE)]
1293        self.seps = ('\r', '\r\n', '\n')
1294        self.arcdata, self.arcfiles = {}, {}
1295        for n, s in enumerate(self.seps):
1296            self.arcdata[s] = s.join(self.line_gen) + s
1297            self.arcfiles[s] = '%s-%d' % (TESTFN, n)
1298            open(self.arcfiles[s], "wb").write(self.arcdata[s])
1299
1300    def make_test_archive(self, f, compression):
1301        # Create the ZIP archive
1302        with zipfile.ZipFile(f, "w", compression) as zipfp:
1303            for fn in self.arcfiles.values():
1304                zipfp.write(fn, fn)
1305
1306    def read_test(self, f, compression):
1307        self.make_test_archive(f, compression)
1308
1309        # Read the ZIP archive
1310        with zipfile.ZipFile(f, "r") as zipfp:
1311            for sep, fn in self.arcfiles.items():
1312                with zipfp.open(fn, "rU") as fp:
1313                    zipdata = fp.read()
1314                self.assertEqual(self.arcdata[sep], zipdata)
1315
1316    def readline_read_test(self, f, compression):
1317        self.make_test_archive(f, compression)
1318
1319        # Read the ZIP archive
1320        zipfp = zipfile.ZipFile(f, "r")
1321        for sep, fn in self.arcfiles.items():
1322            with zipfp.open(fn, "rU") as zipopen:
1323                data = ''
1324                while True:
1325                    read = zipopen.readline()
1326                    if not read:
1327                        break
1328                    data += read
1329
1330                    read = zipopen.read(5)
1331                    if not read:
1332                        break
1333                    data += read
1334
1335            self.assertEqual(data, self.arcdata['\n'])
1336
1337        zipfp.close()
1338
1339    def readline_test(self, f, compression):
1340        self.make_test_archive(f, compression)
1341
1342        # Read the ZIP archive
1343        with zipfile.ZipFile(f, "r") as zipfp:
1344            for sep, fn in self.arcfiles.items():
1345                with zipfp.open(fn, "rU") as zipopen:
1346                    for line in self.line_gen:
1347                        linedata = zipopen.readline()
1348                        self.assertEqual(linedata, line + '\n')
1349
1350    def readlines_test(self, f, compression):
1351        self.make_test_archive(f, compression)
1352
1353        # Read the ZIP archive
1354        with zipfile.ZipFile(f, "r") as zipfp:
1355            for sep, fn in self.arcfiles.items():
1356                with zipfp.open(fn, "rU") as fp:
1357                    ziplines = fp.readlines()
1358                for line, zipline in zip(self.line_gen, ziplines):
1359                    self.assertEqual(zipline, line + '\n')
1360
1361    def iterlines_test(self, f, compression):
1362        self.make_test_archive(f, compression)
1363
1364        # Read the ZIP archive
1365        with zipfile.ZipFile(f, "r") as zipfp:
1366            for sep, fn in self.arcfiles.items():
1367                for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")):
1368                    self.assertEqual(zipline, line + '\n')
1369
1370    def test_read_stored(self):
1371        for f in (TESTFN2, TemporaryFile(), StringIO()):
1372            self.read_test(f, zipfile.ZIP_STORED)
1373
1374    def test_readline_read_stored(self):
1375        # Issue #7610: calls to readline() interleaved with calls to read().
1376        for f in (TESTFN2, TemporaryFile(), StringIO()):
1377            self.readline_read_test(f, zipfile.ZIP_STORED)
1378
1379    def test_readline_stored(self):
1380        for f in (TESTFN2, TemporaryFile(), StringIO()):
1381            self.readline_test(f, zipfile.ZIP_STORED)
1382
1383    def test_readlines_stored(self):
1384        for f in (TESTFN2, TemporaryFile(), StringIO()):
1385            self.readlines_test(f, zipfile.ZIP_STORED)
1386
1387    def test_iterlines_stored(self):
1388        for f in (TESTFN2, TemporaryFile(), StringIO()):
1389            self.iterlines_test(f, zipfile.ZIP_STORED)
1390
1391    @skipUnless(zlib, "requires zlib")
1392    def test_read_deflated(self):
1393        for f in (TESTFN2, TemporaryFile(), StringIO()):
1394            self.read_test(f, zipfile.ZIP_DEFLATED)
1395
1396    @skipUnless(zlib, "requires zlib")
1397    def test_readline_read_deflated(self):
1398        # Issue #7610: calls to readline() interleaved with calls to read().
1399        for f in (TESTFN2, TemporaryFile(), StringIO()):
1400            self.readline_read_test(f, zipfile.ZIP_DEFLATED)
1401
1402    @skipUnless(zlib, "requires zlib")
1403    def test_readline_deflated(self):
1404        for f in (TESTFN2, TemporaryFile(), StringIO()):
1405            self.readline_test(f, zipfile.ZIP_DEFLATED)
1406
1407    @skipUnless(zlib, "requires zlib")
1408    def test_readlines_deflated(self):
1409        for f in (TESTFN2, TemporaryFile(), StringIO()):
1410            self.readlines_test(f, zipfile.ZIP_DEFLATED)
1411
1412    @skipUnless(zlib, "requires zlib")
1413    def test_iterlines_deflated(self):
1414        for f in (TESTFN2, TemporaryFile(), StringIO()):
1415            self.iterlines_test(f, zipfile.ZIP_DEFLATED)
1416
1417    def tearDown(self):
1418        for sep, fn in self.arcfiles.items():
1419            os.remove(fn)
1420        unlink(TESTFN)
1421        unlink(TESTFN2)
1422
1423
1424def test_main():
1425    run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
1426                 PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
1427                 TestWithDirectory, UniversalNewlineTests,
1428                 TestsWithRandomBinaryFiles)
1429
1430if __name__ == "__main__":
1431    test_main()
1432