Skip to content

Commit 62efd2c

Browse files
committed
gh-153679: Raise ZipImportError for an invalid UTF-8 file name in zipimport
zipimport.zipimporter() is documented to raise ZipImportError for an invalid archive, but _read_directory() leaked a raw UnicodeDecodeError when a central directory entry set the UTF-8 file name flag (0x800) but stored bytes that are not valid UTF-8: the UTF-8 branch called name.decode() unguarded, while the sibling non-UTF-8 branch already handles UnicodeDecodeError. Guard the UTF-8 decode and raise ZipImportError instead.
1 parent ed71655 commit 62efd2c

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

Lib/test/test_zipimport.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,24 @@ def testNotZipFile(self):
10741074
fp.close()
10751075
self.assertZipFailure(TESTMOD)
10761076

1077+
def testInvalidUTF8FileName(self):
1078+
# A central directory entry that sets the UTF-8 file name flag (0x800)
1079+
# but stores bytes that are not valid UTF-8 must raise ZipImportError
1080+
# rather than leaking a UnicodeDecodeError.
1081+
UTF8_FLAG = 0x800
1082+
name = b'\xff\xfe\xff'
1083+
cdh = b'PK\x01\x02' + struct.pack(
1084+
'<HHHHHHIIIHHHHHII',
1085+
20, 20, UTF8_FLAG, 0, 0, 0, 0, 50, 100,
1086+
len(name), 0, 0, 0, 0, 0, 0)
1087+
cdh += name
1088+
eocd = b'PK\x05\x06' + struct.pack(
1089+
'<HHHHIIH', 0, 0, 1, 1, len(cdh), 0, 0)
1090+
os_helper.unlink(TESTMOD)
1091+
with open(TESTMOD, 'wb') as fp:
1092+
fp.write(cdh + eocd)
1093+
self.assertZipFailure(TESTMOD)
1094+
10771095
# XXX: disabled until this works on Big-endian machines
10781096
def _testBogusZipFile(self):
10791097
os_helper.unlink(TESTMOD)

Lib/zipimport.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,12 @@ def _read_directory(archive):
427427

428428
if flags & 0x800:
429429
# UTF-8 file names extension
430-
name = name.decode()
430+
try:
431+
name = name.decode()
432+
except UnicodeDecodeError:
433+
raise ZipImportError(
434+
f"can't decode file name in Zip file: {archive!r}",
435+
path=archive)
431436
else:
432437
# Historical ZIP filename encoding
433438
try:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:class:`zipimport.zipimporter` now raises :exc:`zipimport.ZipImportError`
2+
instead of :exc:`UnicodeDecodeError` when a central directory entry sets the
3+
UTF-8 file name flag but stores a file name that is not valid UTF-8.
4+
Patch by tonghuaroot.

0 commit comments

Comments
 (0)