Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b09b844

Browse files
committed
Merged revisions 64688 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r64688 | martin.v.loewis | 2008-07-03 14:51:14 +0200 (Do, 03 Jul 2008) | 9 lines Patch #1622: Correct interpretation of various ZIP header fields. Also fixes - Issue #1526: Allow more than 64k files to be added to Zip64 file. - Issue #1746: Correct handling of zipfile archive comments (previously archives with comments over 4k were flagged as invalid). Allow writing Zip files with archives by setting the 'comment' attribute of a ZipFile. ........
1 parent 451a356 commit b09b844

5 files changed

Lines changed: 317 additions & 109 deletions

File tree

Doc/library/zipfile.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ ZipFile Objects
269269
member of the given :class:`ZipInfo` instance. By default, the
270270
:class:`ZipInfo` constructor sets this member to :const:`ZIP_STORED`.
271271

272-
The following data attribute is also available:
272+
The following data attributes are also available:
273273

274274

275275
.. attribute:: ZipFile.debug
@@ -278,6 +278,12 @@ The following data attribute is also available:
278278
output) to ``3`` (the most output). Debugging information is written to
279279
``sys.stdout``.
280280

281+
.. attribute:: ZipFile.comment
282+
283+
The comment text associated with the ZIP file. If assigning a comment to a
284+
:class:`ZipFile` instance created with mode 'a' or 'w', this should be a
285+
string no longer than 65535 bytes. Comments longer than this will be
286+
truncated in the written archive when :meth:`ZipFile.close` is called.
281287

282288
.. _pyzipfile-objects:
283289

Lib/test/test_zipfile.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,55 @@ def test_NullByteInFilename(self):
699699
zipf.writestr("foo.txt\x00qqq", b"O, for a Muse of Fire!")
700700
self.assertEqual(zipf.namelist(), ['foo.txt'])
701701

702+
def test_StructSizes(self):
703+
# check that ZIP internal structure sizes are calculated correctly
704+
self.assertEqual(zipfile.sizeEndCentDir, 22)
705+
self.assertEqual(zipfile.sizeCentralDir, 46)
706+
self.assertEqual(zipfile.sizeEndCentDir64, 56)
707+
self.assertEqual(zipfile.sizeEndCentDir64Locator, 20)
708+
709+
def testComments(self):
710+
# This test checks that comments on the archive are handled properly
711+
712+
# check default comment is empty
713+
zipf = zipfile.ZipFile(TESTFN, mode="w")
714+
self.assertEqual(zipf.comment, b'')
715+
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
716+
zipf.close()
717+
zipfr = zipfile.ZipFile(TESTFN, mode="r")
718+
self.assertEqual(zipfr.comment, b'')
719+
zipfr.close()
720+
721+
# check a simple short comment
722+
comment = b'Bravely taking to his feet, he beat a very brave retreat.'
723+
zipf = zipfile.ZipFile(TESTFN, mode="w")
724+
zipf.comment = comment
725+
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
726+
zipf.close()
727+
zipfr = zipfile.ZipFile(TESTFN, mode="r")
728+
self.assertEqual(zipfr.comment, comment)
729+
zipfr.close()
730+
731+
# check a comment of max length
732+
comment2 = ''.join(['%d' % (i**3 % 10) for i in range((1 << 16)-1)])
733+
comment2 = comment2.encode("ascii")
734+
zipf = zipfile.ZipFile(TESTFN, mode="w")
735+
zipf.comment = comment2
736+
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
737+
zipf.close()
738+
zipfr = zipfile.ZipFile(TESTFN, mode="r")
739+
self.assertEqual(zipfr.comment, comment2)
740+
zipfr.close()
741+
742+
# check a comment that is too long is truncated
743+
zipf = zipfile.ZipFile(TESTFN, mode="w")
744+
zipf.comment = comment2 + b'oops'
745+
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
746+
zipf.close()
747+
zipfr = zipfile.ZipFile(TESTFN, mode="r")
748+
self.assertEqual(zipfr.comment, comment2)
749+
zipfr.close()
750+
702751
def tearDown(self):
703752
support.unlink(TESTFN)
704753
support.unlink(TESTFN2)

Lib/test/test_zipfile64.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# The support.requires call is the only reason for keeping this separate
33
# from test_zipfile
44
from test import support
5+
56
# XXX(nnorwitz): disable this test by looking for extra largfile resource
67
# which doesn't exist. This test takes over 30 minutes to run in general
78
# and requires more disk space than most of the buildbots.
@@ -92,8 +93,31 @@ def tearDown(self):
9293
if os.path.exists(fname):
9394
os.remove(fname)
9495

96+
97+
class OtherTests(unittest.TestCase):
98+
def testMoreThan64kFiles(self):
99+
# This test checks that more than 64k files can be added to an archive,
100+
# and that the resulting archive can be read properly by ZipFile
101+
zipf = zipfile.ZipFile(TESTFN, mode="w")
102+
zipf.debug = 100
103+
numfiles = (1 << 16) * 3/2
104+
for i in xrange(numfiles):
105+
zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
106+
self.assertEqual(len(zipf.namelist()), numfiles)
107+
zipf.close()
108+
109+
zipf2 = zipfile.ZipFile(TESTFN, mode="r")
110+
self.assertEqual(len(zipf2.namelist()), numfiles)
111+
for i in xrange(numfiles):
112+
self.assertEqual(zipf2.read("foo%08d" % i), "%d" % (i**3 % 57))
113+
zipf.close()
114+
115+
def tearDown(self):
116+
test_support.unlink(TESTFN)
117+
test_support.unlink(TESTFN2)
118+
95119
def test_main():
96-
run_unittest(TestsWithSourceFile)
120+
run_unittest(TestsWithSourceFile, OtherTests)
97121

98122
if __name__ == "__main__":
99123
test_main()

0 commit comments

Comments
 (0)