Bug (& patch): Corrupted messages containing a single byte

Austin Clements amdragon at MIT.EDU
Fri Dec 7 04:32:37 GMT 2012

OfflineIMAP frequently delivers mail files to my Maildir consisting
exclusively of a single ASCII digit.  I tracked the problem down to
IMAPFolder.getmessage, which expects 'data' to be of the form

  [(fetch-info, message-body)]

However, the imapobj.uid call in getmessage returns a list of *all*
pending untagged FETCH responses.  If any message flags were changed
in the selected IMAP folder since the last command (by another client
or another thread in OfflineIMAP itself), the IMAP server will issue
unsolicited FETCH responses indicating these flag changes (RFC3501,
section 7).  When this happens, 'data' will look like, for example

  ['1231 (FLAGS (\\Seen) UID 5300)',
   '1238 (FLAGS (\\Seen) UID 5318)',
   ('1242 (UID 5325 BODY[] {7976}', message-body)]

Unfortunately, getmessage retrieves the message body as data[0][1],
which in this example is just the string "2", and this is what gets
stored in the mail file.

Multi-threaded OfflineIMAP with IDLE or holdconnectionopen is
particularly susceptible to this problem because flag changes synced
back to the IMAP server on one thread will appear as unsolicited FETCH
responses on another thread if it happens to have the same folder
selected.  This can also happen without IDLE or holdconnectionopen or
even in single-threaded OfflineIMAP with concurrent access from other
IMAP clients (webmail clients, etc.), though the window for the bug is
much smaller.

Ideally, either imaplib2 or getmessage would parse the fetch responses
to find the response for the requested UID.  However, since IMAP only
specifies unilateral FETCH responses for flag changes, it's almost
certainly safe to simply find the element of 'data' that is a tuple
(perhaps aborting if there is more than one tuple) and use that.  I've
attached patch to this effect.  I've only given it cursory testing, but
I'm running with it now.  If this seems like a good enough solution and
the patch is correct, I can roll a real patch with a commit message,
SOB, etc.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: unsolicited-fetch.patch
Type: text/x-diff
Size: 1027 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/offlineimap-project/attachments/20121206/cbee355e/attachment-0002.patch>

More information about the OfflineIMAP-project mailing list