From db60a5bfa5d5f7a6f1538cc1fe76f0fda57b524e Mon Sep 17 00:00:00 2001 From: Oren Milman Date: Fri, 20 Oct 2017 23:42:35 +0300 Subject: [PATCH] bpo-31781: Prevent crashes when calling methods of an uninitialized zipimport.zipimporter object (GH-3986) --- Lib/test/test_zipimport.py | 14 ++++++++++++++ .../2017-10-13-20-01-47.bpo-31781.cXE9SM.rst | 2 ++ Modules/zipimport.c | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-10-13-20-01-47.bpo-31781.cXE9SM.rst diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 4a934ff6cb..67ca39b806 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -668,6 +668,20 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): with self.assertWarns(DeprecationWarning): zipimport.zipimporter(memoryview(os.fsencode(filename))) + @support.cpython_only + def testUninitializedZipimporter(self): + # The interpreter shouldn't crash in case of calling methods of an + # uninitialized zipimport.zipimporter object. + zi = zipimport.zipimporter.__new__(zipimport.zipimporter) + self.assertRaises(ValueError, zi.find_module, 'foo') + self.assertRaises(ValueError, zi.find_loader, 'foo') + self.assertRaises(ValueError, zi.load_module, 'foo') + self.assertRaises(ValueError, zi.get_filename, 'foo') + self.assertRaises(ValueError, zi.is_package, 'foo') + self.assertRaises(ValueError, zi.get_data, 'foo') + self.assertRaises(ValueError, zi.get_code, 'foo') + self.assertRaises(ValueError, zi.get_source, 'foo') + @support.requires_zlib class CompressedZipImportTestCase(UncompressedZipImportTestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-13-20-01-47.bpo-31781.cXE9SM.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-13-20-01-47.bpo-31781.cXE9SM.rst new file mode 100644 index 0000000000..79898cfd3d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-13-20-01-47.bpo-31781.cXE9SM.rst @@ -0,0 +1,2 @@ +Prevent crashes when calling methods of an uninitialized +``zipimport.zipimporter`` object. Patch by Oren Milman. diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 895cd800fc..009480bac5 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -322,6 +322,12 @@ get_module_info(ZipImporter *self, PyObject *fullname) PyObject *path, *fullpath, *item; struct st_zip_searchorder *zso; + if (self->prefix == NULL) { + PyErr_SetString(PyExc_ValueError, + "zipimporter.__init__() wasn't called"); + return MI_ERROR; + } + subname = get_subname(fullname); if (subname == NULL) return MI_ERROR; @@ -652,6 +658,12 @@ zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path) PyObject *toc_entry; Py_ssize_t path_start, path_len, len; + if (self->archive == NULL) { + PyErr_SetString(PyExc_ValueError, + "zipimporter.__init__() wasn't called"); + return NULL; + } + #ifdef ALTSEP path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace, "OCC", path, ALTSEP, SEP); @@ -1476,6 +1488,12 @@ get_module_code(ZipImporter *self, PyObject *fullname, PyObject *path, *fullpath = NULL; struct st_zip_searchorder *zso; + if (self->prefix == NULL) { + PyErr_SetString(PyExc_ValueError, + "zipimporter.__init__() wasn't called"); + return NULL; + } + subname = get_subname(fullname); if (subname == NULL) return NULL; -- 2.40.0