]> granicus.if.org Git - python/commitdiff
Fix issue #14315: The zipfile module now ignores extra fields in the central
authorGregory P. Smith <greg@krypto.org>
Fri, 30 May 2014 06:41:52 +0000 (23:41 -0700)
committerGregory P. Smith <greg@krypto.org>
Fri, 30 May 2014 06:41:52 +0000 (23:41 -0700)
directory that are too short to be parsed instead of letting a struct.unpack
error bubble up as this "bad data" appears in many real world zip files in the
wild and is ignored by other zip tools.

Lib/test/test_zipfile.py
Lib/zipfile.py
Misc/NEWS

index 6bf5c2f3189b7b63a67463d5363f5921af024d14..604e57bfa9950f24634ef8718f13421a9df948e3 100644 (file)
@@ -1157,6 +1157,21 @@ class OtherTests(unittest.TestCase):
         self.assertRaises(ValueError,
                           zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0))
 
+    def test_zipfile_with_short_extra_field(self):
+        """If an extra field in the header is less than 4 bytes, skip it."""
+        zipdata = (
+            b'PK\x03\x04\x14\x00\x00\x00\x00\x00\x93\x9b\xad@\x8b\x9e'
+            b'\xd9\xd3\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x03\x00ab'
+            b'c\x00\x00\x00APK\x01\x02\x14\x03\x14\x00\x00\x00\x00'
+            b'\x00\x93\x9b\xad@\x8b\x9e\xd9\xd3\x01\x00\x00\x00\x01\x00\x00'
+            b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00'
+            b'\x00\x00\x00abc\x00\x00PK\x05\x06\x00\x00\x00\x00'
+            b'\x01\x00\x01\x003\x00\x00\x00%\x00\x00\x00\x00\x00'
+        )
+        with zipfile.ZipFile(io.BytesIO(zipdata), 'r') as zipf:
+            # testzip returns the name of the first corrupt file, or None
+            self.assertIsNone(zipf.testzip())
+
     def tearDown(self):
         unlink(TESTFN)
         unlink(TESTFN2)
index 46328f5323f3eabee19f98f5a2ebe9cc0c59d10d..a0beae2a60562907669e6ffc710ba88423e03e0e 100644 (file)
@@ -384,7 +384,7 @@ class ZipInfo (object):
         # Try to decode the extra field.
         extra = self.extra
         unpack = struct.unpack
-        while extra:
+        while len(extra) >= 4:
             tp, ln = unpack('<HH', extra[:4])
             if tp == 1:
                 if ln >= 24:
index 293b2ef82b59a90013810c7ae03df56937fea7ff..3538f88cc43ad7c1d2eb2fd05a829ac3c3392b05 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,11 @@ Core and Builtins
 Library
 -------
 
+- Issue #14315: The zipfile module now ignores extra fields in the central
+  directory that are too short to be parsed instead of letting a struct.unpack
+  error bubble up as this "bad data" appears in many real world zip files in
+  the wild and is ignored by other zip tools.
+
 - Issue #21402: Tkinter.ttk now works when default root window is not set.
 
 - Issue #10203: sqlite3.Row now truly supports sequence protocol.  In particulr