diff --git a/Changelog.rst b/Changelog.rst index a05dec2..4a4db93 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -5,7 +5,15 @@ ChangeLog :website: http://offlineimap.org -OfflineIMAP v6.5.6 (YYYY-MM-DD) +OfflineIMAP v6.5.6.1 (YYYY-MM-DD) +================================= + +* Fix mangled message headers for servers without UIDPLUS: + X-OfflineIMAP was added with preceeding '\n' instead of + '\r\n' just before message was uploaded to the IMAP server. + + +OfflineIMAP v6.5.6 (2014-05-14) =============================== * Fix IDLE mode regression (it didn't worked) introduced diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py index 43e79ff..bca52a2 100644 --- a/offlineimap/folder/Base.py +++ b/offlineimap/folder/Base.py @@ -413,16 +413,26 @@ next line\n """ - def addmessageheader(self, content, headername, headervalue): + def addmessageheader(self, content, crlf, headername, headervalue): + """ + Adds new header to the provided message. + + Arguments: + - content: message content, headers and body as a single string + - crlf: string that carries line ending + - headername: name of the header to add + - headervalue: value of the header to add + + """ self.ui.debug('', 'addmessageheader: called to add %s: %s' % (headername, headervalue)) - prefix = '\n' + prefix = crlf suffix = '' - insertionpoint = content.find('\n\n') + insertionpoint = content.find(crlf + crlf) if insertionpoint == 0 or insertionpoint == -1: prefix = '' - suffix = '\n' + suffix = crlf if insertionpoint == -1: insertionpoint = 0 # When body starts immediately, without preceding '\n' @@ -430,8 +440,8 @@ next line\n # we seen many broken ones), we should add '\n' to make # new (and the only header, in this case) to be properly # separated from the message body. - if content[0] != '\n': - suffix = suffix + '\n' + if content[0:len(crlf)] != crlf: + suffix = suffix + crlf self.ui.debug('', 'addmessageheader: insertionpoint = %d' % insertionpoint) headers = content[0:insertionpoint] diff --git a/offlineimap/folder/Gmail.py b/offlineimap/folder/Gmail.py index f051938..2a598de 100644 --- a/offlineimap/folder/Gmail.py +++ b/offlineimap/folder/Gmail.py @@ -93,7 +93,7 @@ class GmailFolder(IMAPFolder): labels = set() labels = labels - self.ignorelabels labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels)) - body = self.addmessageheader(body, self.labelsheader, labels_str) + body = self.addmessageheader(body, '\n', self.labelsheader, labels_str) if len(body)>200: dbg_output = "%s...%s" % (str(body)[:150], str(body)[-50:]) diff --git a/offlineimap/folder/GmailMaildir.py b/offlineimap/folder/GmailMaildir.py index 3f37b02..be0d20d 100644 --- a/offlineimap/folder/GmailMaildir.py +++ b/offlineimap/folder/GmailMaildir.py @@ -141,7 +141,7 @@ class GmailMaildirFolder(MaildirFolder): # Change labels into content labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels | ignoredlabels)) - content = self.addmessageheader(content, self.labelsheader, labels_str) + content = self.addmessageheader(content, '\n', self.labelsheader, labels_str) rtime = self.messagelist[uid].get('rtime', None) # write file with new labels to a unique file in tmp diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 4801eef..3b506e5 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -526,6 +526,7 @@ class IMAPFolder(BaseFolder): # NB: imapobj to None. try: while retry_left: + # XXX: we can mangle message only once, out of the loop # UIDPLUS extension provides us with an APPENDUID response. use_uidplus = 'UIDPLUS' in imapobj.capabilities @@ -535,7 +536,7 @@ class IMAPFolder(BaseFolder): content) self.ui.debug('imap', 'savemessage: header is: %s: %s' %\ (headername, headervalue)) - content = self.addmessageheader(content, headername, headervalue) + content = self.addmessageheader(content, CRLF, headername, headervalue) if len(content)>200: dbg_output = "%s...%s" % (content[:150], content[-50:])