From d81eea635c2151c2c9c62a53c08e427c38ad0acd Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 29 Jun 2018 17:27:31 +0200 Subject: Partial fix for multipart/mixed in alternative part We only render the first part right now, which is not correct. --- .../src/domain/mime/mimetreeparser/messagepart.cpp | 27 ++++---- .../src/domain/mime/mimetreeparser/messagepart.h | 1 - .../mime/mimetreeparser/multipartalternative.cpp | 28 +------- .../mimetreeparser/tests/mimetreeparsertest.cpp | 20 ++++++ .../testdata/applehtmlwithattachmentsmixed.mbox | 74 ++++++++++++++++++++++ 5 files changed, 111 insertions(+), 39 deletions(-) create mode 100644 framework/src/domain/mime/testdata/applehtmlwithattachmentsmixed.mbox diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.cpp b/framework/src/domain/mime/mimetreeparser/messagepart.cpp index 1a1b2003..9c17aafc 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.cpp +++ b/framework/src/domain/mime/mimetreeparser/messagepart.cpp @@ -587,30 +587,35 @@ AlternativeMessagePart::AlternativeMessagePart(ObjectTreeParser *otp, KMime::Con // when displaying plain text. if (!dataHtml) { dataHtml = findTypeInDirectChilds(mNode, "multipart/mixed"); + if (dataHtml) { + const auto parts = dataHtml->contents(); + for (int i = 0; i < parts.size(); i++) { + const auto p = parts.at(i); + if (i == 0 ) { + // FIXME multipart/mixed should display all types serially, not just one + dataHtml = p; + } else if (KMime::isAttachment(p)) { + appendSubPart(MimeMessagePart::Ptr(new MimeMessagePart(otp, p, true))); + } + } + } } } if (dataIcal) { - mChildNodes[Util::MultipartIcal] = dataIcal; + mChildParts[Util::MultipartIcal] = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, dataIcal, true)); } if (dataText) { - mChildNodes[Util::MultipartPlain] = dataText; + mChildParts[Util::MultipartPlain] = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, dataText, true)); } if (dataHtml) { - mChildNodes[Util::MultipartHtml] = dataHtml; + mChildParts[Util::MultipartHtml] = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, dataHtml, true)); } - if (mChildNodes.isEmpty()) { + if (mChildParts.isEmpty()) { qCWarning(MIMETREEPARSER_LOG) << "no valid nodes"; - return; - } - - QMapIterator i(mChildNodes); - while (i.hasNext()) { - i.next(); - mChildParts[i.key()] = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, i.value(), true)); } } diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.h b/framework/src/domain/mime/mimetreeparser/messagepart.h index c576699e..9add81d2 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.h +++ b/framework/src/domain/mime/mimetreeparser/messagepart.h @@ -245,7 +245,6 @@ public: QList availableModes(); private: - QMap mChildNodes; QMap mChildParts; friend class DefaultRendererPrivate; diff --git a/framework/src/domain/mime/mimetreeparser/multipartalternative.cpp b/framework/src/domain/mime/mimetreeparser/multipartalternative.cpp index d0657edb..b1500136 100644 --- a/framework/src/domain/mime/mimetreeparser/multipartalternative.cpp +++ b/framework/src/domain/mime/mimetreeparser/multipartalternative.cpp @@ -47,35 +47,9 @@ MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Interface::BodyP return MessagePart::Ptr(); } - //Hardcoded after removing the source - auto preferredMode = MimeTreeParser::Util::Html; AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), node)); - if (mp->mChildNodes.isEmpty()) { + if (mp->mChildParts.isEmpty()) { return MimeMessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0))); } - - KMime::Content *dataIcal = mp->mChildNodes.contains(Util::MultipartIcal) ? mp->mChildNodes[Util::MultipartIcal] : nullptr; - KMime::Content *dataHtml = mp->mChildNodes.contains(Util::MultipartHtml) ? mp->mChildNodes[Util::MultipartHtml] : nullptr; - KMime::Content *dataPlain = mp->mChildNodes.contains(Util::MultipartPlain) ? mp->mChildNodes[Util::MultipartPlain] : nullptr; - - // Make sure that in default ical is prefered over html and plain text - if (dataIcal && ((preferredMode != Util::MultipartHtml && preferredMode != Util::MultipartPlain))) { - if (dataHtml) { - part.nodeHelper()->setNodeProcessed(dataHtml, false); - } - if (dataPlain) { - part.nodeHelper()->setNodeProcessed(dataPlain, false); - } - preferredMode = Util::MultipartIcal; - } else if ((dataHtml && (preferredMode == Util::MultipartHtml || preferredMode == Util::Html)) || - (dataHtml && dataPlain && dataPlain->body().isEmpty())) { - if (dataPlain) { - part.nodeHelper()->setNodeProcessed(dataPlain, false); - } - preferredMode = Util::MultipartHtml; - } else if (!(preferredMode == Util::MultipartHtml) && dataPlain) { - part.nodeHelper()->setNodeProcessed(dataHtml, false); - preferredMode = Util::MultipartPlain; - } return mp; } diff --git a/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp b/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp index 6b4280a9..7fa651bc 100644 --- a/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp +++ b/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp @@ -418,6 +418,26 @@ private slots: auto attachments = otp.collectAttachmentParts(); QCOMPARE(attachments.size(), 1); } + + void testAppleHtmlWithAttachmentsMixed() + { + MimeTreeParser::ObjectTreeParser otp; + otp.parseObjectTree(readMailFromFile("applehtmlwithattachmentsmixed.mbox")); + otp.decryptParts(); + otp.print(); + auto partList = otp.collectContentParts(); + QCOMPARE(partList.size(), 1); + auto part = partList[0].dynamicCast(); + QCOMPARE(part->encryptions().size(), 0); + QCOMPARE(part->signatures().size(), 0); + qWarning() << otp.plainTextContent(); + qWarning() << otp.htmlContent(); + QCOMPARE(otp.plainTextContent(), QString::fromUtf8("Hello\n\n\n\nRegards\n\nFsdfsdf")); + QCOMPARE(otp.htmlContent(), QString::fromUtf8("Hello


Regards

Fsdfsdf
")); + + auto attachments = otp.collectAttachmentParts(); + QCOMPARE(attachments.size(), 1); + } }; QTEST_GUILESS_MAIN(InterfaceTest) diff --git a/framework/src/domain/mime/testdata/applehtmlwithattachmentsmixed.mbox b/framework/src/domain/mime/testdata/applehtmlwithattachmentsmixed.mbox new file mode 100644 index 00000000..4c8d3bfd --- /dev/null +++ b/framework/src/domain/mime/testdata/applehtmlwithattachmentsmixed.mbox @@ -0,0 +1,74 @@ +Return-Path: +Received: from imapb020.mykolab.com ([unix socket]) + by imapb020.mykolab.com (Cyrus 2.5.11-41-gd53406f3f-Kolab-2.5.11-15.1.el7.kolab_16) with LMTPA; + Fri, 29 Jun 2018 17:10:33 +0200 +X-Sieve: CMU Sieve 2.4 +Received: from int-mx003.mykolab.com (unknown [10.9.13.3]) + by imapb020.mykolab.com (Postfix) with ESMTPS id DCFFB184 + for ; Fri, 29 Jun 2018 17:10:33 +0200 (CEST) +Received: from ext-subm002.mykolab.com (unknown [10.9.6.2]) + by int-mx003.mykolab.com (Postfix) with ESMTPS id C5438A48 + for ; Fri, 29 Jun 2018 17:10:33 +0200 (CEST) +From: Kolab +Content-Type: multipart/alternative; + boundary="Apple-Mail=_9D1C74B7-3E22-4635-805F-B86CE5F663C3" +Mime-Version: 1.0 (Mac OS X Mail 11.2 \(3445.5.20\)) +Subject: Apple attachment + signature +Message-Id: <0EDA7426-FD89-4C6D-8B28-9ACA7544FA6C@kolab.org> +Date: Fri, 29 Jun 2018 08:10:32 -0700 +To: John Doe + + +--Apple-Mail=_9D1C74B7-3E22-4635-805F-B86CE5F663C3 +Content-Transfer-Encoding: 7bit +Content-Type: text/plain; + charset=us-ascii + +Hello + + + +Regards + +Fsdfsdf +--Apple-Mail=_9D1C74B7-3E22-4635-805F-B86CE5F663C3 +Content-Type: multipart/mixed; + boundary="Apple-Mail=_FA5BEB3B-6B22-4219-964C-85261C367D87" + + +--Apple-Mail=_FA5BEB3B-6B22-4219-964C-85261C367D87 +Content-Transfer-Encoding: 7bit +Content-Type: text/html; + charset=us-ascii + +Hello

+--Apple-Mail=_FA5BEB3B-6B22-4219-964C-85261C367D87 +Content-Disposition: attachment; + filename=rebuildkube.sh +Content-Type: application/octet-stream; + x-unix-mode=0755; + name="rebuildkube.sh" +Content-Transfer-Encoding: 7bit + +set -e + +export CMAKE_LIBRARY_PATH=/usr/local/Cellar/gettext/0.19.8.1/lib:/usr/local/Cellar/readline/7.0.3_1/lib +export CMAKE_INCLUDE_PATH=/usr/local/Cellar/gettext/0.19.8.1/include:/usr/local/Cellar/readline/7.0.3_1/include +export PATH=/usr/local/Cellar/gettext/0.19.8.1/bin:$PATH +export MACOSX_DEPLOYMENT_TARGET=10.9.0 #Minimum version to find the required type_traits header +export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/ + +. craft/craftenv.sh + +craft --install-deps --fetch --unpack --compile --install extragear/sink +craft --install-deps --fetch --unpack --compile --install --package extragear/kube + +--Apple-Mail=_FA5BEB3B-6B22-4219-964C-85261C367D87 +Content-Transfer-Encoding: 7bit +Content-Type: text/html; + charset=us-ascii + +

Regards

Fsdfsdf
+--Apple-Mail=_FA5BEB3B-6B22-4219-964C-85261C367D87-- + +--Apple-Mail=_9D1C74B7-3E22-4635-805F-B86CE5F663C3-- -- cgit v1.2.3