Repository navigation
zipfile may raise EOFError too early #101911
Copy link
Copy link
Closed
Labels
3.12only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-IOtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
I am using the ziprofs.py on Ubuntu. When I run this in Python-3.11.1 it works very well. With Python
3.12.0a4+ there are problems. In both cases, the same ziprofs.py and fuse.py files are used.
The only difference is the python version.
Unfortunately, I was unable to demonstrate problems using Linux
commands like wc, gzip, md5sum. Sofar, I only see this problem with proprietary closed source software.
It appears with different files.
When this EOFError occurs in
def read(self,path,size,offset,fh) of ziprofs.py
then the value of parameter "size" was 131072 and that of "offset" was 75755520.
The size of the file is 525537280 Bytes.
Strikingly, the low value of offset suggests, that the EOF is not yet riched.
Many thanks
C
File "/local/filesystem/git/ZipROFS/ziprofs.py", line 258, in read
return f.read(size)
^^^^^^^^^^^^
File "/local/python/2023_02_cpython-main/Lib/zipfile/__init__.py", line 948, in read
data = self._read1(n)
^^^^^^^^^^^^^^
File "/local/python/2023_02_cpython-main/Lib/zipfile/__init__.py", line 1018, in _read1
data = self._read2(n)
^^^^^^^^^^^^^^
File "/local/python/2023_02_cpython-main/Lib/zipfile/__init__.py", line 1052, in _read2
raise EOFError
EOFError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/local/filesystem/git/ZipROFS/fuse.py", line 744, in _wrapper
return func(*args, **kwargs) or 0
^^^^^^^^^^^^^^^^^^^^^
File "/local/filesystem/git/ZipROFS/fuse.py", line 860, in read
ret = self.operations('read', self._decode_optional_path(path), size, offset, fh)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/local/filesystem/git/ZipROFS/ziprofs.py", line 127, in __call__
return super().__call__(op, self.root + path, *args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/local/filesystem/git/ZipROFS/fuse.py", line 1097, in __call__
return getattr(self, op)(*args)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/local/filesystem/git/ZipROFS/ziprofs.py", line 261, in read
exit(999)
File "<frozen _sitebuiltins>", line 26, in __call__
SystemExit: 999Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.12only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-IOtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Projects
- StatusShow more project fieldsDone
Activity
arhadthedev commentedon Feb 15, 2023
@serhiy-storchaka, @gpshead (as zipfile experts that were seen this week)
christophgil commentedon Feb 15, 2023
It was working with erlend-aasland committed on Jul 22, 2022 f9b3706 and before
and failed since @sobolevn sobolevn committed on Oct 4, 2022 4f380db
This was validated by
git clone https://github.com/python/cpython.git
git checkout 4f380db
rm python; find . -name '*.o' -delete; ./configure; sed -i 's| -O3 | |1' Makefile && make
However without clone I see a carry over from previous checkouts and results are different depending what was checked out before.
Is there a more efficient way to build a python for a particular checkout?
Then I could further narrow it down.
sobolevn commentedon Feb 15, 2023
Take a look at https://git-scm.com/docs/git-bisect
christophgil commentedon Feb 16, 2023
christophgil commentedon Feb 18, 2023
christophgil commentedon Feb 20, 2023
I found the other commit since when occasional, inconstant problems occur when using Ziprofs:
I contacted the commiter via Email. The problem cannot be reproduced with simple shell commands.
It occurs eventually when processing a large number of files by a prorietory software.
commit 26a162b BAD
Author: Jan Wolski jan@wolski.fi
Date: Sun May 15 17:49:19 2022 +0300
gh-89668: Optimize ZipFile file header processing algorithm to avoid unneeded IO(gh-25966)
commit 90e7230 GOOD
Author: Victor Stinner vstinner@python.org
Date: Sun May 15 11:19:52 2022 +0200
gh-92781: Avoid mixing declarations and code in C API (#92783)
Avoid mixing declarations and code in the C API to fix the compiler
warning: "ISO C90 forbids mixed declarations and code"
[-Werror=declaration-after-statement].
christophgil commentedon Feb 20, 2023
christophgil commentedon Feb 23, 2023
I found out that the issues are very likely due to f.seek(offset).
A multithreaded application is loading zip entries via ziprofs
and causes above described errors.
By setting the thread number to one, the errors are gone.
Looking at the function
def read(self, path, size, offset, fh)
in ziprofs, the seek offset is jumping forth and back,
when several threads are reading from the same zip.
When only one thread is reading at a time,
the zip entry is read nicely sequentially.
jpruciak commentedon Mar 15, 2023
zipfile is not threadsafe, that's nothing new
that probably means that locks in ziprofs are not working as intended
ericvsmith commentedon Mar 15, 2023
This looks like either a problem with ziprofs, a problem with user code, and/a feature request for thread safe zipfile. So I’m going to close this.
If you can reproduce a problem with single threaded code and just zipfile, then please reopen this and attach the reproducer.
If you want to suggest a thread safe zipfile, then the best thing to do is start a discussion on discuss.python.org.
mcepl commentedon Mar 31, 2023
I think I can reproduce this with epy (current master, commit c7a87f3), and Python 3.10.10 (from openSUSE/Tumbleweed packages):
It doesn’t happen with all EPubs, but quite often (like 50:50?).
(Yes, I checked with other EPub readers that Twenty Four Years Later-ao3_29298975.epub (renamed to
*.zipbecause the GitHub rules for the attachment naming) is correct EPub).AFAIK, epy is rather simple, certainly single-threaded, application.
thatch commentedon May 20, 2025
I don't think anything looks that weird about the zip file, but do note the current version of epy-reader does use multiprocessing and has several comments that appear to be observed issues decompressing with multiprocessing. Can you try with that turned off?
danifus commentedon May 20, 2025
This commited fix #127856 resolved a couple of bugs with regards to concurrent reading of files in a zip. If it is related to multiprocesssing, it may be worth checking if this bug still exists in newer versions of python
mcepl commentedon May 21, 2025
(Un)fortunately,
epygot fixed in wustho/epy@ee3d693, so it doesn’t crash any more.Ragzouken commentedon Sep 22, 2025
I'm pretty sure I'm encountering this error in version 3.12.0: I try to seek a file in an uncompressed zip and then read, raising an EOFError, if I catch that error, do some more seeking and reading from the beginning of the file, then try my original seek and read again, it doesn't fail. This is happening reliably every single time for this script and zip file, at least as I am writing this message.
I installed version 3.13.7 in parallel and ran the same combination, and everything works correctly every time. Then going back to version 3.12.0 it continues to fail reliably.
Ragzouken commentedon Sep 22, 2025
It seems I can at least workaround the bug by seeking to 0 and reading some data first.
[-]Too early EOFError [/-][+]`zipfile` may raise `EOFError` too early[/+]picnixz commentedon Sep 22, 2025
Does it reproduce with the latest Python 3.12 version? Also, unless this is a security issue (which I believe at first glance it's not), we won't fix 3.12.
Ragzouken commentedon Sep 22, 2025
It didn't occur to me to try on latest 3.12, but after trying yes it seems it is fixed. Sorry for the noise here, but maybe it can serve as some evidence that it's safe to close this issue.
picnixz commentedon Sep 22, 2025
Ok, so I'm going to close it as
fixed. I don't know when it was fixed though but it might have been reported as part of a different issue. Thanks for checking on your side!