[Python-checkins] r53110 - python/trunk/Lib/mailbox.py

Neal Norwitz nnorwitz at gmail.com
Thu Dec 21 05:54:21 CET 2006


Is there any reason to use 2 rather than os.SEEK_END in this code?

> +        self._file.seek(0, 2)

n
--

On 12/20/06, andrew.kuchling <python-checkins at python.org> wrote:
> Author: andrew.kuchling
> Date: Wed Dec 20 20:48:20 2006
> New Revision: 53110
>
> Modified:
>    python/trunk/Lib/mailbox.py
> Log:
> [Apply length-checking.diff from bug #1599254]
>
> Add length checking to single-file mailbox formats: before doing a
> flush() on a mailbox, seek to the end and verify its length is
> unchanged, raising ExternalClashError if the file's length has
> changed.
>
> This fix avoids potential data loss if some other process appends to
> the mailbox file after the table of contents has been generated;
> instead of overwriting the modified file, you'll get the exception.
>
> I also noticed that the self._lookup() call in self.flush() wasn't
> necessary (everything that sets self._pending to True also calls
> self.lookup()), and replaced it by an assertion.
>
> 2.5 backport candidate.
>
>
> Modified: python/trunk/Lib/mailbox.py
> ==============================================================================
> --- python/trunk/Lib/mailbox.py (original)
> +++ python/trunk/Lib/mailbox.py Wed Dec 20 20:48:20 2006
> @@ -513,6 +513,7 @@
>          self._next_key = 0
>          self._pending = False   # No changes require rewriting the file.
>          self._locked = False
> +        self._file_length = None        # Used to record mailbox size
>
>      def add(self, message):
>          """Add message and return assigned key."""
> @@ -566,7 +567,21 @@
>          """Write any pending changes to disk."""
>          if not self._pending:
>              return
> -        self._lookup()
> +
> +        # In order to be writing anything out at all, self._toc must
> +        # already have been generated (and presumably has been modified
> +        # by adding or deleting an item).
> +        assert self._toc is not None
> +
> +        # Check length of self._file; if it's changed, some other process
> +        # has modified the mailbox since we scanned it.
> +        self._file.seek(0, 2)
> +        cur_len = self._file.tell()
> +        if cur_len != self._file_length:
> +            raise ExternalClashError('Size of mailbox file changed '
> +                                     '(expected %i, found %i)' %
> +                                     (self._file_length, cur_len))
> +
>          new_file = _create_temporary(self._path)
>          try:
>              new_toc = {}
> @@ -642,6 +657,7 @@
>          offsets = self._install_message(message)
>          self._post_message_hook(self._file)
>          self._file.flush()
> +        self._file_length = self._file.tell()  # Record current length of mailbox
>          return offsets
>
>
> @@ -733,6 +749,7 @@
>                  break
>          self._toc = dict(enumerate(zip(starts, stops)))
>          self._next_key = len(self._toc)
> +        self._file_length = self._file.tell()
>
>
>  class MMDF(_mboxMMDF):
> @@ -776,6 +793,8 @@
>                  break
>          self._toc = dict(enumerate(zip(starts, stops)))
>          self._next_key = len(self._toc)
> +        self._file.seek(0, 2)
> +        self._file_length = self._file.tell()
>
>
>  class MH(Mailbox):
> @@ -1201,7 +1220,9 @@
>          self._toc = dict(enumerate(zip(starts, stops)))
>          self._labels = dict(enumerate(label_lists))
>          self._next_key = len(self._toc)
> -
> +        self._file.seek(0, 2)
> +        self._file_length = self._file.tell()
> +
>      def _pre_mailbox_hook(self, f):
>          """Called before writing the mailbox to file f."""
>          f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' %
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>


More information about the Python-checkins mailing list