Issue 30213: ZipFile from 'a'ppend-mode file generates invalid zip (original) (raw)
I may be misunderstanding file modes or the zipfile
library, but
from zipfile import ZipFile
ZipFile(open('a.zip', 'ab'), 'a').writestr('f.txt', 'z')
unexpectedly creates an invalid zip file. 7zip is able to open and show the file list, but files inside look empty, and Windows simply says it's invalid.
Changing the file mode from ab
to wb+
fixes the problem, but truncates the file, and rb+
doesn't create the file. Calling close
on both the open
and ZipFile
doesn't help either. Using ZipFile(...).open
instead of writestr
has the same problem.
I could only reproduce this on [Windows 10, Python 3.6.1, 64 bit]. The zip file was proper on [Windows 10, Python 3.3.5, 32 bit], [Windows 10 Bash, Python 3.4.3, 64 bit], and [FreeBSD, Python 3.5.3, 64 bit].
This is my first bug report, so forgive me if I made any mistakes.
I'm not sure this is a duplicate of . That issue includes random data at the start of the file, while this issue uses the 'ab' mode solely for a creating the file if it doesn't exist (and thus is either empty or already a valid zip file). It's not clear to me why 'wb' should work but not 'ab' if the file was empty/missing to begin with.
[Windows 10, Python 3.6.3, 64 bit] still has the same problem.
Here's a more complete test case, starting with no existing files:
from zipfile import ZipFile
# Append mode: v
with open('file.zip', 'ab') as f:
with ZipFile(f, 'a') as zip:
zip.writestr('file.txt', 'contents')
with open('file.zip', 'rb') as f:
with ZipFile(f, 'r') as zip:
print(zip.read('file.txt'))
# Fails with "zipfile.BadZipFile: Bad magic number for file header"
# Write mode: v
with open('file.zip', 'wb') as f:
with ZipFile(f, 'a') as zip:
zip.writestr('file.txt', 'contents')
with open('file.zip', 'rb') as f:
with ZipFile(f, 'r') as zip:
print(zip.read('file.txt'))
# Works.