https://github.com/python/cpython/commit/095a421b1606ee27e00a5d9d253b05a9f0c... commit: 095a421b1606ee27e00a5d9d253b05a9f0cfadb8 branch: 3.6 author: Oren Milman <orenmn@gmail.com> committer: Serhiy Storchaka <storchaka@gmail.com> date: 2017-08-30T14:08:39+03:00 summary: [3.6] bpo-31291: Fixed an assertion failure in zipimport.zipimporter.get_data() (GH-3226) (#3243) if pathname.replace('/', '\\') returns non-string. (cherry picked from commit 631fdee6e61b4ba8ce800f827fecdd536bfb04f3) files: A Misc/NEWS.d/next/Core and Builtins/2017-08-28-11-51-29.bpo-31291.t8QggK.rst M Lib/test/test_zipimport.py M Modules/zipimport.c diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 7ddbc509f9b..daa5138751b 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -521,6 +521,23 @@ def testGetData(self): z.close() os.remove(TEMP_ZIP) + def test_issue31291(self): + # There shouldn't be an assertion failure in get_data(). + class FunnyStr(str): + def replace(self, old, new): + return 42 + z = ZipFile(TEMP_ZIP, "w") + try: + name = "test31291.dat" + data = b'foo' + z.writestr(name, data) + z.close() + zi = zipimport.zipimporter(TEMP_ZIP) + self.assertEqual(data, zi.get_data(FunnyStr(name))) + finally: + z.close() + os.remove(TEMP_ZIP) + def testImporterAttr(self): src = """if 1: # indent hack def get_file(): diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-08-28-11-51-29.bpo-31291.t8QggK.rst b/Misc/NEWS.d/next/Core and Builtins/2017-08-28-11-51-29.bpo-31291.t8QggK.rst new file mode 100644 index 00000000000..0576785c7df --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-08-28-11-51-29.bpo-31291.t8QggK.rst @@ -0,0 +1,3 @@ +Fix an assertion failure in `zipimport.zipimporter.get_data` on Windows, +when the return value of ``pathname.replace('/','\\')`` isn't a string. +Patch by Oren Milman. diff --git a/Modules/zipimport.c b/Modules/zipimport.c index cccc033d2d9..5bf31cc0605 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -580,7 +580,8 @@ zipimporter_get_data(PyObject *obj, PyObject *args) return NULL; #ifdef ALTSEP - path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP); + path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace, + "OCC", path, ALTSEP, SEP); if (!path) return NULL; #else