diff options
-rw-r--r-- | src/libraries/qmfclient/qmailmessage.cpp | 14 | ||||
-rw-r--r-- | src/plugins/messageservices/imap/imapprotocol.cpp | 4 | ||||
-rw-r--r-- | tests/tst_qmailmessage/tst_qmailmessage.cpp | 207 |
3 files changed, 129 insertions, 96 deletions
diff --git a/src/libraries/qmfclient/qmailmessage.cpp b/src/libraries/qmfclient/qmailmessage.cpp index f021833a..cd8ca4b1 100644 --- a/src/libraries/qmfclient/qmailmessage.cpp +++ b/src/libraries/qmfclient/qmailmessage.cpp @@ -1162,10 +1162,15 @@ namespace findAttachments { QMailMessageContentType contentType = part.contentType(); - bool isText = (contentType.matches("text", "plain") - || contentType.matches("text", "html")); + // Excluded text content-types. + bool excludedText = (contentType.matches("text", "plain") + || contentType.matches("text", "html") + || contentType.matches("text", "calendar")); - bool isCalendar = contentType.matches("text", "calendar"); + // Excluded application content-types even when + // explicitly marked as attachment. + bool excludedApp = (contentType.matches("application", "pgp-signature") + || contentType.matches("application", "pkcs7-signature")); bool isInLine = (!part.contentDisposition().isNull()) && (part.contentDisposition().type() == QMailMessageContentDisposition::Inline); @@ -1177,7 +1182,8 @@ namespace findAttachments // Attached messages are considered as attachments even if content disposition // is inline instead of attachment, but only if they aren't text/plain nor text/html - if (isRFC822 || isAttachment || (isInLine && !isText && !isCalendar)) { + if (isRFC822 || (isAttachment && !excludedApp) + || (isInLine && !excludedText && !excludedApp)) { if (found) { *found << part.location(); } diff --git a/src/plugins/messageservices/imap/imapprotocol.cpp b/src/plugins/messageservices/imap/imapprotocol.cpp index 6de98d68..630b16ed 100644 --- a/src/plugins/messageservices/imap/imapprotocol.cpp +++ b/src/plugins/messageservices/imap/imapprotocol.cpp @@ -3804,8 +3804,9 @@ QByteArray ImapProtocol::quoteString(const QByteArray& input) void ImapProtocol::createMail(const QString &uid, const QDateTime &timeStamp, int size, uint flags, const QString &detachedFile, const QStringList& structure) { - QMailMessage mail = QMailMessage::fromSkeletonRfc2822File( detachedFile ); + QMailMessage mail; if ( !structure.isEmpty() ) { + mail = QMailMessage::fromSkeletonRfc2822File( detachedFile ); bool wellFormed = setMessageContentFromStructure( structure, &mail ); if (wellFormed && (mail.multipartType() != QMailMessage::MultipartNone)) { @@ -3817,6 +3818,7 @@ void ImapProtocol::createMail(const QString &uid, const QDateTime &timeStamp, in mail.setStatus( QMailMessage::New, true ); } else { // No structure - we're fetching the body of a message we already know about + mail = QMailMessage::fromRfc2822File( detachedFile ); mail.setStatus( QMailMessage::ContentAvailable, true ); } diff --git a/tests/tst_qmailmessage/tst_qmailmessage.cpp b/tests/tst_qmailmessage/tst_qmailmessage.cpp index 57645075..b6ac9f7b 100644 --- a/tests/tst_qmailmessage/tst_qmailmessage.cpp +++ b/tests/tst_qmailmessage/tst_qmailmessage.cpp @@ -127,8 +127,8 @@ private slots: void multiMultipart(); + void attachments_data(); void attachments(); - void recursiveAttachments(); void copyAndAssign(); @@ -1473,107 +1473,132 @@ void tst_QMailMessage::multiMultipart() } } -void tst_QMailMessage::attachments() +Q_DECLARE_METATYPE(QMailMessageContentDisposition::DispositionType) +typedef QPair<QByteArray, QMailMessageContentDisposition::DispositionType> PartDefinition; +void tst_QMailMessage::attachments_data() { - QByteArray data; - QByteArray type; - - QMailMessagePart p1; - type = "text/plain; charset=UTF-8"; - data = "P1: This is a plain text part."; - p1.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::EightBit, - QMailMessageBody::RequiresEncoding)); - - QMailMessagePart p2; - type = "text/calendar; charset=UTF-8"; - data = "BEGIN:VCALENDAR\nEND:VCALENDAR"; - p2.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::EightBit, - QMailMessageBody::RequiresEncoding)); - - QMailMessagePart p3; - type = "application/octet-stream; name=\"attach.pdf\""; - data = "abcdef"; - p3.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::Base64, - QMailMessageBody::AlreadyEncoded)); - p3.setContentDisposition(QMailMessageContentDisposition::Attachment); - - QMailMessage m; - m.setTo(QMailAddress("someone@example.net")); - m.setFrom(QMailAddress("someone@example.net")); - m.setSubject("multipart/mixed with attachment"); - - m.setMultipartType(QMailMessagePartContainer::MultipartMixed); - m.appendPart(p1); - m.appendPart(p2); - m.appendPart(p3); - QCOMPARE(m.contentType().toString().toLower(), - QByteArray("Content-Type: multipart/mixed").toLower()); - QCOMPARE(m.transferEncoding(), QMailMessageBody::NoEncoding); - QCOMPARE(m.partCount(), uint(3)); - for (uint i = 0; i < m.partCount(); ++i) - QCOMPARE( m.partAt(i).partNumber(), int(i) ); - - QList<QMailMessagePart::Location> indices = m.findAttachmentLocations(); - QCOMPARE(indices.size(), 1); - QCOMPARE(indices.at(0).toString(false), QStringLiteral("3")); + QTest::addColumn<QList<PartDefinition>>("structure"); + QTest::addColumn<QStringList>("attachments"); + + QTest::newRow("simple text") + << (QList<PartDefinition>() + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline)) + << QStringList(); + + QTest::newRow("multipart/alternative text-HTML") + << (QList<PartDefinition>() + << PartDefinition("multipart/alternative", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("text/html; charset=UTF-8", + QMailMessageContentDisposition::Inline)) + << QStringList(); + + QTest::newRow("multipart/mixed with calendar") + << (QList<PartDefinition>() + << PartDefinition("multipart/mixed", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("text/calendar; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("application/octet-stream; name=\"attach.pdf\"", + QMailMessageContentDisposition::Attachment)) + << (QStringList() << "3"); + + QTest::newRow("multipart/mixed with text attachment") + << (QList<PartDefinition>() + << PartDefinition("multipart/mixed", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Attachment)) + << (QStringList() << "2"); + + QTest::newRow("multipart/alternative recursive") + << (QList<PartDefinition>() + << PartDefinition("multipart/alternative", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("multipart/mixed", + QMailMessageContentDisposition::None) + << PartDefinition("text/html; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("application/octet-stream; name=\"attach.pdf\"", + QMailMessageContentDisposition::Attachment)) + << (QStringList() << "2.2"); + + QTest::newRow("multipart/signed PGP") + << (QList<PartDefinition>() + << PartDefinition("multipart/signed", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("application/pgp-signature", + QMailMessageContentDisposition::Inline)) + << QStringList(); + + QTest::newRow("multipart/signed S/MIME") + << (QList<PartDefinition>() + << PartDefinition("multipart/signed", + QMailMessageContentDisposition::None) + << PartDefinition("text/plain; charset=UTF-8", + QMailMessageContentDisposition::Inline) + << PartDefinition("application/pkcs7-signature", + QMailMessageContentDisposition::Attachment)) + << QStringList(); } -void tst_QMailMessage::recursiveAttachments() +void tst_QMailMessage::attachments() { - QByteArray data; - QByteArray type; - - QMailMessagePart p1; - type = "text/plain; charset=UTF-8"; - data = "P1: This is a plain text part."; - p1.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::EightBit, - QMailMessageBody::RequiresEncoding)); - - QMailMessagePart p3; - type = "text/html; charset=UTF-8"; - data = "<html></html>"; - p3.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::EightBit, - QMailMessageBody::RequiresEncoding)); - - QMailMessagePart p4; - type = "application/octet-stream; name=\"attach.pdf\""; - data = "abcdef"; - p4.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), - QMailMessageBody::Base64, - QMailMessageBody::AlreadyEncoded)); - p4.setContentDisposition(QMailMessageContentDisposition::Attachment); - - QMailMessagePart p2; - p2.setMultipartType(QMailMessagePartContainer::MultipartMixed); - p2.appendPart(p3); - p2.appendPart(p4); + QFETCH(QList<PartDefinition>, structure); + QFETCH(QStringList, attachments); QMailMessage m; m.setTo(QMailAddress("someone@example.net")); m.setFrom(QMailAddress("someone@example.net")); - m.setSubject("multipart/alternative with attachment in mixed"); + m.setSubject("multipart/mixed with attachment"); - m.setMultipartType(QMailMessagePartContainer::MultipartAlternative); - m.appendPart(p1); - m.appendPart(p2); - QCOMPARE(m.contentType().toString().toLower(), - QByteArray("Content-Type: multipart/alternative").toLower()); - QCOMPARE(m.transferEncoding(), QMailMessageBody::NoEncoding); - QCOMPARE(m.partCount(), uint(2)); - for (uint i = 0; i < m.partCount(); ++i) - QCOMPARE( m.partAt(i).partNumber(), int(i) ); - QCOMPARE(m.partAt(1).partCount(), uint(2)); - for (uint i = 0; i < m.partAt(1).partCount(); ++i) - QCOMPARE( m.partAt(1).partAt(i).partNumber(), int(i) ); + if (!structure[0].first.startsWith("multipart")) { + m.setBody(QMailMessageBody::fromData(QStringLiteral("some content"), + QMailMessageContentType(structure[0].first), + QMailMessageBody::QuotedPrintable)); + m.setContentDisposition(structure[0].second); + } else { + QList<PartDefinition>::ConstIterator it = structure.constBegin(); + m.setBody(QMailMessageBody::fromData(QString(), + QMailMessageContentType(it->first), + QMailMessageBody::NoEncoding)); + m.setContentDisposition(it->second); + QMailMessagePartContainer *lastContainer = &m; + for (it++; it != structure.constEnd(); it++) { + QMailMessagePart part; + if (it->first.startsWith("multipart")) { + part.setBody(QMailMessageBody::fromData(QString(), + QMailMessageContentType(it->first), + QMailMessageBody::NoEncoding)); + part.setContentDisposition(it->second); + lastContainer->appendPart(part); + lastContainer = &lastContainer->partAt(lastContainer->partCount() - 1); + } else { + part.setBody(QMailMessageBody::fromData(QStringLiteral("some content"), + QMailMessageContentType(it->first), + QMailMessageBody::QuotedPrintable)); + part.setContentDisposition(it->second); + lastContainer->appendPart(part); + } + } + } QList<QMailMessagePart::Location> indices = m.findAttachmentLocations(); - QCOMPARE(indices.size(), 1); - QCOMPARE(indices.at(0).toString(false), QStringLiteral("2.2")); + QCOMPARE(indices.size(), attachments.size()); + for (int i = 0; i < attachments.size(); i++) { + QCOMPARE(indices.at(i).toString(false), attachments[i]); + } } void tst_QMailMessage::copyAndAssign() |