Repository navigation
zipfile can't extract file: file name in directory and header differ #51088
Copy link
Copy link
Open
Labels
3.7 (EOL)end of lifeend of lifeOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
| BPO | 6839 |
|---|---|
| Nosy | @birkenfeld, @terryjreedy, @gpshead, @ronaldoussoren, @amauryfa, @ncoghlan, @berkerpeksag, @JimJJewett, @serhiy-storchaka, @MorganRamsay |
| PRs | |
| Files |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2009-09-04.19:56:49.966>
labels = ['3.7', 'type-bug', 'library', 'OS-windows']
title = "zipfile can't extract file"
updated_at = <Date 2019-06-18.21:36:54.889>
user = 'https://bugs.python.org/NewerCookie'bugs.python.org fields:
activity = <Date 2019-06-18.21:36:54.889>
actor = 'python-dev'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)', 'Windows']
creation = <Date 2009-09-04.19:56:49.966>
creator = 'NewerCookie'
dependencies = []
files = ['14832', '14934', '35115', '35117', '35120']
hgrepos = []
issue_num = 6839
keywords = ['patch']
message_count = 61.0
messages = ['92265', '92297', '92309', '92326', '92330', '92335', '92516', '92874', '116384', '116385', '200165', '201842', '208970', '208973', '208975', '208982', '208983', '208985', '208987', '209023', '211562', '217533', '217546', '217551', '217554', '217556', '217558', '217561', '217569', '217570', '217571', '217572', '217573', '217574', '217575', '217576', '217578', '217616', '217624', '217625', '217627', '217634', '217635', '217636', '217638', '217641', '217642', '217643', '217647', '217648', '217659', '217660', '217661', '217743', '217753', '217754', '217756', '217778', '217932', '217933', '345999']
nosy_count = 15.0
nosy_names = ['georg.brandl', 'terry.reedy', 'gregory.p.smith', 'ronaldoussoren', 'amaury.forgeotdarc', 'ncoghlan', 'NewerCookie', 'chuck', 'francismb', 'berker.peksag', 'Jim.Jewett', 'serhiy.storchaka', 'apolkosnik', 'Sean Goodwin', 'MorganRamsay']
pr_nums = ['14212']
priority = 'normal'
resolution = None
stage = 'patch review'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue6839'
versions = ['Python 2.7', 'Python 3.4', 'Python 3.5', 'Python 3.6', 'Python 3.7']Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.7 (EOL)end of lifeend of lifeOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Projects
- StatusShow more project fieldsNo status
Activity
NewerCookie commentedon Sep 4, 2009
The following exception occured when I tried to extract on Windows.
"zipfile.BadZipfile: File name in directory "test\test2.txt" and header
"test/test2.txt" differ."
It seems like problem about slash.
I tested using by zipfile Revision 72893.
NewerCookie commentedon Sep 6, 2009
P.S
I tested extraction by using 7-zip.
It works fine.
ronaldoussoren commentedon Sep 6, 2009
The zipfile is technically incorrect, the zipfile specification prescribes
that all filenames use '/' as the directory separator.
Even without that caveat the file is corrupt because the zipfile directory
header and the per-file header don't agree on the name of the file.
That said: IMHO the current code in zipfile.ZipFile.open is too strict, it
shouldn't raise an error when the two names aren't exactly the same
because there are valid reasons for them to be different (such as renaming
a file in the zipfile without rewriting the entire zipfile).
alanmcintyre commentedon Sep 6, 2009
FileRoller doesn't complain about the mismatched slashes either. Where
did the ZIP come from, by the way? I seem to recall that there have
been other instances in which ZIP applications were more "forgiving"
than the zipfile module. How far should zipfile go in bending the
interpretation of the ZIP standard?
As far as the renaming goes, it seems the standard says the header name
should be used if the two names are different. If nobody else has time
to make a patch and tests I can take a stab at it in the next few days.
ronaldoussoren commentedon Sep 6, 2009
alan: I don't quite understand which filename you want to use when the
name in the per-file header and the central directory don't match.
Where in the standard is this prescribed? I couldn't find anything in
the PKWare zipfile appnote [1]
My preference would be to use the central directory as the canonical
value because scanning the entire zipfile to read the per-file header
would give a significant overhead. This might not be very noticable with
small zipfiles, but I regularly use zipfiles with over 100K files in
them in those files a scan of the zipfile is prohibitively expensive.
Furthermore, when the two are different the most reasonably explaination
is that an in-place edit of the zipfile changed the directory without
rewriting the entire zipfile (just like you can "delete" files from a
zipfile by dumping them from the directory rather than completely
rewriting the entire archive)
[1]
APPNOTE.TXT - .ZIP File Format Specification Version: 6.3.2
Revised: September 28, 2007
Copyright (c) 1989 - 2007 PKWARE Inc., All Rights Reserved.
alanmcintyre commentedon Sep 6, 2009
Sorry about the confusion--I think I confused myself by looking at the
bit about CRC checksums in the "Info-ZIP Unicode Path Extra Field"
section before I posted. I meant to say that the central directory name
looks preferred over the per-file header.
n section J, under "file name (Variable)" there's a bit that says:
"If input came from standard input, there is no file name field. If
encrypting the central directory and general purpose bit flag 13 is set
indicating masking, the file name stored in the Local Header will not be
the actual file name. A masking value consisting of a unique
hexadecimal value will be stored."
So in these cases the central directory name has to be used. And, as
you pointed out, some operations like "deleting" a member from the
archive are implemented by editing the central directory, so it would
seem that the central directory should be used if there's a conflict.
terryjreedy commentedon Sep 11, 2009
In the case at issue, the file name is the same (contrary to the error
message). The two representations of the *path* are different, but
equivalent. There is no ambiguity: the file should be put in directory
'test' and named 'test2.txt'. So I think zipfile should do what 7zip
does and do just that.
An actual filename difference might be argued differently.
chuck commentedon Sep 19, 2009
I added a patch to replace back slashes by forward slashes in three
places, only one if them actually relevant to the errors in the attached
.zip file.
I kept the exception for mismatching filenames, but if you think it is
appropriate to remove it I could do that as well.
amauryfa commentedon Sep 14, 2010
I agree with the change, but the code should be factorized in a function (normalize_filename for example)
ronaldoussoren commentedon Sep 14, 2010
I'd prefer if the code no longer checked if the filename in the directory matches the name in the per-file header.
The reason of that is that the two don't have to match: it is relatively cheap to rename a file in the zipfile by rewriting the directory while rewriting the entire zipfile can be pretty expensive when zipfiles get large.
It's probably worthwhile to test what other zipfile tools do in the respect (e.g., create a zipfile where the filename in the header doesn't match the name in the directory and extract that zip using a number of popular tools).
(I have a slightly odd perspective on this because I regularly deal with zipfiles containing over 100K files and over 10GByte of data).
46 remaining items
ethanfurman commentedon May 2, 2014
Adam Polkasnik said:
--------------------
That doesn't make sense. If an exception was "stopping the whole extraction process" then extraction was not working fine.
Questions:
Are the names with '\' in them in the central directory, or the per-file header?
If in the central directory (which is the name we are going to use, yes?) how do
we tell if the '\' should be a '/' or an escape? (such as '\t')
apolkosnik commentedon May 2, 2014
Ethan,
I'd refer you to msg92309...
And
When testing with WinZip it looks like this:
No errors detected in compressed data of C:\Downloads\test.zip.
Testing ...
Testing test\ OK
Testing test\test2.txt OK
Testing test1.txt OK
So, based on that everything is already converted to forward slashes for the extraction.
ethanfurman commentedon May 5, 2014
Ah, so when you (Adam) said "extraction works fine", what you meant was "extraction works fine *in other programs*". Okay.
apolkosnik commentedon May 5, 2014
Both. Other programs, and in python scripts when raise() is removed in zipfile.py. Unless your results are different.
MorganRamsay commentedon Jun 18, 2019
The encoding test in ZipFile.open() is highly opinionated and has no purpose beyond itself. Testing for encoding issues should be done outside this library in the user's own code.
Using the 3.7.2 version of ZipFile, this is my proposal:
https://gist.github.com/MorganRamsay/696e89450e0f172c16ac8dfc016eb79f/revisions?diff=unified
Currently, I'm subclassing ZipFile with this patch and I've had no issues with extracting thousands of different ZIP files on Windows. I can't attest to this solution's applicability on other platforms.
thatch commentedon May 20, 2025
I think the core of this bug is that we don't do the "/"-normalization in
cpython/Lib/zipfile/__init__.py
Lines 1733 to 1742 in 6b73502
Would fixing that be sufficient?
thatch commentedon May 20, 2025
I'm also not sure this looks at the unicode filename extra, and probably should. This is a case where we could refactor them to use the same code...
serhiy-storchaka commentedon May 18, 2026
There is a good reason to keep the exception. This protects us from the simplest kind of zipbombs. If remove it, then the attacker can create a ZIP file containing one large file and many entries with different files in the central directory referring the same local header. Both the size and the number of entries under threshold. Extracting such archive will lead to occupying disk space equal to multiplication of the single file size and the number of entries.
Normalization of only slashes on Windows before the check will protect us.
Normalization of slashes on Posix platforms will be a breaking change. Backslash has no special meaning in the path, it can be a part of normal file name. So this solution will not help on Posix.
[-]zipfile can't extract file[/-][+]zipfile can't extract file: file name in directory and header differ[/+]MorganRamsay commentedon May 19, 2026
We have two goals then:
Path normalization works for Windows users, but not so much for users on other platforms.
What do you think about offset validation?