gh-68164: Set the "regular file" bit in zipfile's writestr (GH-134232)

serhiy-storchaka <[email protected]> Tue, 11 Aug 2026 11:59:13 -0400 (EDT)
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/42a18e14d201f8a99cd1f064b4058cbe81a70ba2
commit: 42a18e14d201f8a99cd1f064b4058cbe81a70ba2
branch: main
author: Tim Hatch <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-11T15:59:01Z
summary:

gh-68164: Set the "regular file" bit in zipfile's writestr (GH-134232)

files:
A Misc/NEWS.d/next/Library/2025-05-19-07-32-51.gh-issue-68164.XhFbJD.rst
M Lib/test/test_zipfile/test_core.py
M Lib/zipfile/__init__.py

diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index e9974d6c05648bb..d0ae7ce787bee32 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -500,7 +500,7 @@ def zip_test_writestr_permissions(self, f, compression):
         self.make_test_archive(f, compression)
         with zipfile.ZipFile(f, "r") as zipfp:
             zinfo = zipfp.getinfo('strfile')
-            self.assertEqual(zinfo.external_attr, 0o600 << 16)
+            self.assertEqual(zinfo.external_attr, 0o100600 << 16)
 
             zinfo2 = zipfp.getinfo('written-open-w')
             self.assertEqual(zinfo2.external_attr, 0o600 << 16)
@@ -4513,8 +4513,8 @@ def test_for_archive(self):
             zi = zipfile.ZipInfo(base_filename)._for_archive(zf)
             self.assertEqual(zi.compress_level, 1)
             self.assertEqual(zi.compress_type, zipfile.ZIP_STORED)
-            # ?rw- --- ---
-            filemode = stat.S_IRUSR | stat.S_IWUSR
+            # - rw- --- ---
+            filemode = stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR
             # filemode is stored as the highest 16 bits of external_attr
             self.assertEqual(zi.external_attr >> 16, filemode)
             self.assertEqual(zi.external_attr & 0xFF, 0)  # no MS-DOS flag
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 764bb9b1e9246f6..dd1f7fb9e802048 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -689,7 +689,7 @@ def _for_archive(self, archive):
             self.external_attr = 0o40775 << 16  # drwxrwxr-x
             self.external_attr |= 0x10  # MS-DOS directory flag
         else:
-            self.external_attr = 0o600 << 16  # ?rw-------
+            self.external_attr = 0o100600 << 16  # -rw-------
         return self
 
     def is_dir(self):
diff --git a/Misc/NEWS.d/next/Library/2025-05-19-07-32-51.gh-issue-68164.XhFbJD.rst b/Misc/NEWS.d/next/Library/2025-05-19-07-32-51.gh-issue-68164.XhFbJD.rst
new file mode 100644
index 000000000000000..21c1ed188c25070
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-19-07-32-51.gh-issue-68164.XhFbJD.rst
@@ -0,0 +1,2 @@
+Fix :func:`zipfile.ZipFile.writestr` so it sets the "regular file" bit by
+default.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]