diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2024-01-10 13:31:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-10 13:31:55 (GMT) |
commit | be5e65fdf67b1817e173e73443564c7c146b09a4 (patch) | |
tree | 31a8b1454d36d03a2a8919b1d8b9685907708539 /Lib/mailbox.py | |
parent | 89cee94b315c88d3cd4c9ffc051e7abd6a5f2196 (diff) | |
download | cpython-be5e65fdf67b1817e173e73443564c7c146b09a4.zip cpython-be5e65fdf67b1817e173e73443564c7c146b09a4.tar.gz cpython-be5e65fdf67b1817e173e73443564c7c146b09a4.tar.bz2 |
gh-66515: Fix locking of an MH mailbox without ".mh_sequences" file (GH-113482)
Guarantee that it either open an existing ".mh_sequences" file or create
a new ".mh_sequences" file, but do not replace existing ".mh_sequences"
file.
Diffstat (limited to 'Lib/mailbox.py')
-rw-r--r-- | Lib/mailbox.py | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 0e1d49b..81ea210 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1141,10 +1141,24 @@ class MH(Mailbox): """Return a count of messages in the mailbox.""" return len(list(self.iterkeys())) + def _open_mh_sequences_file(self, text): + mode = '' if text else 'b' + kwargs = {'encoding': 'ASCII'} if text else {} + path = os.path.join(self._path, '.mh_sequences') + while True: + try: + return open(path, 'r+' + mode, **kwargs) + except FileNotFoundError: + pass + try: + return open(path, 'x+' + mode, **kwargs) + except FileExistsError: + pass + def lock(self): """Lock the mailbox.""" if not self._locked: - self._file = open(os.path.join(self._path, '.mh_sequences'), 'rb+') + self._file = self._open_mh_sequences_file(text=False) _lock_file(self._file) self._locked = True @@ -1225,8 +1239,9 @@ class MH(Mailbox): def set_sequences(self, sequences): """Set sequences using the given name-to-key-list dictionary.""" - f = open(os.path.join(self._path, '.mh_sequences'), 'w', encoding='ASCII') + f = self._open_mh_sequences_file(text=True) try: + os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC)) for name, keys in sequences.items(): if len(keys) == 0: continue |