From 41f0608645155d78ec249b8bf51687fb8bf0a938 Mon Sep 17 00:00:00 2001 From: lipengyu Date: Thu, 20 Aug 2026 09:59:31 +0800 Subject: [PATCH 1/3] gh-156078: Prevent ZipFile.mkdir() during an active write Fix `ZipFile.mkdir()` so that it raises `ValueError` when another writable member handle returned by `ZipFile.open(..., mode="w")` is still open. --- Lib/test/test_zipfile/test_core.py | 2 ++ Lib/zipfile/__init__.py | 5 +++++ .../Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 1c6e3a9f0a9a2d..a2dcbc36352ec1 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) diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 7a81aa8f44c8f4..1868d467161bd6 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -2596,6 +2596,11 @@ def mkdir(self, zinfo_or_directory_name, mode=511): else: raise TypeError("Expected type str or ZipInfo") + 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 00000000000000..43c35dba56a4b7 --- /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. From 60a6c3815720b7cb6ddb5521366b2df0b0640195 Mon Sep 17 00:00:00 2001 From: lipengyu Date: Thu, 20 Aug 2026 19:01:02 +0800 Subject: [PATCH 2/3] Add the missing closed-archive check --- Lib/test/test_zipfile/test_core.py | 3 +++ Lib/zipfile/__init__.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index a2dcbc36352ec1..f37696be8a3eb4 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -5520,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 1868d467161bd6..36e844a3f9089b 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -2596,6 +2596,9 @@ 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." From b6e2d9ba388e8df3f6e1e69160a019e150b72e11 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 22 Aug 2026 11:23:18 +0100 Subject: [PATCH 3/3] Little nits Co-authored-by: Stan Ulbrych --- Lib/zipfile/__init__.py | 3 ++- .../Library/2026-08-20-09-56-45.gh-issue-156078.-E7gZc.rst | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 36e844a3f9089b..e2666c4c1dfcf8 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -2598,7 +2598,8 @@ def mkdir(self, zinfo_or_directory_name, mode=511): if not self.fp: raise ValueError( - "Attempt to write to ZIP archive that was already closed") + "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." 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 index 43c35dba56a4b7..d2a3a219fa8958 100644 --- 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 @@ -1,3 +1,2 @@ -Fix :meth:`zipfile.ZipFile.mkdir` to raise :exc:`ValueError` when called -while a writable member handle is open, preventing corruption of the ZIP -archive. +:meth:`zipfile.ZipFile.mkdir` now raises :exc:`ValueError` when the archive +is closed or when a writable member handle is open.