From ae1c5a0a53d1fd351b6fd33e8a46ad1034874489 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 14 Jun 2017 12:39:29 +0200 Subject: Deal with both CRLF and LF mime messages. IMAP always requires CRLF, and so does the MIME standard, KMIME expects LF-only. We now just try to always use CRLF on disk, but convert LF-only messages should we have to (e.g. because copied over from maildir or so). --- examples/imapresource/imapresource.cpp | 15 ++++++++++++--- .../mailtransportresource/tests/mailtransporttest.cpp | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'examples') diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 945962f..25d9534 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -197,7 +197,7 @@ public: auto mail = Sink::ApplicationDomain::Mail::create(mResourceInstanceIdentifier); mail.setFolder(folderLocalId); - mail.setMimeMessage(message.msg->encodedContent()); + mail.setMimeMessage(message.msg->encodedContent(true)); mail.setExtractedFullPayloadAvailable(message.fullPayload); setFlags(mail, message.flags); @@ -608,6 +608,15 @@ public: } return KAsync::error("Nothing to do"); } + static QByteArray ensureCRLF(const QByteArray &data) { + auto index = data.indexOf('\n'); + if (index > 0 && data.at(index - 1) == '\r') { //First line is LF-only terminated + //Convert back and forth in case there's a mix. We don't want to expand CRLF into CRCRLF. + return KMime::LFtoCRLF(KMime::CRLFtoLF(data)); + } else { + return data; + } + } KAsync::Job replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList &changedProperties) Q_DECL_OVERRIDE { @@ -616,7 +625,7 @@ public: KAsync::Job job = KAsync::null(); if (operation == Sink::Operation_Creation) { const QString mailbox = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); - const QByteArray content = mail.getMimeMessage(); + const auto content = ensureCRLF(mail.getMimeMessage()); const auto flags = getFlags(mail); const QDateTime internalDate = mail.getDate(); job = login.then(imap->append(mailbox, content, flags, internalDate)) @@ -651,7 +660,7 @@ public: if (messageChanged || messageMoved) { const auto folderId = folderIdFromMailRid(oldRemoteId); const QString oldMailbox = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, folderId); - const QByteArray content = mail.getMimeMessage(); + const auto content = ensureCRLF(mail.getMimeMessage()); const QDateTime internalDate = mail.getDate(); SinkTrace() << "Replacing message. Old mailbox: " << oldMailbox << "New mailbox: " << mailbox << "Flags: " << flags << "Content: " << content; KIMAP2::ImapSet set; diff --git a/examples/mailtransportresource/tests/mailtransporttest.cpp b/examples/mailtransportresource/tests/mailtransporttest.cpp index e4cc447..2a831ed 100644 --- a/examples/mailtransportresource/tests/mailtransporttest.cpp +++ b/examples/mailtransportresource/tests/mailtransporttest.cpp @@ -64,7 +64,7 @@ private slots: message->assemble(); auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); - mail.setMimeMessage(message->encodedContent()); + mail.setMimeMessage(message->encodedContent(true)); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); @@ -92,7 +92,7 @@ private slots: message->assemble(); auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); - mail.setMimeMessage(message->encodedContent()); + mail.setMimeMessage(message->encodedContent(true)); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); -- cgit v1.2.3