summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_zipimport.py17
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2017-09-27-09-30-03.bpo-31602.MtgLCn.rst2
-rw-r--r--Modules/zipimport.c8
3 files changed, 27 insertions, 0 deletions
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
index daa5138751..4a934ff6cb 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -17,6 +17,10 @@ import doctest
import inspect
import io
from traceback import extract_tb, extract_stack, print_tb
+try:
+ import zlib
+except ImportError:
+ zlib = None
test_src = """\
def get_name():
@@ -669,6 +673,19 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
class CompressedZipImportTestCase(UncompressedZipImportTestCase):
compression = ZIP_DEFLATED
+ @support.cpython_only
+ def test_issue31602(self):
+ # There shouldn't be an assertion failure in zipimporter.get_source()
+ # in case of a bad zlib.decompress().
+ def bad_decompress(*args):
+ return None
+ with ZipFile(TEMP_ZIP, 'w') as zip_file:
+ self.addCleanup(support.unlink, TEMP_ZIP)
+ zip_file.writestr('bar.py', b'print("hello world")', ZIP_DEFLATED)
+ zi = zipimport.zipimporter(TEMP_ZIP)
+ with support.swap_attr(zlib, 'decompress', bad_decompress):
+ self.assertRaises(TypeError, zi.get_source, 'bar')
+
class BadFileZipImportTestCase(unittest.TestCase):
def assertZipFailure(self, filename):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-09-27-09-30-03.bpo-31602.MtgLCn.rst b/Misc/NEWS.d/next/Core and Builtins/2017-09-27-09-30-03.bpo-31602.MtgLCn.rst
new file mode 100644
index 0000000000..3a6320911e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2017-09-27-09-30-03.bpo-31602.MtgLCn.rst
@@ -0,0 +1,2 @@
+Fix an assertion failure in `zipimporter.get_source()` in case of a bad
+`zlib.decompress()`. Patch by Oren Milman.
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 141ada5adc..493e6db394 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -1236,6 +1236,14 @@ get_data(PyObject *archive, PyObject *toc_entry)
data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Py_DECREF(decompress);
Py_DECREF(raw_data);
+ if (data != NULL && !PyBytes_Check(data)) {
+ PyErr_Format(PyExc_TypeError,
+ "zlib.decompress() must return a bytes object, not "
+ "%.200s",
+ Py_TYPE(data)->tp_name);
+ Py_DECREF(data);
+ return NULL;
+ }
return data;
eof_error: