docker-offlineimap/offlineimap
Nicolas Sebrecht be285e522d IMAP: don't take junk data for valid mail content
OfflineIMAP frequently delivers mail files to the Maildir consisting exclusively
of a single ASCII digit in IDLE mode. IMAPFolder.getmessage 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.

Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/162
Based-on-patch-by: Austin Clements <amdragon@MIT.EDU>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
2016-07-28 07:18:23 +02:00
..
folder IMAP: don't take junk data for valid mail content 2016-07-28 07:18:23 +02:00
repository offlineimap.conf: allow non-spaces in the account list 2016-07-28 04:06:52 +02:00
ui learn to not download UIDs defined by the user 2016-07-03 20:02:45 +02:00
utils Make OS-default CA certificate file to be requested explicitely 2015-01-18 22:05:49 +03:00
__init__.py v7.0.2 2016-07-27 16:38:55 +02:00
accounts.py properly ignore folders with invalid characters (sep) in their name 2016-07-27 18:45:18 +02:00
bundled_imaplib2.py bump from imaplib2 v2.53 to v2.55 2016-06-11 11:08:02 +02:00
CustomConfig.py offlineimap.conf: learn to evaluate oauth2 related options 2016-07-27 04:25:18 +02:00
emailutil.py Rename email.Parser to email.parser 2016-05-10 02:53:09 +02:00
error.py more consistent style 2015-01-07 21:31:43 +01:00
globals.py fix: when called with -a, mbnames must not erase entries of other accounts 2016-06-25 17:33:42 +02:00
imaplibutil.py improve error message when ssl_version must be set due to the tls_level 2016-07-25 03:29:25 +02:00
imapserver.py improve error message when ssl_version must be set due to the tls_level 2016-07-25 03:29:25 +02:00
imaputil.py Add workaround for string.split for Python3 2016-05-10 02:53:09 +02:00
init.py offlineimap.conf: allow non-spaces in the account list 2016-07-28 04:06:52 +02:00
localeval.py minor code enhancements 2016-07-28 00:42:35 +02:00
mbnames.py mbnames: fix the filename extension for the intermediate files 2016-07-06 01:15:33 +02:00
threadutil.py threadutil: use 'with' statements for lock 2016-07-03 20:03:14 +02:00
virtual_imaplib2.py bump from imaplib2 v2.53 to v2.55 2016-06-11 11:08:02 +02:00