Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Lib/test/test_zipfile/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4337,6 +4337,26 @@ def test_closed_zip_raises_ValueError(self):
f.write('zipfile test data')
self.assertRaises(ValueError, zipf.write, TESTFN)

def test_closed_zip_extract_raises_ValueError(self):
with zipfile.ZipFile(io.BytesIO(), mode="w") as zipf:
pass
self.assertRaises(ValueError, zipf.testzip)

with zipfile.ZipFile(io.BytesIO(), mode="w") as zipf:
zipf.writestr("dir/", b"")
zipf.writestr("file.txt", b"data")
self.assertRaises(ValueError, zipf.testzip)

with temp_dir() as dest:
self.assertRaises(ValueError, zipf.extract, "dir/", dest)
self.assertEqual(os.listdir(dest), [])
self.assertRaises(ValueError, zipf.extract, "file.txt", dest)
self.assertEqual(os.listdir(dest), [])
self.assertRaises(ValueError, zipf.extractall, dest)
self.assertEqual(os.listdir(dest), [])
self.assertRaises(ValueError, zipf.extractall, dest, ["dir/"])
self.assertEqual(os.listdir(dest), [])

def test_bad_constructor_mode(self):
"""Check that bad modes passed to ZipFile constructor are caught."""
self.assertRaises(ValueError, zipfile.ZipFile, TESTFN, "q")
Expand Down
9 changes: 9 additions & 0 deletions Lib/zipfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,9 @@ def testzip(self):

Return None if all files could be read successfully, or the name
of the offending file otherwise."""
if not self.fp:
raise ValueError(
"Attempt to use ZIP archive that was already closed")
chunk_size = 2 ** 20
for zinfo in self.filelist:
try:
Expand Down Expand Up @@ -2352,6 +2355,9 @@ def extract(self, member, path=None, pwd=None):
specify a different directory using 'path'. You can specify the
password to decrypt the file using 'pwd'.
"""
if not self.fp:
raise ValueError(
"Attempt to use ZIP archive that was already closed")
if path is None:
path = os.getcwd()
else:
Expand All @@ -2366,6 +2372,9 @@ def extractall(self, path=None, members=None, pwd=None):
by namelist(). You can specify the password to decrypt all files
using 'pwd'.
"""
if not self.fp:
raise ValueError(
"Attempt to use ZIP archive that was already closed")
if members is None:
members = self.namelist()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:meth:`zipfile.ZipFile.testzip`, :meth:`~zipfile.ZipFile.extract` and
:meth:`~zipfile.ZipFile.extractall` now consistently raise :exc:`ValueError`
on a closed :class:`~zipfile.ZipFile` before touching the filesystem.
Loading