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.
This commit is contained in:
Serhiy Storchaka 2024-01-10 15:31:55 +02:00 committed by GitHub
parent 89cee94b31
commit be5e65fdf6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 2 deletions

View file

@ -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