diff options
author | Damien Caliste <dcaliste@free.fr> | 2018-09-14 11:01:38 +0200 |
---|---|---|
committer | Pekka Vuorela <pvuorela@iki.fi> | 2018-09-29 11:50:48 +0000 |
commit | d761a52dd051c10e59716c27e5dd2ce3eb32f7b2 (patch) | |
tree | 8f8a387a710571351a5cf02bb51aad5e40a08872 | |
parent | 066aff4b15160c6872c0e77f6ab2556aa293c185 (diff) |
Use codec detection when charset is unknown
For emails where the plain text (or the HTML version) is declared with an unknown charset,
the body()->data() of the text part (or the HTML one) is QString() empty.
Example of wrong declaration:
--0ec52789c76dd9f8e88d72dc967821ec
Content-Type: text/plain; charset=quoted-printable
Content-Transfer-Encoding: quoted-printable
Emails like that are definitely violating the standard and are indeed broken. But having
an empty display when viewing the email is not useful neither.
The issue is in QMailCodec::decode(), where the "if (codecForName())" has no fallback if
the codec does not exist. This commit is adding a fallback, assuming UTF-8 encoding.
Change-Id: I7b67cea999a2c1eb4211749d87a4ccb54daa332d
Reviewed-by: Pekka Vuorela <pvuorela@iki.fi>
Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au>
-rw-r--r-- | src/libraries/qmfclient/qmailcodec.cpp | 40 | ||||
-rw-r--r-- | tests/tst_qmailmessagebody/tst_qmailmessagebody.cpp | 11 |
2 files changed, 31 insertions, 20 deletions
diff --git a/src/libraries/qmfclient/qmailcodec.cpp b/src/libraries/qmfclient/qmailcodec.cpp index f34492a3..d5f168ea 100644 --- a/src/libraries/qmfclient/qmailcodec.cpp +++ b/src/libraries/qmfclient/qmailcodec.cpp @@ -160,32 +160,32 @@ void QMailCodec::encode(QDataStream& out, QTextStream& in, const QString& charse */ void QMailCodec::decode(QTextStream& out, QDataStream& in, const QString& icharset) { - if (QTextCodec* codec = codecForName(icharset.toLatin1())) + QByteArray decoded; { - QByteArray decoded; + QDataStream decodedStream(&decoded, QIODevice::WriteOnly); + + char* buffer = new char[MaxCharacters]; + while (!in.atEnd()) { - QDataStream decodedStream(&decoded, QIODevice::WriteOnly); - - char* buffer = new char[MaxCharacters]; - while (!in.atEnd()) - { - int length = in.readRawData(buffer, MaxCharacters); + int length = in.readRawData(buffer, MaxCharacters); - // Allow for decoded data to be twice the size without reallocation - decoded.reserve(decoded.size() + (MaxCharacters * 2)); + // Allow for decoded data to be twice the size without reallocation + decoded.reserve(decoded.size() + (MaxCharacters * 2)); - decodeChunk(decodedStream, buffer, length, in.atEnd()); - } - delete [] buffer; + decodeChunk(decodedStream, buffer, length, in.atEnd()); } - - // This is an unfortunately-necessary copy operation; we should investigate - // using QTextCodec::makeDecoder, and adding a factory method to - // QMailMessagePartContainer that returns a readable QIODevice* - QString unicode = codec->toUnicode(decoded); - out << unicode; - out.flush(); + delete [] buffer; } + QTextCodec* codec = codecForName(icharset.toLatin1()); + if (!codec) + codec = QTextCodec::codecForUtfText(decoded, codecForName("UTF-8")); + + // This is an unfortunately-necessary copy operation; we should investigate + // using QTextCodec::makeDecoder, and adding a factory method to + // QMailMessagePartContainer that returns a readable QIODevice* + QString unicode = codec->toUnicode(decoded); + out << unicode; + out.flush(); } /*! diff --git a/tests/tst_qmailmessagebody/tst_qmailmessagebody.cpp b/tests/tst_qmailmessagebody/tst_qmailmessagebody.cpp index b2c6602e..1591e556 100644 --- a/tests/tst_qmailmessagebody/tst_qmailmessagebody.cpp +++ b/tests/tst_qmailmessagebody/tst_qmailmessagebody.cpp @@ -505,6 +505,17 @@ void tst_QMailMessageBody::fromFile_data() << QByteArray() << string_source << ( QStringList() << "text" << "plain" << "UTF-8" ); + + QTest::newRow("unknown charset") + << QString::fromLatin1(encode(string_source.toUtf8(), QMailMessageBody::Base64)) + << QByteArray() + << QByteArray("text/plain; charset=this-is-not-a-valid-charset") + << QMailMessageBody::Base64 + << QMailMessageBody::AlreadyEncoded + << encode(string_source.toUtf8(), QMailMessageBody::Base64) + << QByteArray() + << string_source + << ( QStringList() << "text" << "plain" << "this-is-not-a-valid-charset" ); } void tst_QMailMessageBody::fromFile() |