Skip to content

Commit 631fdee

Browse files
orenmnserhiy-storchaka
authored andcommitted
bpo-31291: Fixed an assertion failure in zipimport.zipimporter.get_data() (#3226)
if pathname.replace('/', '\\') returns non-string.
1 parent 006617f commit 631fdee

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

Lib/test/test_zipimport.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,23 @@ def testGetData(self):
521521
z.close()
522522
os.remove(TEMP_ZIP)
523523

524+
def test_issue31291(self):
525+
# There shouldn't be an assertion failure in get_data().
526+
class FunnyStr(str):
527+
def replace(self, old, new):
528+
return 42
529+
z = ZipFile(TEMP_ZIP, "w")
530+
try:
531+
name = "test31291.dat"
532+
data = b'foo'
533+
z.writestr(name, data)
534+
z.close()
535+
zi = zipimport.zipimporter(TEMP_ZIP)
536+
self.assertEqual(data, zi.get_data(FunnyStr(name)))
537+
finally:
538+
z.close()
539+
os.remove(TEMP_ZIP)
540+
524541
def testImporterAttr(self):
525542
src = """if 1: # indent hack
526543
def get_file():
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix an assertion failure in `zipimport.zipimporter.get_data` on Windows,
2+
when the return value of ``pathname.replace('/','\\')`` isn't a string.
3+
Patch by Oren Milman.

Modules/zipimport.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,8 @@ zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path)
651651
Py_ssize_t path_start, path_len, len;
652652

653653
#ifdef ALTSEP
654-
path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
654+
path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace,
655+
"OCC", path, ALTSEP, SEP);
655656
if (!path)
656657
return NULL;
657658
#else

0 commit comments

Comments
 (0)