diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 2be4c83..8575851 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -683,6 +683,11 @@ class _singlefileMailbox(Mailbox): _sync_close(new_file) # self._file is about to get replaced, so no need to sync. self._file.close() + + # Ensure 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) + try: os.rename(new_file.name, self._path) except OSError as e: diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 91c8983..85126e5 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -942,7 +942,26 @@ class TestMaildir(TestMailbox, unittest.TestCase): self._box._refresh() self.assertTrue(refreshed()) -class _TestMboxMMDF(TestMailbox): + +class _TestSingleFile(TestMailbox): + '''Common tests for single-file mailboxes''' + + def test_permissions_after_flush(self): + # See issue #5346 + + # Make the mailbox world writable. It's unlikely that the + # mailbox would have these permissions after flush, because + # umask prevents it. + mode = os.stat(self._path).st_mode | 0o666 + os.chmod(self._path, mode) + + self._box.add(self._template % 0) + self._box.flush() + + self.assertEqual(os.stat(self._path).st_mode, mode) + + +class _TestMboxMMDF(_TestSingleFile): def tearDown(self): super().tearDown() @@ -1217,7 +1236,7 @@ class TestMH(TestMailbox, unittest.TestCase): return os.path.join(self._path, '.mh_sequences.lock') -class TestBabyl(TestMailbox, unittest.TestCase): +class TestBabyl(_TestSingleFile, unittest.TestCase): _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)