summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorDaniel Hillier <daniel.hillier@gmail.com>2019-11-30 08:30:47 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2019-11-30 08:30:47 (GMT)
commit8d62df60d8733d0fa9aee14ef746d0009a7a9726 (patch)
tree313fcbd540496aaf81650be5a189cbc8abeee63e /Lib
parent1df65f7c6c00dfae9286c7a58e1b3803e3af33e5 (diff)
downloadcpython-8d62df60d8733d0fa9aee14ef746d0009a7a9726.zip
cpython-8d62df60d8733d0fa9aee14ef746d0009a7a9726.tar.gz
cpython-8d62df60d8733d0fa9aee14ef746d0009a7a9726.tar.bz2
bpo-37523: Raise ValueError for I/O operations on a closed zipfile.ZipExtFile. (GH-14658)
Raises ValueError when calling the following on a closed zipfile.ZipExtFile: read, readable, seek, seekable, tell.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_zipfile.py14
-rw-r--r--Lib/zipfile.py10
2 files changed, 24 insertions, 0 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 1e1854b..66f05ac 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -571,6 +571,20 @@ class StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
with open(TESTFN, "rb") as f:
self.assertEqual(zipfp.read(TESTFN), f.read())
+ def test_io_on_closed_zipextfile(self):
+ fname = "somefile.txt"
+ with zipfile.ZipFile(TESTFN2, mode="w") as zipfp:
+ zipfp.writestr(fname, "bogus")
+
+ with zipfile.ZipFile(TESTFN2, mode="r") as zipfp:
+ with zipfp.open(fname) as fid:
+ fid.close()
+ self.assertRaises(ValueError, fid.read)
+ self.assertRaises(ValueError, fid.seek, 0)
+ self.assertRaises(ValueError, fid.tell)
+ self.assertRaises(ValueError, fid.readable)
+ self.assertRaises(ValueError, fid.seekable)
+
def test_write_to_readonly(self):
"""Check that trying to call write() on a readonly ZipFile object
raises a ValueError."""
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index b0afb9d..e1d07f2 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -889,12 +889,16 @@ class ZipExtFile(io.BufferedIOBase):
return self._readbuffer[self._offset: self._offset + 512]
def readable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return True
def read(self, n=-1):
"""Read and return up to n bytes.
If the argument is omitted, None, or negative, data is read and returned until EOF is reached.
"""
+ if self.closed:
+ raise ValueError("read from closed file.")
if n is None or n < 0:
buf = self._readbuffer[self._offset:]
self._readbuffer = b''
@@ -1031,9 +1035,13 @@ class ZipExtFile(io.BufferedIOBase):
super().close()
def seekable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return self._seekable
def seek(self, offset, whence=0):
+ if self.closed:
+ raise ValueError("seek on closed file.")
if not self._seekable:
raise io.UnsupportedOperation("underlying stream is not seekable")
curr_pos = self.tell()
@@ -1082,6 +1090,8 @@ class ZipExtFile(io.BufferedIOBase):
return self.tell()
def tell(self):
+ if self.closed:
+ raise ValueError("tell on closed file.")
if not self._seekable:
raise io.UnsupportedOperation("underlying stream is not seekable")
filepos = self._orig_file_size - self._left - len(self._readbuffer) + self._offset