zipimport.zipimporter raises UnicodeDecodeError instead of ZipImportError for an invalid UTF-8 file name
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug description
zipimport.zipimporter() is documented to raise zipimport.ZipImportError
for an invalid archive, but it leaks a raw UnicodeDecodeError when a central
directory entry sets the UTF-8 file name flag (0x800) yet stores bytes that
are not valid UTF-8.
In _read_directory() (Lib/zipimport.py) the UTF-8 branch does
name = name.decode() with no error handling, whereas the sibling non-UTF-8
branch already guards UnicodeDecodeError and falls back to latin-1/cp437.
Every other corruption path in the function raises ZipImportError.
>>> import struct, zipimport
>>> name = b'\xff\xfe\xff'
>>> cdh = b'PK\x01\x02' + struct.pack('<HHHHHHIIIHHHHHII', 20,20,0x800,0,0,0,0,50,100,len(name),0,0,0,0,0,0) + name
>>> eocd = b'PK\x05\x06' + struct.pack('<HHHHIIH', 0,0,1,1,len(cdh),0,0)
>>> _ = open('bad.zip','wb').write(cdh + eocd)
>>> zipimport.zipimporter('bad.zip')
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Expected: zipimport.ZipImportError.
CPython versions tested on
3.13, 3.14, 3.15
Operating systems tested on
Linux, macOS
Linked PRs
- gh-153680
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Lib/zipimport.py at _read_directory() and reproduce the malformed archive case described in the issue. Done means an invalid UTF-8 filename causes zipimport.zipimporter() to raise ZipImportError rather than UnicodeDecodeError; gh-153680 is already linked.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100