Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
messagelib
0001-Fix-fallback-path-in-MessageFactoryNG-appl...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Fix-fallback-path-in-MessageFactoryNG-applyCharset.patch of Package messagelib
From a70416bedf7c2358584aacb774fd0731a20986c9 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Tue, 7 Mar 2023 21:32:18 +0100 Subject: [PATCH] Fix fallback path in MessageFactoryNG::applyCharset In the case that the codec of the original message could not encode the reply, it was still set as charset but the body encoded with the fallback codec. This resulted in replies having messed up encoding. It can be triggered by replying to multipart mails which define the charset in parts only or if the reply template ends up with other special characters. BUG: 447297 BUG: 443009 BUG: 298349 (cherry picked from commit 29a5a05e2078b75f0a994e29e92707e3ec81e2d1) --- .../autotests/messagefactoryngtest.cpp | 64 +++++++++++++++++++ .../autotests/messagefactoryngtest.h | 3 + .../src/helper/messagefactoryng.cpp | 9 +-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/messagecomposer/autotests/messagefactoryngtest.cpp b/messagecomposer/autotests/messagefactoryngtest.cpp index 5856780f7..2d156e666 100644 --- a/messagecomposer/autotests/messagefactoryngtest.cpp +++ b/messagecomposer/autotests/messagefactoryngtest.cpp @@ -947,3 +947,67 @@ void MessageFactoryTest::test_multipartAlternative() QCOMPARE(reply.msg->contents().at(contentAt)->encodedBody().data(), expected.toLatin1().data()); origMsg.clear(); } + +KMime::Message::Ptr MessageFactoryTest::createReplyAllForMessage(KMime::Message::Ptr origMsg) +{ + MessageFactoryNG factory(origMsg, 0); + factory.setIdentityManager(mIdentMan); + factory.setQuote(true); + factory.setReplyStrategy(ReplyAll); + + QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone); + factory.createReplyAsync(); + spy.wait(); + return spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>().msg; +} + +void MessageFactoryTest::testCreateReplyWithForcedCharset() +{ + KMime::Message::Ptr origMsg(new KMime::Message); + QByteArray origMail = + "From: from@example.com\n" + "To: to@example.com\n" + "Sender: from@example.com\n" + "Subject: Test\n" + "Content-Type: text/plain; charset=iso-8859-1\n" + "\n" + "Test \xC4\n"; + origMsg->setContent(origMail); + origMsg->parse(); + + QCOMPARE(origMsg->contentType()->charset(), QByteArray("iso-8859-1")); + QCOMPARE(origMsg->body(), QByteArray("Test \xC4\n")); + + MessageComposerSettings::self()->setPreferredCharsets(QStringList() << QStringLiteral("utf-8")); + TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QString::fromUtf8("%QUOTE")); + + { + // The reply should use the same charset as the original mail + MessageComposerSettings::self()->setForceReplyCharset(true); + + auto msg = createReplyAllForMessage(origMsg); + QCOMPARE(msg->contentType()->charset(), QByteArray("iso-8859-1")); + QCOMPARE(msg->body(), QByteArray("> Test \xC4")); + } + + // The Euro symbol can't be encoded in ISO-8859-1, so it has to choose UTF-8 instead + TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QString::fromUtf8("\xE2\x82\xAC%QUOTE")); + + { + // Use the preferred charset, UTF-8 + MessageComposerSettings::self()->setForceReplyCharset(false); + + auto msg = createReplyAllForMessage(origMsg); + QCOMPARE(msg->contentType()->charset(), QByteArray("UTF-8")); + QCOMPARE(msg->body(), QByteArray("\xE2\x82\xAC> Test \xC3\x84")); + } + + { + // It should try to keep ISO-8859-1 but fall back to UTF-8 + MessageComposerSettings::self()->setForceReplyCharset(true); + + auto msg = createReplyAllForMessage(origMsg); + QCOMPARE(msg->contentType()->charset(), QByteArray("UTF-8")); + QCOMPARE(msg->body(), QByteArray("\xE2\x82\xAC> Test \xC3\x84")); + } +} diff --git a/messagecomposer/autotests/messagefactoryngtest.h b/messagecomposer/autotests/messagefactoryngtest.h index 8e54aec3f..b4bb812d6 100644 --- a/messagecomposer/autotests/messagefactoryngtest.h +++ b/messagecomposer/autotests/messagefactoryngtest.h @@ -53,10 +53,13 @@ private Q_SLOTS: void testCreateReplyToAllWithUseSenderByNoSameIdentitiesAsync(); void testCreateReplyToAllWithUseSenderAndIdentityInCCAsync(); + void testCreateReplyWithForcedCharset(); + void cleanupTestCase(); private: Q_REQUIRED_RESULT KMime::Message::Ptr createPlainTestMessage(); Q_REQUIRED_RESULT KMime::Message::Ptr createPlainTestMessageWithMultiEmails(); + Q_REQUIRED_RESULT KMime::Message::Ptr createReplyAllForMessage(KMime::Message::Ptr origMsg); KIdentityManagement::IdentityManager *mIdentMan = nullptr; }; diff --git a/messagecomposer/src/helper/messagefactoryng.cpp b/messagecomposer/src/helper/messagefactoryng.cpp index 4b15ef430..da2990e52 100644 --- a/messagecomposer/src/helper/messagefactoryng.cpp +++ b/messagecomposer/src/helper/messagefactoryng.cpp @@ -938,11 +938,10 @@ void MessageFactoryNG::applyCharset(const KMime::Message::Ptr msg) const QString body = bodyCodec->toUnicode(msg->body()); // then apply the encoding of the original message - msg->contentType()->setCharset(mOrigMsg->contentType()->charset()); - - QTextCodec *codec = KCharsets::charsets()->codecForName(QString::fromLatin1(msg->contentType()->charset())); + QTextCodec *codec = KCharsets::charsets()->codecForName(QString::fromLatin1(mOrigMsg->contentType()->charset())); if (!codec) { - qCCritical(MESSAGECOMPOSER_LOG) << "Could not get text codec for charset" << msg->contentType()->charset(); + qCCritical(MESSAGECOMPOSER_LOG) << "Could not get text codec for charset" << mOrigMsg->contentType()->charset(); + // Don't touch the message } else if (!codec->canEncode(body)) { // charset can't encode body, fall back to preferred const QStringList charsets = MessageComposer::MessageComposerSettings::preferredCharsets(); @@ -958,8 +957,10 @@ void MessageFactoryNG::applyCharset(const KMime::Message::Ptr msg) } codec = KCharsets::charsets()->codecForName(QString::fromLatin1(fallbackCharset)); + msg->contentType()->setCharset(codec->name()); msg->setBody(codec->fromUnicode(body)); } else { + msg->contentType()->setCharset(mOrigMsg->contentType()->charset()); msg->setBody(codec->fromUnicode(body)); } } -- 2.39.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor