diff options
author | Damien Caliste <dcaliste@free.fr> | 2018-12-03 13:44:53 +0100 |
---|---|---|
committer | Damien Caliste <dcaliste@free.fr> | 2018-12-18 11:54:16 +0000 |
commit | 03bdfab415b9e88165c0e2bad3d97eb0976d4a63 (patch) | |
tree | 94ba9fc0ba9adef184373c47d9a6588fe8f09de8 | |
parent | 3dc8e6f79caf1c8c108700be0f03df914e97821e (diff) |
Also generate boundaries when serializing QMailMessagePart
In a multipart messages, boundaries are generated when calling
QMailMessage::toRfc2822(). For signature purposes, there is a
need to generate RFC2822 compliant output for QMailMessagePart
only. Previous implementation of QMailMessagePart::toRfc2822()
introduced for signature purposes was lacking boundary
generation.
Change-Id: I7381cf2cb3a8bf83267f36e2f3f7369e8b040cef
Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
-rw-r--r-- | src/libraries/qmfclient/qmailmessage.cpp | 26 | ||||
-rw-r--r-- | src/libraries/qmfclient/qmailmessage_p.h | 1 | ||||
-rw-r--r-- | tests/tst_qmailmessagepart/tst_qmailmessagepart.cpp | 50 |
3 files changed, 69 insertions, 8 deletions
diff --git a/src/libraries/qmfclient/qmailmessage.cpp b/src/libraries/qmfclient/qmailmessage.cpp index cd8ca4b1..48b8b026 100644 --- a/src/libraries/qmfclient/qmailmessage.cpp +++ b/src/libraries/qmfclient/qmailmessage.cpp @@ -4223,6 +4223,20 @@ void QMailMessagePartContainerPrivate::setBoundary(const QByteArray& text) } } +static QByteArray boundaryString(const QByteArray &hash); +void QMailMessagePartContainerPrivate::generateBoundary() +{ + if (_multipartType != QMailMessagePartContainer::MultipartNone + && _boundary.isEmpty()) { + // Include a hash of the header data in the boundary + QCryptographicHash hash(QCryptographicHash::Md5); + foreach (const QByteArray *field, _header.fieldList()) + hash.addData(*field); + + setBoundary(boundaryString(hash.result())); + } +} + QMailMessageBody& QMailMessagePartContainerPrivate::body() { return _body; @@ -6413,6 +6427,9 @@ void QMailMessagePart::output(QDataStream& out, bool includeAttachments, bool ex QByteArray QMailMessagePart::toRfc2822() const { + // Generate boundaries for this part, as in QMailMessage::toRfc2822(). + const_cast<QMailMessagePartPrivate*>(impl(this))->generateBoundary(); + QByteArray result; QDataStream out(&result, QIODevice::WriteOnly); output(out, true, true); @@ -7967,14 +7984,7 @@ void QMailMessagePrivate::toRfc2822(QDataStream **out, QMailMessage::EncodingFor bool includeBcc = (format != QMailMessage::TransmissionFormat); bool excludeInternalFields = (format == QMailMessage::TransmissionFormat); - if (_messageParts.count() && boundary().isEmpty()) { - // Include a hash of the header data in the boundary - QCryptographicHash hash(QCryptographicHash::Md5); - foreach (const QByteArray* field, _header.fieldList()) - hash.addData(*field); - - const_cast<QMailMessagePrivate*>(this)->setBoundary(boundaryString(hash.result())); - } + const_cast<QMailMessagePrivate*>(this)->generateBoundary(); outputHeaders(**out, addTimeStamp, addContentHeaders, includeBcc, excludeInternalFields); **out << DataString('\n'); diff --git a/src/libraries/qmfclient/qmailmessage_p.h b/src/libraries/qmfclient/qmailmessage_p.h index d2c63d46..f8138814 100644 --- a/src/libraries/qmfclient/qmailmessage_p.h +++ b/src/libraries/qmfclient/qmailmessage_p.h @@ -216,6 +216,7 @@ public: QByteArray boundary() const; void setBoundary(const QByteArray& text); + void generateBoundary(); // Note: this returns a reference: QMailMessageBody& body(); diff --git a/tests/tst_qmailmessagepart/tst_qmailmessagepart.cpp b/tests/tst_qmailmessagepart/tst_qmailmessagepart.cpp index e3cf690e..ed6a6510 100644 --- a/tests/tst_qmailmessagepart/tst_qmailmessagepart.cpp +++ b/tests/tst_qmailmessagepart/tst_qmailmessagepart.cpp @@ -86,6 +86,7 @@ private slots: void appendHeaderField(); void removeHeaderField(); + void testToRfc2822(); void testSerialization(); }; @@ -340,6 +341,55 @@ void tst_QMailMessagePart::removeHeaderField() QCOMPARE(m.headerFields("Resent-From"), QList<QMailMessageHeaderField>()); } +void tst_QMailMessagePart::testToRfc2822() +{ + QMailMessagePart body = QMailMessagePart::fromData + (QStringLiteral("Some body text"), + QMailMessageContentDisposition(), + QMailMessageContentType("text/plain"), + QMailMessageBody::QuotedPrintable); + QMailMessagePart disposition = QMailMessagePart::fromData + (QByteArray(), + QMailMessageContentDisposition(), + QMailMessageContentType("message/disposition-notification"), + QMailMessageBody::NoEncoding); + disposition.setHeaderField("Original-Recipient", "foo@example.org"); + disposition.setHeaderField("Original-Message-ID", "123456789"); + + QMailMessagePart alt = QMailMessagePart::fromData + (QByteArray(), + QMailMessageContentDisposition(), + QMailMessageContentType(), + QMailMessageBodyFwd::NoEncoding); + alt.setMultipartType(QMailMessagePartContainer::MultipartAlternative); + alt.appendPart(body); + alt.appendPart(disposition); + + const QByteArray expected( +"Content-Type: multipart/alternative; boundary=\"[}<}]\"" CRLF +"Content-Disposition:" CRLF +CRLF +CRLF +"--[}<}]" CRLF +"Content-Type: text/plain" CRLF +"Content-Transfer-Encoding: quoted-printable" CRLF +"Content-Disposition:" CRLF +CRLF +"Some body text" CRLF +"--[}<}]" CRLF +"Content-Type: message/disposition-notification" CRLF +"Content-Disposition:" CRLF +"Original-Recipient: foo@example.org" CRLF +"Original-Message-ID: 123456789" CRLF +CRLF +CRLF +"--[}<}]--" CRLF +); + + const QByteArray serialized = alt.toRfc2822(); + QCOMPARE( serialized, expected ); +} + void tst_QMailMessagePart::testSerialization() { QByteArray data; |