]> granicus.if.org Git - python/commitdiff
bpo-26185: Fix repr() on empty ZipInfo object (#13441)
authorMickaël Schoentgen <contact@tiger-222.fr>
Mon, 9 Sep 2019 13:08:54 +0000 (15:08 +0200)
committerDino Viehland <dinoviehland@gmail.com>
Mon, 9 Sep 2019 13:08:54 +0000 (06:08 -0700)
* bpo-26185: Fix repr() on empty ZipInfo object

It was failing on AttributeError due to inexistant
but required attributes file_size and compress_size.
They are now initialized to 0 in ZipInfo.__init__().

* Remove useless hasattr() in ZipInfo._open_to_write()

* Completely remove file_size setting in _open_to_write().

Lib/test/test_zipfile.py
Lib/zipfile.py
Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst [new file with mode: 0644]

index 8e437e5cb2b90c870ded66556f4b1ff967d69634..f9ee740eb6fa4d9ac280b526b3e773126179ae51 100644 (file)
@@ -1655,6 +1655,33 @@ class OtherTests(unittest.TestCase):
         self.assertRaises(ValueError,
                           zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0))
 
+    def test_create_empty_zipinfo_repr(self):
+        """Before bpo-26185, repr() on empty ZipInfo object was failing."""
+        zi = zipfile.ZipInfo(filename="empty")
+        self.assertEqual(repr(zi), "<ZipInfo filename='empty' file_size=0>")
+
+    def test_create_empty_zipinfo_default_attributes(self):
+        """Ensure all required attributes are set."""
+        zi = zipfile.ZipInfo()
+        self.assertEqual(zi.orig_filename, "NoName")
+        self.assertEqual(zi.filename, "NoName")
+        self.assertEqual(zi.date_time, (1980, 1, 1, 0, 0, 0))
+        self.assertEqual(zi.compress_type, zipfile.ZIP_STORED)
+        self.assertEqual(zi.comment, b"")
+        self.assertEqual(zi.extra, b"")
+        self.assertIn(zi.create_system, (0, 3))
+        self.assertEqual(zi.create_version, zipfile.DEFAULT_VERSION)
+        self.assertEqual(zi.extract_version, zipfile.DEFAULT_VERSION)
+        self.assertEqual(zi.reserved, 0)
+        self.assertEqual(zi.flag_bits, 0)
+        self.assertEqual(zi.volume, 0)
+        self.assertEqual(zi.internal_attr, 0)
+        self.assertEqual(zi.external_attr, 0)
+
+        # Before bpo-26185, both were missing
+        self.assertEqual(zi.file_size, 0)
+        self.assertEqual(zi.compress_size, 0)
+
     def test_zipfile_with_short_extra_field(self):
         """If an extra field in the header is less than 4 bytes, skip it."""
         zipdata = (
index dfd090795019622a84d3cbc04734bff6ec0e8118..c2c5b6a2a44a7688e35b5b52b97099e409ae9126 100644 (file)
@@ -376,11 +376,11 @@ class ZipInfo (object):
         self.volume = 0                 # Volume number of file header
         self.internal_attr = 0          # Internal attributes
         self.external_attr = 0          # External file attributes
+        self.compress_size = 0          # Size of the compressed file
+        self.file_size = 0              # Size of the uncompressed file
         # Other attributes are set by class ZipFile:
         # header_offset         Byte offset to the file header
         # CRC                   CRC-32 of the uncompressed file
-        # compress_size         Size of the compressed file
-        # file_size             Size of the uncompressed file
 
     def __repr__(self):
         result = ['<%s filename=%r' % (self.__class__.__name__, self.filename)]
@@ -1564,9 +1564,7 @@ class ZipFile:
                              "another write handle open on it. "
                              "Close the first handle before opening another.")
 
-        # Sizes and CRC are overwritten with correct data after processing the file
-        if not hasattr(zinfo, 'file_size'):
-            zinfo.file_size = 0
+        # Size and CRC are overwritten with correct data after processing the file
         zinfo.compress_size = 0
         zinfo.CRC = 0
 
diff --git a/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst b/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst
new file mode 100644 (file)
index 0000000..dc71dae
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by Mickaël
+Schoentgen.