diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 1c6e3a9f0a9a2de..f37696be8a3eb4b 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -4598,6 +4598,8 @@ def test_open_conflicting_handles(self): zipf.writestr('str', 'abcde') with self.assertRaises(ValueError): zipf.write(__file__, 'file') + with self.assertRaises(ValueError): + zipf.mkdir('directory') with self.assertRaises(ValueError): zipf.close() w1.write(msg2) @@ -5518,6 +5520,9 @@ def test_mkdir(self): zf.extractall(target) self.assertEqual(set(os.listdir(target)), {"directory", "directory2", "directory3", "directory4"}) + with self.assertRaises(ValueError): + zf.mkdir("closed") + def test_create_directory_with_write(self): with zipfile.ZipFile(TESTFN, "w") as zf: zf.writestr(zipfile.ZipInfo('directory/'), '') diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 7a81aa8f44c8f4c..36e844a3f9089b7 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -2596,6 +2596,14 @@ def mkdir(self, zinfo_or_directory_name, mode=511): else: raise TypeError("Expected type str or ZipInfo") + if not self.fp: + raise ValueError( + "Attempt to write to ZIP archive that was already closed") + if self._writing: + raise ValueError( + "Can't write to ZIP archive while an open writing handle exists." + ) + with self._lock: if self._seekable: self.fp.seek(self.start_dir) diff --git a/Misc/NEWS.d/next/Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst b/Misc/NEWS.d/next/Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst new file mode 100644 index 000000000000000..43c35dba56a4b7b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst @@ -0,0 +1,3 @@ +Fix :meth:`zipfile.ZipFile.mkdir` to raise :exc:`ValueError` when called +while a writable member handle is open, preventing corruption of the ZIP +archive.