[issue14313] zipfile should raise an exception for unsupported compression methods

Serhiy Storchaka report at bugs.python.org
Wed May 16 22:15:55 CEST 2012


Serhiy Storchaka <storchaka at gmail.com> added the comment:

> I still like NotImplementedError more than RuntimeError, though.

Well. here are patches for Python 3.2 and 2.7 (backported changeset
596b0eaeece8 + part of changeset fccdcd83708a).

----------
Added file: http://bugs.python.org/file25618/zipfile_unsupported_compression-3.2.patch
Added file: http://bugs.python.org/file25619/zipfile_unsupported_compression-2.7.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue14313>
_______________________________________
-------------- next part --------------
diff -r 13900edf13be Lib/test/test_zipfile.py
--- a/Lib/test/test_zipfile.py	Wed May 16 15:01:40 2012 +0200
+++ b/Lib/test/test_zipfile.py	Wed May 16 23:00:01 2012 +0300
@@ -922,6 +922,17 @@
         caught."""
         self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
 
+    def test_unsupported_compression(self):
+        # data is declared as shrunk, but actually deflated
+        data = (b'PK\x03\x04.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00'
+        b'\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00x\x03\x00PK\x01'
+        b'\x02.\x03.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00\x00\x02\x00\x00'
+        b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        b'\x80\x01\x00\x00\x00\x00xPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00'
+        b'/\x00\x00\x00!\x00\x00\x00\x00\x00')
+        with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+            self.assertRaises(NotImplementedError, zipf.open, 'x')
+
     def test_null_byte_in_filename(self):
         """Check that a filename containing a null byte is properly
         terminated."""
diff -r 13900edf13be Lib/zipfile.py
--- a/Lib/zipfile.py	Wed May 16 15:01:40 2012 +0200
+++ b/Lib/zipfile.py	Wed May 16 23:00:01 2012 +0300
@@ -461,6 +461,28 @@
         self._UpdateKeys(c)
         return c
 
+
+compressor_names = {
+    0: 'store',
+    1: 'shrink',
+    2: 'reduce',
+    3: 'reduce',
+    4: 'reduce',
+    5: 'reduce',
+    6: 'implode',
+    7: 'tokenize',
+    8: 'deflate',
+    9: 'deflate64',
+    10: 'implode',
+    12: 'bzip2',
+    14: 'lzma',
+    18: 'terse',
+    19: 'lz77',
+    97: 'wavpack',
+    98: 'ppmd',
+}
+
+
 class ZipExtFile(io.BufferedIOBase):
     """File-like object for reading an archive member.
        Is returned by ZipFile.open().
@@ -487,6 +509,12 @@
 
         if self._compress_type == ZIP_DEFLATED:
             self._decompressor = zlib.decompressobj(-15)
+        elif self._compress_type != ZIP_STORED:
+            descr = compressor_names.get(self._compress_type)
+            if descr:
+                raise NotImplementedError("compression type %d (%s)" % (self._compress_type, descr))
+            else:
+                raise NotImplementedError("compression type %d" % (self._compress_type,))
         self._unconsumed = b''
 
         self._readbuffer = b''
-------------- next part --------------
diff -r e957b93571a8 Lib/test/test_zipfile.py
--- a/Lib/test/test_zipfile.py	Wed May 16 15:01:40 2012 +0200
+++ b/Lib/test/test_zipfile.py	Wed May 16 23:03:30 2012 +0300
@@ -859,6 +859,17 @@
         caught."""
         self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
 
+    def test_unsupported_compression(self):
+        # data is declared as shrunk, but actually deflated
+        data = (b'PK\x03\x04.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00'
+        b'\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00x\x03\x00PK\x01'
+        b'\x02.\x03.\x00\x00\x00\x01\x00\xe4C\xa1@\x00\x00\x00\x00\x02\x00\x00'
+        b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        b'\x80\x01\x00\x00\x00\x00xPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00'
+        b'/\x00\x00\x00!\x00\x00\x00\x00\x00')
+        with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+            self.assertRaises(NotImplementedError, zipf.open, 'x')
+
     def test_null_byte_in_filename(self):
         """Check that a filename containing a null byte is properly
         terminated."""
diff -r e957b93571a8 Lib/zipfile.py
--- a/Lib/zipfile.py	Wed May 16 15:01:40 2012 +0200
+++ b/Lib/zipfile.py	Wed May 16 23:03:30 2012 +0300
@@ -461,6 +461,28 @@
         self._UpdateKeys(c)
         return c
 
+
+compressor_names = {
+    0: 'store',
+    1: 'shrink',
+    2: 'reduce',
+    3: 'reduce',
+    4: 'reduce',
+    5: 'reduce',
+    6: 'implode',
+    7: 'tokenize',
+    8: 'deflate',
+    9: 'deflate64',
+    10: 'implode',
+    12: 'bzip2',
+    14: 'lzma',
+    18: 'terse',
+    19: 'lz77',
+    97: 'wavpack',
+    98: 'ppmd',
+}
+
+
 class ZipExtFile(io.BufferedIOBase):
     """File-like object for reading an archive member.
        Is returned by ZipFile.open().
@@ -485,6 +507,12 @@
 
         if self._compress_type == ZIP_DEFLATED:
             self._decompressor = zlib.decompressobj(-15)
+        elif self._compress_type != ZIP_STORED:
+            descr = compressor_names.get(self._compress_type)
+            if descr:
+                raise NotImplementedError("compression type %d (%s)" % (self._compress_type, descr))
+            else:
+                raise NotImplementedError("compression type %d" % (self._compress_type,))
         self._unconsumed = ''
 
         self._readbuffer = ''


More information about the Python-bugs-list mailing list