Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package messagelib for openSUSE:Factory checked in at 2023-03-11 18:22:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/messagelib (Old) and /work/SRC/openSUSE:Factory/.messagelib.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "messagelib" Sat Mar 11 18:22:54 2023 rev:96 rq:1070450 version:22.12.3 Changes: -------- --- /work/SRC/openSUSE:Factory/messagelib/messagelib.changes 2023-03-03 22:27:14.859093841 +0100 +++ /work/SRC/openSUSE:Factory/.messagelib.new.31432/messagelib.changes 2023-03-11 18:22:55.878533930 +0100 @@ -1,0 +2,6 @@ +Thu Mar 9 13:16:20 UTC 2023 - Fabian Vogt <fab...@ritter-vogt.de> + +- Add patch to fix encoding of replies (kde#447297, kde#443009, kde#298349): + * 0001-Fix-fallback-path-in-MessageFactoryNG-applyCharset.patch + +------------------------------------------------------------------- New: ---- 0001-Fix-fallback-path-in-MessageFactoryNG-applyCharset.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ messagelib.spec ++++++ --- /var/tmp/diff_new_pack.cxdT8P/_old 2023-03-11 18:22:56.394536619 +0100 +++ /var/tmp/diff_new_pack.cxdT8P/_new 2023-03-11 18:22:56.398536640 +0100 @@ -30,6 +30,8 @@ Source1: https://download.kde.org/stable/release-service/%{version}/src/%{name}-%{version}.tar.xz.sig Source2: applications.keyring %endif +# PATCH-FIX-UPSTREAM +Patch1: 0001-Fix-fallback-path-in-MessageFactoryNG-applyCharset.patch BuildRequires: extra-cmake-modules BuildRequires: kf5-filesystem BuildRequires: libQt5Sql-private-headers-devel ++++++ 0001-Fix-fallback-path-in-MessageFactoryNG-applyCharset.patch ++++++ >From a70416bedf7c2358584aacb774fd0731a20986c9 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fab...@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: f...@example.com\n" + "To: t...@example.com\n" + "Sender: f...@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