]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-117467: Add preserving of mailbox owner on flush (GH-117510) (GH-117537)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 4 Apr 2024 10:55:42 +0000 (12:55 +0200)
committerGitHub <noreply@github.com>
Thu, 4 Apr 2024 10:55:42 +0000 (10:55 +0000)
(cherry picked from commit 3f5bcc86d0764b691087e8412941e947554c93fd)

Co-authored-by: Tony Mountifield <tony@mountifield.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/mailbox.py
Lib/test/test_mailbox.py
Misc/NEWS.d/next/Library/2024-04-03-18-36-53.gh-issue-117467.l6rWlj.rst [new file with mode: 0644]

index c8b3444f646b384244f60428bdf942ba600394b4..c7f060ce5210879c82fc9bf608ff74abc0ade593 100644 (file)
@@ -698,9 +698,13 @@ class _singlefileMailbox(Mailbox):
         _sync_close(new_file)
         # self._file is about to get replaced, so no need to sync.
         self._file.close()
-        # Make sure the new file's mode is the same as the old file's
-        mode = os.stat(self._path).st_mode
-        os.chmod(new_file.name, mode)
+        # Make sure the new file's mode and owner are the same as the old file's
+        info = os.stat(self._path)
+        os.chmod(new_file.name, info.st_mode)
+        try:
+            os.chown(new_file.name, info.st_uid, info.st_gid)
+        except (AttributeError, OSError):
+            pass
         try:
             os.rename(new_file.name, self._path)
         except FileExistsError:
index 9f13d2ff4f6854871bc4787b621483c07c2a8330..93cf53bfcbb53743fdfaa114931e7357f2d717aa 100644 (file)
@@ -9,6 +9,7 @@ import re
 import io
 import tempfile
 from test import support
+from test.support import import_helper
 from test.support import os_helper
 from test.support import socket_helper
 import unittest
@@ -981,6 +982,47 @@ class _TestSingleFile(TestMailbox):
 
         self.assertEqual(os.stat(self._path).st_mode, mode)
 
+    @unittest.skipUnless(hasattr(os, 'chown'), 'requires os.chown')
+    def test_ownership_after_flush(self):
+        # See issue gh-117467
+
+        pwd = import_helper.import_module('pwd')
+        grp = import_helper.import_module('grp')
+        st = os.stat(self._path)
+
+        for e in pwd.getpwall():
+            if e.pw_uid != st.st_uid:
+                other_uid = e.pw_uid
+                break
+        else:
+            self.skipTest("test needs more than one user")
+
+        for e in grp.getgrall():
+            if e.gr_gid != st.st_gid:
+                other_gid = e.gr_gid
+                break
+        else:
+            self.skipTest("test needs more than one group")
+
+        try:
+            os.chown(self._path, other_uid, other_gid)
+        except OSError:
+            self.skipTest('test needs root privilege')
+        # Change permissions as in test_permissions_after_flush.
+        mode = st.st_mode | 0o666
+        os.chmod(self._path, mode)
+
+        self._box.add(self._template % 0)
+        i = self._box.add(self._template % 1)
+        # Need to remove one message to make flush() create a new file
+        self._box.remove(i)
+        self._box.flush()
+
+        st = os.stat(self._path)
+        self.assertEqual(st.st_uid, other_uid)
+        self.assertEqual(st.st_gid, other_gid)
+        self.assertEqual(st.st_mode, mode)
+
 
 class _TestMboxMMDF(_TestSingleFile):
 
diff --git a/Misc/NEWS.d/next/Library/2024-04-03-18-36-53.gh-issue-117467.l6rWlj.rst b/Misc/NEWS.d/next/Library/2024-04-03-18-36-53.gh-issue-117467.l6rWlj.rst
new file mode 100644 (file)
index 0000000..64ae9ff
--- /dev/null
@@ -0,0 +1,2 @@
+Preserve mailbox ownership when rewriting in :func:`mailbox.mbox.flush`.
+Patch by Tony Mountifield.