diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-04-04 18:56:49 +0000 |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-04-04 18:56:49 +0000 |
commit | 819a5f28e9e47737c9303846c1a3cb3ae31a0e0b (patch) | |
tree | 1e0e2ea1c8403d1c1726031e987f85bbcccc3822 /Lib | |
parent | 199504cd535cadfd752daf2aec5385f6badc6922 (diff) | |
download | cpython-819a5f28e9e47737c9303846c1a3cb3ae31a0e0b.tar.gz |
Sf bug [ #412214 ] ZipFile constructor leaves files open.
This applies the patch Fred Drake created to fix it.
I'm checking it in since I had to apply the patch anyway in order
to test its behavior on Windows.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_zipfile.py | 16 | ||||
-rw-r--r-- | Lib/zipfile.py | 14 |
2 files changed, 30 insertions, 0 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 50b8b36a85..bf7770b8cb 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -42,6 +42,22 @@ finally: if os.path.isfile(zipname): os.unlink(zipname) + +# This test checks that the ZipFile constructor closes the file object +# it opens if there's an error in the file. If it doesn't, the traceback +# holds a reference to the ZipFile object and, indirectly, the file object. +# On Windows, this causes the os.unlink() call to fail because the +# underlying file is still open. This is SF bug #412214. +# +fp = open(srcname, "w") +fp.write("this is not a legal zip file\n") +fp.close() +try: + zf = zipfile.ZipFile(srcname) +except zipfile.BadZipfile: + os.unlink(srcname) + + # make sure we don't raise an AttributeError when a partially-constructed # ZipFile instance is finalized; this tests for regression on SF tracker # bug #403871. diff --git a/Lib/zipfile.py b/Lib/zipfile.py index b638592a7a..5dedc1ba8c 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -186,9 +186,23 @@ class ZipFile: else: # file is not a zip file, just append fp.seek(0, 2) else: + if not self._filePassed: + self.fp.close() + self.fp = None raise RuntimeError, 'Mode must be "r", "w" or "a"' def _GetContents(self): + """Read the directory, making sure we close the file if the format + is bad.""" + try: + self._RealGetContents() + except BadZipfile: + if not self._filePassed: + self.fp.close() + self.fp = None + raise + + def _RealGetContents(self): """Read in the table of contents for the ZIP file.""" fp = self.fp fp.seek(-22, 2) # Start of end-of-archive record |