diff options
-rw-r--r-- | user/trojita/APKBUILD | 33 | ||||
-rw-r--r-- | user/trojita/attachments.patch | 68 | ||||
-rw-r--r-- | user/trojita/deprecated1.patch | 369 | ||||
-rw-r--r-- | user/trojita/deprecated2.patch | 28 | ||||
-rw-r--r-- | user/trojita/deprecated3.patch | 37 | ||||
-rw-r--r-- | user/trojita/fetch-task.patch | 204 | ||||
-rw-r--r-- | user/trojita/plaintext-upgrade-attack.patch | 221 | ||||
-rw-r--r-- | user/trojita/pwstorage.patch | 52 | ||||
-rw-r--r-- | user/trojita/segfault-sorting-mailboxes.patch | 72 | ||||
-rw-r--r-- | user/trojita/signedness.patch | 71 | ||||
-rw-r--r-- | user/trojita/statusbar-fix.patch | 167 | ||||
-rw-r--r-- | user/trojita/testfix.patch | 85 |
12 files changed, 1404 insertions, 3 deletions
diff --git a/user/trojita/APKBUILD b/user/trojita/APKBUILD index a78279253..265b1850a 100644 --- a/user/trojita/APKBUILD +++ b/user/trojita/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Sheila Aman <sheila@vulpine.house> pkgname=trojita pkgver=0.7 -pkgrel=1 +pkgrel=2 pkgdesc="Qt-based IMAP email client" url="http://trojita.flaska.net/" arch="all" @@ -18,6 +18,17 @@ source="https://sourceforge.net/projects/trojita/files/src/trojita-$pkgver.tar.x fix-gpg.patch CVE-2019-10734.patch CVE-2020-15047.patch + attachments.patch + fetch-task.patch + testfix.patch + plaintext-upgrade-attack.patch + pwstorage.patch + segfault-sorting-mailboxes.patch + signedness.patch + statusbar-fix.patch + deprecated1.patch + deprecated2.patch + deprecated3.patch " # secfixes: @@ -25,6 +36,11 @@ source="https://sourceforge.net/projects/trojita/files/src/trojita-$pkgver.tar.x # - CVE-2019-10734 # - CVE-2020-15047 +prepare() { + default_prepare + sed -e "s/--dirty//" -i "$builddir"/cmake/TrojitaVersion.cmake +} + build() { if [ "$CBUILD" != "$CHOST" ]; then CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux" @@ -34,7 +50,7 @@ build() { -DCMAKE_INSTALL_LIBDIR=lib \ -DBUILD_SHARED_LIBS=True \ -DCMAKE_BUILD_TYPE=RelWithDebugInfo \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS" \ + -DCMAKE_CXX_FLAGS="$CXXFLAGS -Wno-deprecated" \ -DCMAKE_C_FLAGS="$CFLAGS" \ -DWITH_GPGMEPP=ON \ ${CMAKE_CROSSOPTS} . @@ -54,4 +70,15 @@ sha512sums="fe4d9316f97d913619f27d24a5023c3d8dd4a6b9fb058651be12c67188f394aa8cbb 740c2410d7236d722482f05dd1d2c681e35543620823cb7c1396710081f9de4f6ae530c5b5442ecf5d08a8e552f0697f3a35bf51e07a3b4336dec7021b665706 use-qgpgme.patch 9d0fbf7c0b0f6975990a7705f9d43043e5807401cee179d7a07f9514856332d6bb1aa8448e84d0083003c34a3bb181080b973e8c1f77d1b5a8930d07d57702da fix-gpg.patch db96a566924b5d7b80787ab624af3726d5dd3459653192436a377d6482ab73801a7dcca1df1b1d937cf0d0798b827e04f8ef2c1124f91dc9da3e8036ef61e28a CVE-2019-10734.patch -2477612aca1e558fa3ba2b434a701cc255c573ac7e2001e7b5921c9b991f7c95720f53b70b49824e36bafb53ab53477950cb8d436e637fda4d59c7ec5883ce5f CVE-2020-15047.patch" +2477612aca1e558fa3ba2b434a701cc255c573ac7e2001e7b5921c9b991f7c95720f53b70b49824e36bafb53ab53477950cb8d436e637fda4d59c7ec5883ce5f CVE-2020-15047.patch +714b6d3b8a791783039f51d98b5d14b2b01ec3228993500623c980c09d04c38e6f26d236efa7fc722d68cd72692b646e5c4b2ca13d3d9b342e2072afb466ded0 attachments.patch +af6d1951fe89a1347b0793175e2348c9cf883792bd576cead9cd70b83546d3dd29a59390c167e76d67413f822368d16892f11dac08da2ce0d9ed53e51b2c0d52 fetch-task.patch +762c10e004e51d229f5a88410b049716abe3bd25f7ff904b031c1d6ed4a637449e47e2219c5ac85db36517d7599f48cd8a15a0cc2d87ba9e5cba79d483bf8d84 testfix.patch +1ed2feb300304c58902e034767747610641c998b7a33fede01ff850b298074a04b0aa23332f8b37ecd9d798c35126d0d8f2e7560699c672a2195f110891cbe1a plaintext-upgrade-attack.patch +86f5dce6bbc7926105bb2950aa15ca469a65cb29d1197d660a3de8ebbe19bb54a945803c542540c168f0b9dc3bfbde58e160bb4f47e0c418fcbb81744f3f60a2 pwstorage.patch +93b8e795ef3f4423f1a1cce4ca87d146252af33259be2ed597af822a5c8b4abca2292055799c5b5ab70983b8dbba667e516dfe28e6c26705266f3f05b275ad4b segfault-sorting-mailboxes.patch +83fd69307bb6c34c72a566e06674cc63f330d967d50812067c66633d9cfeb450410257042d489d4be591af383725e5d5f465421675065140fab6c6a40ab55484 signedness.patch +b17f19a7c9a02fbf711b6e960bf9679caf591c35b59ec636293d341286135aaef7e6d137076502a2087375d30bf75cd5c8d67bcf726f75b0ab76aae0d8f24927 statusbar-fix.patch +7a7d71e415c2b3e11c962eedf5fe3b5b22579fc86855a904a8d4c1ee2bf300d0872e0a9081644c33b197b2ad5eda9b0209fe7bccfcce466efd9924ea52282fe5 deprecated1.patch +2f1c1de165f8fede77cbb0fe9a5cc1139def4d903692adefcc25a14fcec0c50f1070d458ddaa17bdb2c999f54c3dbf6e6403ccd5c897f4c861a1df7d121e978a deprecated2.patch +bce7713fb5bef29b2b189d281dee57ddfc57f1c0601f424aba2185668215878b9bfd3bb80f0d2f8b73219e782db5e64973e79190fe62afa8ba98327535139146 deprecated3.patch" diff --git a/user/trojita/attachments.patch b/user/trojita/attachments.patch new file mode 100644 index 000000000..38d11316e --- /dev/null +++ b/user/trojita/attachments.patch @@ -0,0 +1,68 @@ +From cf2364b80fa8ae844df8350cd5833d47cce235f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Mon, 9 Mar 2020 08:24:48 -0700 +Subject: [PATCH] Fix possible crash when downloading attachments + +Turns out we've been happily deleting network replies from the +QNetworkReply::finished(). That was never a good thing to do, but it did +not use to crash with older Qt. Now it does. + +After changing to deleteLater(), there's a window for +already-deregistered replies to generate events, therefore the assert +has to go, too, otherwise Bad Things happen: + + (gdb) bt + #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 + #1 0x00007ffff16bdcd2 in __GI_abort () at abort.c:89 + #2 0x00007ffff2400bcb in qt_message_fatal (context=..., message=<synthetic pointer>...) at /var/tmp/portage/dev-qt/qtcore-5.13.9999/work/qtcore-5.13.9999/src/corelib/global/qlogging.cpp:1904 + #3 QMessageLogger::fatal (this=this@entry=0x7fffffffc990, msg=msg@entry=0x7ffff2690b10 "ASSERT: \"%s\" in file %s, line %d") at /var/tmp/portage/dev-qt/qtcore-5.13.9999/work/qtcore-5.13.9999/src/corelib/global/qlogging.cpp:888 + #4 0x00007ffff23fff7c in qt_assert (assertion=assertion@entry=0x5555558451d7 "reply", file=file@entry=0x555555841a38 "/home/jkt/work/prog/trojita/src/Imap/Network/FileDownloadManager.cpp", line=line@entry=142) + at /var/tmp/portage/dev-qt/qtcore-5.13.9999/work/qtcore-5.13.9999/src/corelib/global/qglobal.cpp:3247 + #5 0x00005555555da840 in Imap::Network::FileDownloadManager::onPartDataTransfered (this=0x555556a20990) + #6 0x00007ffff25f1bdf in QtPrivate::QSlotObjectBase::call (a=0x7fffffffcaa0, r=0x555556a20990, this=0x5555569f99c0) at ../../include/QtCore/../../../qtcore-5.13.9999/src/corelib/kernel/qobjectdefs_impl.h:394 + #7 QMetaObject::activate(QObject*, int, int, void**) () at /var/tmp/portage/dev-qt/qtcore-5.13.9999/work/qtcore-5.13.9999/src/corelib/kernel/qobject.cpp:3787 + #8 0x00007ffff25f20b7 in QMetaObject::activate (sender=sender@entry=0x555556a21370, m=m@entry=0x7ffff3f96b00 <QNetworkReply::staticMetaObject>, local_signal_index=local_signal_index@entry=1, argv=argv@entry=0x0) + at /var/tmp/portage/dev-qt/qtcore-5.13.9999/work/qtcore-5.13.9999/src/corelib/kernel/qobject.cpp:3658 + #9 0x00007ffff3d3cbf3 in QNetworkReply::finished (this=this@entry=0x555556a21370) at .moc/moc_qnetworkreply.cpp:385 + #10 0x0000555555709485 in Imap::Network::MsgPartNetworkReply::slotMyDataChanged() () at /home/jkt/work/prog/trojita/src/Imap/Network/MsgPartNetworkReply.cpp:112 + +BUG: 417697 +Reported-by: Stefan de Konink <stefan@konink.de> +Change-Id: I79f340c5a471430a14474472513d0a055c7238d6 +--- + src/Imap/Network/FileDownloadManager.cpp | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/Imap/Network/FileDownloadManager.cpp b/src/Imap/Network/FileDownloadManager.cpp +index 16b6c8df..c3f72176 100644 +--- a/src/Imap/Network/FileDownloadManager.cpp ++++ b/src/Imap/Network/FileDownloadManager.cpp +@@ -139,7 +139,9 @@ void FileDownloadManager::downloadMessage() + + void FileDownloadManager::onPartDataTransfered() + { +- Q_ASSERT(reply); ++ if (!reply) { ++ return; ++ } + if (reply->error() == QNetworkReply::NoError) { + if (!saving.open(QIODevice::WriteOnly)) { + emit transferError(saving.errorString()); +@@ -192,11 +194,11 @@ void FileDownloadManager::onCombinerTransferError(const QString &message) + + void FileDownloadManager::deleteReply(QNetworkReply *reply) + { +- if (reply == this->reply) { ++ if (reply && reply == this->reply) { + if (!saved) + onPartDataTransfered(); +- delete reply; +- this->reply = 0; ++ reply->deleteLater(); ++ this->reply = nullptr; + } + } + +-- +GitLab + diff --git a/user/trojita/deprecated1.patch b/user/trojita/deprecated1.patch new file mode 100644 index 000000000..e09c0c573 --- /dev/null +++ b/user/trojita/deprecated1.patch @@ -0,0 +1,369 @@ +From 297f0d5a1df9c1b9ca5e9287bb2e603985c232cf Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 1 Feb 2022 17:06:49 +0100 +Subject: [PATCH 1/6] Port away from deprecated qSort to std::sort + +--- + src/Imap/Model/MailboxTree.cpp | 2 +- + src/Imap/Model/Model.cpp | 7 +++---- + src/Imap/Model/ThreadingMsgListModel.cpp | 2 +- + src/Imap/Parser/Sequence.cpp | 3 ++- + src/Imap/Tasks/ObtainSynchronizedMailboxTask.cpp | 2 +- + src/Imap/Tasks/SortTask.cpp | 2 +- + 6 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/Imap/Model/MailboxTree.cpp b/src/Imap/Model/MailboxTree.cpp +index e61f59c5..d9a03fc3 100644 +--- a/src/Imap/Model/MailboxTree.cpp ++++ b/src/Imap/Model/MailboxTree.cpp +@@ -590,7 +590,7 @@ void TreeItemMailbox::handleVanished(Model *const model, const Responses::Vanish + QModelIndex listIndex = list->toIndex(model); + + auto uids = resp.uids; +- qSort(uids); ++ std::sort(uids.begin(), uids.end()); + // Remove duplicates -- even that garbage can be present in a perfectly valid VANISHED :( + uids.erase(std::unique(uids.begin(), uids.end()), uids.end()); + +diff --git a/src/Imap/Model/Model.cpp b/src/Imap/Model/Model.cpp +index 1d539e22..aff8ea43 100644 +--- a/src/Imap/Model/Model.cpp ++++ b/src/Imap/Model/Model.cpp +@@ -25,7 +25,6 @@ + #include <QAuthenticator> + #include <QCoreApplication> + #include <QDebug> +-#include <QtAlgorithms> + #include "Model.h" + #include "Common/FindWithUnknown.h" + #include "Common/InvokeMethod.h" +@@ -350,7 +349,7 @@ void Model::finalizeList(Parser *parser, TreeItemMailbox *mailboxPtr) + ++it; + } + } +- qSort(mailboxes.begin(), mailboxes.end(), MailboxNameComparator); ++ std::sort(mailboxes.begin(), mailboxes.end(), MailboxNameComparator); + + // Remove duplicates; would be great if this could be done in a STLish way, + // but unfortunately std::unique won't help here (the "duped" part of the +@@ -406,7 +405,7 @@ void Model::finalizeIncrementalList(Parser *parser, const QString &parentMailbox + ++it; + } + } +- qSort(mailboxes.begin(), mailboxes.end(), MailboxNameComparator); ++ std::sort(mailboxes.begin(), mailboxes.end(), MailboxNameComparator); + + if (mailboxes.size() == 0) { + qDebug() << "Weird, no matching LIST response for our prompt after CREATE"; +@@ -1259,7 +1258,7 @@ void Model::copyMoveMessages(TreeItemMailbox *sourceMbox, const QString &destMai + + Q_ASSERT(sourceMbox); + +- qSort(uids); ++ std::sort(uids.begin(), uids.end()); + + QModelIndexList messages; + Sequence seq; +diff --git a/src/Imap/Model/ThreadingMsgListModel.cpp b/src/Imap/Model/ThreadingMsgListModel.cpp +index 29786022..76ef94c2 100644 +--- a/src/Imap/Model/ThreadingMsgListModel.cpp ++++ b/src/Imap/Model/ThreadingMsgListModel.cpp +@@ -718,7 +718,7 @@ void ThreadingMsgListModel::slotIncrementalThreadingAvailable(const Responses::E + for (Responses::ESearch::IncrementalThreadingData_t::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) { + gatherAllUidsFromThreadNode(affectedUids, it->thread); + } +- qSort(affectedUids); ++ std::sort(affectedUids.begin(), affectedUids.end()); + QList<TreeItemMessage*> affectedMessages = const_cast<Model*>(realModel)-> + findMessagesByUids(static_cast<TreeItemMailbox*>(mailboxIndex.internalPointer()), affectedUids); + QHash<uint,void *> uidToPtrCache; +diff --git a/src/Imap/Parser/Sequence.cpp b/src/Imap/Parser/Sequence.cpp +index 31b257bb..0e2cd314 100644 +--- a/src/Imap/Parser/Sequence.cpp ++++ b/src/Imap/Parser/Sequence.cpp +@@ -23,6 +23,7 @@ + #include "Sequence.h" + #include <QStringList> + #include <QTextStream> ++#include <algorithm> + + namespace Imap + { +@@ -114,7 +115,7 @@ Sequence &Sequence::add(uint num) + Sequence Sequence::fromVector(Imap::Uids numbers) + { + Q_ASSERT(!numbers.isEmpty()); +- qSort(numbers); ++ std::sort(numbers.begin(), numbers.end()); + Sequence seq(numbers.first()); + for (int i = 1; i < numbers.size(); ++i) { + seq.add(numbers[i]); +diff --git a/src/Imap/Tasks/ObtainSynchronizedMailboxTask.cpp b/src/Imap/Tasks/ObtainSynchronizedMailboxTask.cpp +index 9d6f8279..89fdf4ef 100644 +--- a/src/Imap/Tasks/ObtainSynchronizedMailboxTask.cpp ++++ b/src/Imap/Tasks/ObtainSynchronizedMailboxTask.cpp +@@ -974,7 +974,7 @@ void ObtainSynchronizedMailboxTask::finalizeSearch() + } + } + +- qSort(uidMap); ++ std::sort(uidMap.begin(), uidMap.end()); + if (!uidMap.isEmpty() && uidMap.front() == 0) { + throw MailboxException("UID (E)SEARCH response contains invalid UID zero"); + } +diff --git a/src/Imap/Tasks/SortTask.cpp b/src/Imap/Tasks/SortTask.cpp +index 347ec85e..8c2b4d69 100644 +--- a/src/Imap/Tasks/SortTask.cpp ++++ b/src/Imap/Tasks/SortTask.cpp +@@ -179,7 +179,7 @@ bool SortTask::handleSearch(const Imap::Responses::Search *const resp) + // That just doesn't look like worth it. + + sortResult += resp->items; +- qSort(sortResult); ++ std::sort(sortResult.begin(), sortResult.end()); + sortResult.erase(std::unique(sortResult.begin(), sortResult.end()), sortResult.end()); + return true; + } +-- +GitLab + + +From 268637f7b63059a065dffcb87c13166ebb0d3d3f Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 1 Feb 2022 17:31:43 +0100 +Subject: [PATCH 2/6] Port away from deprecated qFind to std::find + +--- + src/Imap/Model/ThreadingMsgListModel.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/Imap/Model/ThreadingMsgListModel.cpp b/src/Imap/Model/ThreadingMsgListModel.cpp +index 76ef94c2..58b606a5 100644 +--- a/src/Imap/Model/ThreadingMsgListModel.cpp ++++ b/src/Imap/Model/ThreadingMsgListModel.cpp +@@ -1130,7 +1130,7 @@ void ThreadingMsgListModel::pruneTree() + Q_ASSERT(parent != threading.end()); + + // and the node itself has to be found in its parent's children +- QList<uint>::iterator childIt = qFind(parent->children.begin(), parent->children.end(), it->internalId); ++ QList<uint>::iterator childIt = std::find(parent->children.begin(), parent->children.end(), it->internalId); + Q_ASSERT(childIt != parent->children.end()); + // The offset of this child might no longer be correct, though -- we're postponing the actual deletion until later + +@@ -1175,7 +1175,7 @@ void ThreadingMsgListModel::pruneTree() + + if (parent->internalId == 0) { + // Update the list of all thread roots +- QList<uint>::iterator rootIt = qFind(threadedRootIds.begin(), threadedRootIds.end(), it->internalId); ++ QList<uint>::iterator rootIt = std::find(threadedRootIds.begin(), threadedRootIds.end(), it->internalId); + if (rootIt != threadedRootIds.end()) + *rootIt = replaceWith->internalId; + } +-- +GitLab + + +From f06067dfa9bbb28cc385e526e9a7b261fe8448bc Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 1 Feb 2022 17:33:32 +0100 +Subject: [PATCH 3/6] Port away from deprecated qLowerBound to std::lower_bound + +--- + src/Imap/Parser/Sequence.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Imap/Parser/Sequence.cpp b/src/Imap/Parser/Sequence.cpp +index 0e2cd314..55adb6aa 100644 +--- a/src/Imap/Parser/Sequence.cpp ++++ b/src/Imap/Parser/Sequence.cpp +@@ -106,7 +106,7 @@ Imap::Uids Sequence::toVector() const + Sequence &Sequence::add(uint num) + { + Q_ASSERT(kind == DISTINCT); +- auto it = qLowerBound(numbers.begin(), numbers.end(), num); ++ auto it = std::lower_bound(numbers.begin(), numbers.end(), num); + if (it == numbers.end() || *it != num) + numbers.insert(it, num); + return *this; +-- +GitLab + + +From b7e9532a3209d64c15937e29b359be40fbd2fff7 Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 1 Feb 2022 17:34:15 +0100 +Subject: [PATCH 4/6] Port away from deprecated qLess to std::less + +--- + tests/Misc/test_algorithms.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tests/Misc/test_algorithms.cpp b/tests/Misc/test_algorithms.cpp +index a9a53745..86ce9e16 100644 +--- a/tests/Misc/test_algorithms.cpp ++++ b/tests/Misc/test_algorithms.cpp +@@ -21,6 +21,7 @@ + */ + + #include <QTest> ++#include <functional> + #include "test_algorithms.h" + + #include "Common/FindWithUnknown.h" +@@ -38,9 +39,9 @@ void TestCommonAlgorithms::testLowerBoundWithUnknown() + QFETCH(int, needle); + QFETCH(int, offset); + +- QList<int>::const_iterator it = Common::linearLowerBoundWithUnknownElements(list.constBegin(), list.constEnd(), needle, isZero, qLess<int>()); ++ QList<int>::const_iterator it = Common::linearLowerBoundWithUnknownElements(list.constBegin(), list.constEnd(), needle, isZero, std::less<int>()); + QCOMPARE(it - list.constBegin(), offset); +- it = Common::lowerBoundWithUnknownElements(list.constBegin(), list.constEnd(), needle, isZero, qLess<int>()); ++ it = Common::lowerBoundWithUnknownElements(list.constBegin(), list.constEnd(), needle, isZero, std::less<int>()); + QCOMPARE(it - list.constBegin(), offset); + } + +-- +GitLab + + +From 42ea2f0ec8de8fc2ea3e607d0b694dbd30e3ffaf Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Sat, 29 Jan 2022 23:54:40 +0100 +Subject: [PATCH 5/6] Port from the deprecated QProcess::error() to + errorOccurred + +Raises the Qt requirement to 5.6. +--- + CMakeLists.txt | 3 ++- + src/MSA/Sendmail.cpp | 2 +- + src/Streams/IODeviceSocket.cpp | 2 +- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a3d54166..54512029 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -69,7 +69,7 @@ else() + set(QTKEYCHAIN_DEPENDS "") + endif() + +-find_package(Qt5Core 5.2 REQUIRED) ++find_package(Qt5Core 5.6 REQUIRED) + find_package(Qt5Gui REQUIRED) + find_package(Qt5Network REQUIRED) + find_package(Qt5Sql REQUIRED) +@@ -183,6 +183,7 @@ add_definitions(-DQT_STRICT_ITERATORS) + add_definitions(-DQT_USE_QSTRINGBUILDER) + add_definitions(-DQT_USE_FAST_OPERATOR_PLUS) + add_definitions(-DQT_USE_FAST_CONCATENATION) ++add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050600) + + if(NOT MSVC) + # We're using C++11's threading features (std::async in particular), and that requires "some threading". With GCC and +diff --git a/src/MSA/Sendmail.cpp b/src/MSA/Sendmail.cpp +index f72f4927..d88d16c4 100644 +--- a/src/MSA/Sendmail.cpp ++++ b/src/MSA/Sendmail.cpp +@@ -30,7 +30,7 @@ Sendmail::Sendmail(QObject *parent, const QString &command, const QStringList &a + proc = new QProcess(this); + connect(proc, &QProcess::started, this, &Sendmail::handleStarted); + connect(proc, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, &Sendmail::handleFinished); +- connect(proc, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, &Sendmail::handleError); ++ connect(proc, &QProcess::errorOccurred, this, &Sendmail::handleError); + connect(proc, &QIODevice::bytesWritten, this, &Sendmail::handleBytesWritten); + } + +diff --git a/src/Streams/IODeviceSocket.cpp b/src/Streams/IODeviceSocket.cpp +index 7998028d..90f8470e 100644 +--- a/src/Streams/IODeviceSocket.cpp ++++ b/src/Streams/IODeviceSocket.cpp +@@ -141,7 +141,7 @@ ProcessSocket::ProcessSocket(QProcess *proc, const QString &executable, const QS + IODeviceSocket(proc), executable(executable), args(args) + { + connect(proc, &QProcess::stateChanged, this, &ProcessSocket::handleStateChanged); +- connect(proc, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, &ProcessSocket::handleProcessError); ++ connect(proc, &QProcess::errorOccurred, this, &ProcessSocket::handleProcessError); + } + + ProcessSocket::~ProcessSocket() +-- +GitLab + + +From aee63baa14f3fc318d4aac67b2c740067ffc7929 Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 1 Feb 2022 17:52:12 +0100 +Subject: [PATCH 6/6] Port from deprecated {from,to}Time_t to + {from,to}SecsSinceEpock + +Raises the Qt requirement to 5.8. + +Not raising QT_DISABLE_DEPRECATED_BEFORE=0x050800 yet, because +QModelIndex.child() was deprecated with 5.8 and it's quite frequenty +used. +--- + CMakeLists.txt | 4 ++-- + src/Cryptography/GpgMe++.cpp | 4 ++-- + src/Imap/Model/Utils.cpp | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 54512029..e2cd9108 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -69,7 +69,7 @@ else() + set(QTKEYCHAIN_DEPENDS "") + endif() + +-find_package(Qt5Core 5.6 REQUIRED) ++find_package(Qt5Core 5.8 REQUIRED) + find_package(Qt5Gui REQUIRED) + find_package(Qt5Network REQUIRED) + find_package(Qt5Sql REQUIRED) +@@ -183,7 +183,7 @@ add_definitions(-DQT_STRICT_ITERATORS) + add_definitions(-DQT_USE_QSTRINGBUILDER) + add_definitions(-DQT_USE_FAST_OPERATOR_PLUS) + add_definitions(-DQT_USE_FAST_CONCATENATION) +-add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050600) ++add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050700) + + if(NOT MSVC) + # We're using C++11's threading features (std::async in particular), and that requires "some threading". With GCC and +diff --git a/src/Cryptography/GpgMe++.cpp b/src/Cryptography/GpgMe++.cpp +index 716b8aff..78f8caf5 100644 +--- a/src/Cryptography/GpgMe++.cpp ++++ b/src/Cryptography/GpgMe++.cpp +@@ -366,7 +366,7 @@ void GpgMePart::extractSignatureStatus(std::shared_ptr<GpgME::Context> ctx, cons + } else { + signer = QString::fromUtf8(sig.fingerprint()); + } +- signDate = QDateTime::fromTime_t(sig.creationTime()); ++ signDate = QDateTime::fromSecsSinceEpoch(sig.creationTime()); + + if (sig.summary() & GpgME::Signature::Green) { + // FIXME: change the above to GpgME::Signature::Valid and react to expired keys/signatures by checking the timestamp +@@ -462,7 +462,7 @@ void GpgMePart::extractSignatureStatus(std::shared_ptr<GpgME::Context> ctx, cons + if (sig.summary() & GpgME::Signature::SigExpired) { + ENSURE_LINE_LF(longStatus); + longStatus += tr("Signature expired on %1.") +- .arg(QDateTime::fromTime_t(sig.expirationTime()).toString(Qt::DefaultLocaleShortDate)); ++ .arg(QDateTime::fromSecsSinceEpoch(sig.expirationTime()).toString(Qt::DefaultLocaleShortDate)); + } + if (sig.summary() & GpgME::Signature::KeyMissing) { + ENSURE_LINE_LF(longStatus); +diff --git a/src/Imap/Model/Utils.cpp b/src/Imap/Model/Utils.cpp +index 00b3d4b3..b09341a6 100644 +--- a/src/Imap/Model/Utils.cpp ++++ b/src/Imap/Model/Utils.cpp +@@ -343,7 +343,7 @@ QString formatDateTimeWithTimeZoneAtEnd(const QDateTime &now, const QString &for + + // Got to cast to a signed type to prevent unsigned underflow here. Also go to 64bits because otherwise there'd + // a problem when the value is out-of-range for an int32. +- int minutesDifference = (static_cast<qint64>(now.toTime_t()) - static_cast<qint64>(nowUtc.toTime_t())) / 60; ++ int minutesDifference = (now.toSecsSinceEpoch() - nowUtc.toSecsSinceEpoch()) / 60; + int tzOffsetHours = qAbs(minutesDifference) / 60; + int tzOffsetMinutes = qAbs(minutesDifference) % 60; + // The rest is just a piece of cake now +-- +GitLab + diff --git a/user/trojita/deprecated2.patch b/user/trojita/deprecated2.patch new file mode 100644 index 000000000..968f06ec4 --- /dev/null +++ b/user/trojita/deprecated2.patch @@ -0,0 +1,28 @@ +From 2869c385e72932cbed7398742b8a4d5e3feda765 Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Tue, 24 Mar 2020 13:14:43 +0100 +Subject: [PATCH] Fix build with Qt 5.15.0 + +QPainterPath is no longer included via qtransform.h (since +5.15.0-beta2, 50d2acdc93b4de2ba56eb67787e2bdcb21dd4bea in qtbase.git). + +Change-Id: Ibb59e769bba8514d86aa886afee26a2395d458ef +--- + src/Gui/Window.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp +index 65ba2463..8d74874f 100644 +--- a/src/Gui/Window.cpp ++++ b/src/Gui/Window.cpp +@@ -32,6 +32,7 @@ + #include <QKeyEvent> + #include <QMenuBar> + #include <QMessageBox> ++#include <QPainterPath> + #include <QProgressBar> + #include <QRegularExpression> + #include <QScopedPointer> +-- +GitLab + diff --git a/user/trojita/deprecated3.patch b/user/trojita/deprecated3.patch new file mode 100644 index 000000000..9f1ab3e7e --- /dev/null +++ b/user/trojita/deprecated3.patch @@ -0,0 +1,37 @@ +From 39772585033c1c0aff96f297e93de7be53f9b114 Mon Sep 17 00:00:00 2001 +From: Heiko Becker <heirecka@exherbo.org> +Date: Sat, 23 Mar 2019 01:17:11 +0100 +Subject: [PATCH] tests: Fix build with Qt 5.13 + +QTest::toString(QModelIndex) was added in +7ef0b575b38d267bd3dc14ff46935d556562ff00 and thus causes a build +error with Qt 5.13 because it's redefined here. + +Change-Id: I015800e49cf8d0e87f3541642406396f150d0eeb +--- + tests/Imap/test_Imap_BodyParts.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/Imap/test_Imap_BodyParts.cpp b/tests/Imap/test_Imap_BodyParts.cpp +index f1c577fa..b6e0421d 100644 +--- a/tests/Imap/test_Imap_BodyParts.cpp ++++ b/tests/Imap/test_Imap_BodyParts.cpp +@@ -51,6 +51,7 @@ struct Data { + + Q_DECLARE_METATYPE(QList<Data>) + ++#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0) + namespace QTest { + template <> + char *toString(const QModelIndex &index) +@@ -60,6 +61,7 @@ char *toString(const QModelIndex &index) + return qstrdup(buf.toUtf8().constData()); + } + } ++#endif + + using namespace Imap::Mailbox; + +-- +GitLab + diff --git a/user/trojita/fetch-task.patch b/user/trojita/fetch-task.patch new file mode 100644 index 000000000..378db6477 --- /dev/null +++ b/user/trojita/fetch-task.patch @@ -0,0 +1,204 @@ +From b12f18885861b125ed139f83fa27491d4b3f9f4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Mon, 2 Jan 2017 19:01:16 +0100 +Subject: [PATCH] Refactoring: move FETCH finalization to a corresponding Task + +The tasks were always meant to be able to directly perform these +operations. There's no point in stashing all functionality in the Model +class -- that one is way too big already. + +Change-Id: I9adfefbdf2d7ecd3d060e764ace5535be10dd0d3 +--- + src/Imap/Model/MailboxTree.cpp | 16 +++++++++++---- + src/Imap/Model/MailboxTree.h | 2 ++ + src/Imap/Model/Model.cpp | 28 ------------------------- + src/Imap/Model/Model.h | 1 - + src/Imap/Tasks/FetchMsgPartTask.cpp | 32 ++++++++++++++++++++++++++++- + src/Imap/Tasks/FetchMsgPartTask.h | 10 +++++---- + 6 files changed, 51 insertions(+), 38 deletions(-) + +diff --git a/src/Imap/Model/MailboxTree.cpp b/src/Imap/Model/MailboxTree.cpp +index 8c28775f..47ea675c 100644 +--- a/src/Imap/Model/MailboxTree.cpp ++++ b/src/Imap/Model/MailboxTree.cpp +@@ -1556,8 +1556,12 @@ bool TreeItemMessage::hasNestedAttachments(Model *const model, TreeItemPart *par + } + + +-TreeItemPart::TreeItemPart(TreeItem *parent, const QByteArray &mimeType): +- TreeItem(parent), m_mimeType(mimeType.toLower()), m_octets(0), m_partMime(0), m_partRaw(0) ++TreeItemPart::TreeItemPart(TreeItem *parent, const QByteArray &mimeType) ++ : TreeItem(parent) ++ , m_mimeType(mimeType.toLower()) ++ , m_octets(0) ++ , m_partMime(nullptr) ++ , m_partRaw(nullptr) + { + if (isTopLevelMultiPart()) { + // Note that top-level multipart messages are special, their immediate contents +@@ -1566,8 +1570,12 @@ TreeItemPart::TreeItemPart(TreeItem *parent, const QByteArray &mimeType): + } + } + +-TreeItemPart::TreeItemPart(TreeItem *parent): +- TreeItem(parent), m_mimeType("text/plain"), m_octets(0), m_partMime(0), m_partRaw(0) ++TreeItemPart::TreeItemPart(TreeItem *parent) ++ : TreeItem(parent) ++ , m_mimeType("text/plain") ++ , m_octets(0) ++ , m_partMime(nullptr) ++ , m_partRaw(nullptr) + { + } + +diff --git a/src/Imap/Model/MailboxTree.h b/src/Imap/Model/MailboxTree.h +index 5cfd843a..137d4a5f 100644 +--- a/src/Imap/Model/MailboxTree.h ++++ b/src/Imap/Model/MailboxTree.h +@@ -55,6 +55,7 @@ class TreeItem + friend class MsgListModel; // for direct access to m_children + friend class ThreadingMsgListModel; // for direct access to m_children + friend class UpdateFlagsOfAllMessagesTask; // for direct access to m_children ++ friend class FetchMsgPartTask; // for direct access to m_children + + protected: + /** @short Availability of an item */ +@@ -140,6 +141,7 @@ class TreeItemMailbox: public TreeItem + friend class DeleteMailboxTask; // for direct access to maintainingTask + friend class KeepMailboxOpenTask; // needs access to maintainingTask + friend class SubscribeUnsubscribeTask; // needs access to m_metadata.flags ++ friend class FetchMsgPartTask; // needs access to partIdToPtr() + static QLatin1String flagNoInferiors; + static QLatin1String flagHasNoChildren; + static QLatin1String flagHasChildren; +diff --git a/src/Imap/Model/Model.cpp b/src/Imap/Model/Model.cpp +index e62ef3dd..dc985d44 100644 +--- a/src/Imap/Model/Model.cpp ++++ b/src/Imap/Model/Model.cpp +@@ -500,34 +500,6 @@ void Model::emitMessageCountChanged(TreeItemMailbox *const mailbox) + emit messageCountPossiblyChanged(mailboxIndex); + } + +-/** @short Retrieval of a message part has completed */ +-bool Model::finalizeFetchPart(TreeItemMailbox *const mailbox, const uint sequenceNo, const QByteArray &partId) +-{ +- // At first, verify that the message itself is marked as loaded. +- // If it isn't, it's probably because of Model::releaseMessageData(). +- TreeItem *item = mailbox->m_children[0]; // TreeItemMsgList +- item = item->child(sequenceNo - 1, this); // TreeItemMessage +- Q_ASSERT(item); // FIXME: or rather throw an exception? +- if (item->accessFetchStatus() == TreeItem::NONE) { +- // ...and it indeed got released, so let's just return and don't try to check anything +- return false; +- } +- +- TreeItemPart *part = mailbox->partIdToPtr(this, static_cast<TreeItemMessage *>(item), partId); +- if (! part) { +- qDebug() << "Can't verify part fetching status: part is not here!"; +- return false; +- } +- if (part->loading()) { +- part->setFetchStatus(TreeItem::UNAVAILABLE); +- QModelIndex idx = part->toIndex(this); +- emit dataChanged(idx, idx); +- return false; +- } else { +- return true; +- } +-} +- + void Model::handleCapability(Imap::Parser *ptr, const Imap::Responses::Capability *const resp) + { + updateCapabilities(ptr, resp->capabilities); +diff --git a/src/Imap/Model/Model.h b/src/Imap/Model/Model.h +index 46dce087..114e29ac 100644 +--- a/src/Imap/Model/Model.h ++++ b/src/Imap/Model/Model.h +@@ -492,7 +492,6 @@ private: + + void finalizeList(Parser *parser, TreeItemMailbox *const mailboxPtr); + void finalizeIncrementalList(Parser *parser, const QString &parentMailboxName); +- bool finalizeFetchPart(TreeItemMailbox *const mailbox, const uint sequenceNo, const QByteArray &partId); + void genericHandleFetch(TreeItemMailbox *mailbox, const Imap::Responses::Fetch *const resp); + + void replaceChildMailboxes(TreeItemMailbox *mailboxPtr, const TreeItemChildrenList &mailboxes); +diff --git a/src/Imap/Tasks/FetchMsgPartTask.cpp b/src/Imap/Tasks/FetchMsgPartTask.cpp +index c7a49437..40e7ec81 100644 +--- a/src/Imap/Tasks/FetchMsgPartTask.cpp ++++ b/src/Imap/Tasks/FetchMsgPartTask.cpp +@@ -121,7 +121,7 @@ void FetchMsgPartTask::markPendingItemsUnavailable() + QList<TreeItemMessage *> messages = model->findMessagesByUids(mailbox, uids); + Q_FOREACH(TreeItemMessage *message, messages) { + Q_FOREACH(const QByteArray &partId, parts) { +- if (model->finalizeFetchPart(mailbox, message->row() + 1, partId)) { ++ if (finalizeFetchPart(mailbox, message->row() + 1, partId)) { + log(QLatin1String("Fetched part ") + QString::fromUtf8(partId), Common::LOG_MESSAGES); + } else { + log(QLatin1String("Received no data for part ") + QString::fromUtf8(partId), Common::LOG_MESSAGES); +@@ -130,5 +130,35 @@ void FetchMsgPartTask::markPendingItemsUnavailable() + } + } + ++/** @short Retrieval of a message part has completed */ ++bool FetchMsgPartTask::finalizeFetchPart(TreeItemMailbox *const mailbox, const uint sequenceNo, const QByteArray &partId) ++{ ++ Q_ASSERT(model); ++ // At first, verify that the message itself is marked as loaded. ++ // If it isn't, it's probably because of Model::releaseMessageData(). ++ TreeItem *item = mailbox->m_children[0]; // TreeItemMsgList ++ item = item->child(sequenceNo - 1, model); // TreeItemMessage ++ Q_ASSERT(item); // FIXME: or rather throw an exception? ++ if (item->accessFetchStatus() == TreeItem::NONE) { ++ // ...and it indeed got released, so let's just return and don't try to check anything ++ return false; ++ } ++ ++ TreeItemPart *part = mailbox->partIdToPtr(model, static_cast<TreeItemMessage *>(item), partId); ++ if (!part) { ++ log(QStringLiteral("Can't verify part fetching status: part is not here!"), Common::LOG_MESSAGES); ++ return false; ++ } ++ if (part->loading()) { ++ part->setFetchStatus(TreeItem::UNAVAILABLE); ++ QModelIndex idx = part->toIndex(model); ++ emit model->dataChanged(idx, idx); ++ return false; ++ } else { ++ return true; ++ } ++} ++ ++ + } + } +diff --git a/src/Imap/Tasks/FetchMsgPartTask.h b/src/Imap/Tasks/FetchMsgPartTask.h +index 4d5b591f..a7e4b2c1 100644 +--- a/src/Imap/Tasks/FetchMsgPartTask.h ++++ b/src/Imap/Tasks/FetchMsgPartTask.h +@@ -26,10 +26,10 @@ + #include <QPersistentModelIndex> + #include "ImapTask.h" + +-namespace Imap +-{ +-namespace Mailbox +-{ ++namespace Imap { ++namespace Mailbox { ++ ++class TreeItemMailbox; + + /** @short Fetch a message part */ + class FetchMsgPartTask : public ImapTask +@@ -48,6 +48,8 @@ public: + protected slots: + void markPendingItemsUnavailable(); + private: ++ bool finalizeFetchPart(TreeItemMailbox *const mailbox, const uint sequenceNo, const QByteArray &partId); ++ + CommandHandle tag; + ImapTask *conn; + Imap::Uids uids; +-- +GitLab + diff --git a/user/trojita/plaintext-upgrade-attack.patch b/user/trojita/plaintext-upgrade-attack.patch new file mode 100644 index 000000000..f3c30b9aa --- /dev/null +++ b/user/trojita/plaintext-upgrade-attack.patch @@ -0,0 +1,221 @@ +From 27573cf04802fc2fdeb7f7beace4612b22ea1942 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Sun, 30 Jan 2022 23:56:31 +0100 +Subject: [PATCH] IMAP: ignore unsolicited LIST and STATUS before we're + authenticated +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These responses were combined with legit responses which arrive from the +real server later on, after having authenticated, and as a result, a +malicious active attacker on a network was able to inject extra fake +mailboxes to the GUI even when upgrading connection from plaintext to a +secure one via STARTTLS. + +These two responses are the only ones which are handled by our pre-task +code directly in Model.cpp, which means that the state machine has to be +checked and messages which are received prior to authentication must be +rejected. Since this is really a pretty serious violation of the IMAP +state machine, let's not ignore them silently, and simply treat them as +any other unexpected response. + +BUG: 432353 +Change-Id: I9292fcb20215ebe4dbc7a103fc9403dfa97b258b +Reported-by: Damian Poddebniak +Co-authored-by: Espen Sandøy Hustad <espen@ehustad.com> +Reviewed-by: Caspar Schutijser <caspar@schutijser.com> +--- + src/Imap/Model/Model.cpp | 7 +- + tests/Imap/test_Imap_Tasks_OpenConnection.cpp | 122 +++++++++++++++++- + tests/Imap/test_Imap_Tasks_OpenConnection.h | 9 ++ + 3 files changed, 136 insertions(+), 2 deletions(-) + +diff --git a/src/Imap/Model/Model.cpp b/src/Imap/Model/Model.cpp +index 7a393c7a..79e34658 100644 +--- a/src/Imap/Model/Model.cpp ++++ b/src/Imap/Model/Model.cpp +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> ++/* Copyright (C) 2006 - 2021 Jan Kundrát <jkt@flaska.net> + + This file is part of the Trojita Qt IMAP e-mail client, + http://trojita.flaska.net/ +@@ -519,6 +519,8 @@ void Model::handleList(Imap::Parser *ptr, const Imap::Responses::List *const res + { + if (accessParser(ptr).connState == CONN_STATE_LOGOUT) + return; ++ if (accessParser(ptr).connState < CONN_STATE_AUTHENTICATED) ++ throw UnexpectedResponseReceived("Unexpected LIST response before authentication succeeded", *resp); + accessParser(ptr).listResponses << *resp; + } + +@@ -547,6 +549,9 @@ void Model::handleStatus(Imap::Parser *ptr, const Imap::Responses::Status *const + { + if (accessParser(ptr).connState == CONN_STATE_LOGOUT) + return; ++ if (accessParser(ptr).connState < CONN_STATE_AUTHENTICATED) ++ throw UnexpectedResponseReceived("Unexpected STATUS response before authentication succeeded", *resp); ++ + Q_UNUSED(ptr); + TreeItemMailbox *mailbox = findMailboxByName(resp->mailbox); + if (! mailbox) { +diff --git a/tests/Imap/test_Imap_Tasks_OpenConnection.cpp b/tests/Imap/test_Imap_Tasks_OpenConnection.cpp +index b72898c4..953fe6f9 100644 +--- a/tests/Imap/test_Imap_Tasks_OpenConnection.cpp ++++ b/tests/Imap/test_Imap_Tasks_OpenConnection.cpp +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> ++/* Copyright (C) 2006 - 2021 Jan Kundrát <jkt@flaska.net> + + This file is part of the Trojita Qt IMAP e-mail client, + http://trojita.flaska.net/ +@@ -611,5 +611,125 @@ void ImapModelOpenConnectionTest::provideAuthDetails() + } + } + ++void ImapModelOpenConnectionTest::dataBug432353() ++{ ++ QTest::addColumn<QByteArray>("garbage"); ++ QTest::newRow("LIST") << QByteArray("* LIST (\\HasNoChildren) \".\" x\r\n"); ++ QTest::newRow("STATUS") << QByteArray("* STATUS INBOX (MESSAGES 123)\r\n"); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusUponConnect_data() ++{ ++ dataBug432353(); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusUponConnect() ++{ ++ QFETCH(QByteArray, garbage); ++ reinit(TlsRequired::Yes); ++ cEmpty(); ++ QCOMPARE(model->rowCount(QModelIndex()), 1); ++ ExpectSingleErrorHere x(this); ++ cServer("* OK foo\r\n" + garbage); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusStartTls_data() ++{ ++ dataBug432353(); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusStartTls() ++{ ++ QFETCH(QByteArray, garbage); ++ reinit(TlsRequired::Yes); ++ cEmpty(); ++ cServer("* OK [Capability imap4rev1 starttls] foo\r\n"); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cClient(t.mk("STARTTLS\r\n")); ++ cServer(t.last("OK will establish secure layer immediately\r\n")); ++ QVERIFY(authSpy->isEmpty()); ++ cClient("[*** STARTTLS ***]" + t.mk("CAPABILITY\r\n")); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cServer("* CAPABILITY IMAP4rev1\r\n" + t.last("OK capability completed\r\n")); ++ cClient(t.mk("LOGIN luzr sikrit\r\n")); ++ QCOMPARE(authSpy->size(), 1); ++ ExpectSingleErrorHere x(this); ++ cServer(garbage + t.last("OK [CAPABILITY IMAP4rev1] logged in\r\n")); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusBeforeAuthenticated_data() ++{ ++ dataBug432353(); ++} ++ ++void ImapModelOpenConnectionTest::testNoListStatusBeforeAuthenticated() ++{ ++ QFETCH(QByteArray, garbage); ++ reinit(TlsRequired::Yes); ++ cEmpty(); ++ cServer("* OK [Capability imap4rev1 starttls] foo\r\n"); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cClient(t.mk("STARTTLS\r\n")); ++ cServer(t.last("OK will establish secure layer immediately\r\n")); ++ QVERIFY(authSpy->isEmpty()); ++ cClient("[*** STARTTLS ***]" + t.mk("CAPABILITY\r\n")); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cServer("* CAPABILITY IMAP4rev1\r\n" + t.last("OK capability completed\r\n")); ++ cClient(t.mk("LOGIN luzr sikrit\r\n")); ++ QCOMPARE(authSpy->size(), 1); ++ ExpectSingleErrorHere x(this); ++ cServer(garbage + t.last("OK [CAPABILITY IMAP4rev1] logged in\r\n")); ++} ++ ++void ImapModelOpenConnectionTest::testListStatusUnsolicited() ++{ ++ model->cache()->setChildMailboxes(QString(), ++ QList<Imap::Mailbox::MailboxMetadata>() ++ << Imap::Mailbox::MailboxMetadata(QLatin1String("INBOX"), QString(), QStringList()) ++ ); ++ ++ reinit(TlsRequired::Yes); ++ cEmpty(); ++ cServer("* OK [Capability imap4rev1 starttls] foo\r\n"); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cClient(t.mk("STARTTLS\r\n")); ++ cServer(t.last("OK will establish secure layer immediately\r\n")); ++ QVERIFY(authSpy->isEmpty()); ++ cClient("[*** STARTTLS ***]" + t.mk("CAPABILITY\r\n")); ++ QVERIFY(completedSpy->isEmpty()); ++ QVERIFY(authSpy->isEmpty()); ++ cServer("* CAPABILITY IMAP4rev1\r\n" + t.last("OK capability completed\r\n")); ++ cClient(t.mk("LOGIN luzr sikrit\r\n")); ++ QCOMPARE(authSpy->size(), 1); ++ cServer(t.last("OK [CAPABILITY IMAP4rev1] logged in\r\n") + ++ "* LIST (\\HasNoChildren) \".\" abc\r\n" ++ "* LIST (\\HasNoChildren) \".\" def\r\n" ++ "* STATUS INBOX (MESSAGES 123)\r\n" ++ ); ++ QCOMPARE(model->rowCount(QModelIndex()), 1); ++ cClient(t.mk("LIST \"\" \"%\"\r\n")); ++ cEmpty(); ++ QCOMPARE(completedSpy->size(), 1); ++ QVERIFY(failedSpy->isEmpty()); ++ cServer("* LIST (\\Noselect \\HasChildren) \".\" \"xyz\"\r\n" ++ "* LIST (\\HasNoChildren) \".\" \"INBOX\"\r\n" ++ + t.last("OK list done\r\n") ++ + "* STATUS INBOX (MESSAGES 789)\r\n"); ++ cEmpty(); ++ ++ // Mailboxes "abc" and "def" were reported by the server as an async replay after having authenticated, ++ // so there's no reason not to trust them. However, they were received before a LIST was issues, ++ // so they should be probably ignored -- but that is tricky to do properly with command pipelining, etc. ++ QCOMPARE(model->rowCount( QModelIndex() ), 5 /* empty root, INBOX, abc, def, xyz */); ++ QCOMPARE(model->index(1, 0, QModelIndex()).data().toString(), QLatin1String("INBOX")); ++ QCOMPARE(model->index(2, 0, QModelIndex()).data().toString(), QLatin1String("abc")); ++ QCOMPARE(model->index(3, 0, QModelIndex()).data().toString(), QLatin1String("def")); ++ QCOMPARE(model->index(4, 0, QModelIndex()).data().toString(), QLatin1String("xyz")); ++} + + QTEST_GUILESS_MAIN( ImapModelOpenConnectionTest ) +diff --git a/tests/Imap/test_Imap_Tasks_OpenConnection.h b/tests/Imap/test_Imap_Tasks_OpenConnection.h +index 4df65c05..6a0e2704 100644 +--- a/tests/Imap/test_Imap_Tasks_OpenConnection.h ++++ b/tests/Imap/test_Imap_Tasks_OpenConnection.h +@@ -70,6 +70,15 @@ private slots: + + void testExcessivePasswordPrompts(); + ++ void dataBug432353(); ++ void testNoListStatusUponConnect(); ++ void testNoListStatusUponConnect_data(); ++ void testNoListStatusStartTls(); ++ void testNoListStatusStartTls_data(); ++ void testNoListStatusBeforeAuthenticated(); ++ void testNoListStatusBeforeAuthenticated_data(); ++ void testListStatusUnsolicited(); ++ + void provideAuthDetails(); + void acceptSsl(const QList<QSslCertificate> &certificateChain, const QList<QSslError> &sslErrors); + +-- +GitLab + diff --git a/user/trojita/pwstorage.patch b/user/trojita/pwstorage.patch new file mode 100644 index 000000000..e0cec35ba --- /dev/null +++ b/user/trojita/pwstorage.patch @@ -0,0 +1,52 @@ +From 7481e43116995d744d485655b1de6494d771227e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Thu, 16 May 2019 19:28:14 +0200 +Subject: [PATCH] SMTP: Store correct password into the password manager + +The configuration ties the SMTP account with the IMAP account (in terms +of per-profile access), so it was wrong to use the default account name. +This fixes a rare configuration where the user is: + +- using a non-default profile, +- requires SMTP auth, +- *and* uses a different set of credentials for SMTP access compared to IMAP. + +Change-Id: Id6d341d14bf795943d8f3b7b42fac587a062141d +--- + src/Gui/ComposeWidget.cpp | 4 ---- + src/Gui/SettingsDialog.cpp | 4 +++- + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/Gui/ComposeWidget.cpp b/src/Gui/ComposeWidget.cpp +index 104d2790..9fb3192a 100644 +--- a/src/Gui/ComposeWidget.cpp ++++ b/src/Gui/ComposeWidget.cpp +@@ -660,10 +660,6 @@ void ComposeWidget::passwordRequested(const QString &user, const QString &host) + return; + } + +- // FIXME: use another account-id at some point in future +- // we are now using the profile to avoid overwriting passwords of +- // other profiles in secure storage +- // 'account-0' is the hardcoded value when not using a profile + Plugins::PasswordJob *job = password->requestPassword(m_submission->accountId(), QStringLiteral("smtp")); + if (!job) { + askPassword(user, host); +diff --git a/src/Gui/SettingsDialog.cpp b/src/Gui/SettingsDialog.cpp +index a6e9b6b6..2eeb8b12 100644 +--- a/src/Gui/SettingsDialog.cpp ++++ b/src/Gui/SettingsDialog.cpp +@@ -1078,7 +1078,9 @@ OutgoingPage::OutgoingPage(SettingsDialog *parent, QSettings &s): QScrollArea(pa + connect(smtpBurl, &QAbstractButton::toggled, m_smtpAccountSettings, &MSA::Account::setUseBurl); + connect(sendmail, &LineEdit::textEditingFinished, m_smtpAccountSettings, &MSA::Account::setPathToSendmail); + +- m_pwWatcher = new UiUtils::PasswordWatcher(this, m_parent->pluginManager(), QStringLiteral("account-0"), QStringLiteral("smtp")); ++ m_pwWatcher = new UiUtils::PasswordWatcher(this, m_parent->pluginManager(), ++ profileName.isEmpty() ? QStringLiteral("account-0") : profileName, ++ QStringLiteral("smtp")); + connect(m_pwWatcher, &UiUtils::PasswordWatcher::stateChanged, this, &OutgoingPage::updateWidgets); + connect(m_pwWatcher, &UiUtils::PasswordWatcher::savingFailed, this, &OutgoingPage::saved); + connect(m_pwWatcher, &UiUtils::PasswordWatcher::savingDone, this, &OutgoingPage::saved); +-- +GitLab + diff --git a/user/trojita/segfault-sorting-mailboxes.patch b/user/trojita/segfault-sorting-mailboxes.patch new file mode 100644 index 000000000..833110983 --- /dev/null +++ b/user/trojita/segfault-sorting-mailboxes.patch @@ -0,0 +1,72 @@ +From d4e01b6b2cf476f4892b24bdeaae67f5b9ed2ee2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Tue, 1 Feb 2022 21:04:14 +0100 +Subject: [PATCH] MailboxNameComparator: implement "less than", not "less or + equal" + +This comparator is used for "natural order" sorting of mailboxes. The +usual way of sorting is via a functor which satisfies the Compare [1] +C++ named requirement, which is effectively a "less than" operation. +This code implemented a less-than-or-equal, which means that it was not +usable for `std::sort` which would segfault: + + 0x00007ffff354a35d in __dynamic_cast () from /nix/store/b0p7nvkwxr65q016zsqicrd4bcg5bv1s-gcc-10.3.0-lib/lib/libstdc++.so.6 + (gdb) bt + #0 0x00007ffff354a35d in __dynamic_cast () from /nix/store/b0p7nvkwxr65q016zsqicrd4bcg5bv1s-gcc-10.3.0-lib/lib/libstdc++.so.6 + #1 0x00000000005d316c in (anonymous namespace)::MailboxNameComparator (a=0x520041004d005c, b=0x12ac740) at /home/jkt/work/prog/trojita/src/Imap/Model/Model.cpp:74 + #2 0x00000000005e1d46 in __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)>::operator()<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator> (__it2=..., __it1=..., this=<synthetic pointer>) at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1909 + #3 std::__unguarded_partition<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> > (__comp=..., __pivot=..., __last=..., __first=...) + at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1909 + #4 std::__unguarded_partition_pivot<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> > (__comp=..., __last=..., __first=...) + at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1931 + #5 std::__introsort_loop<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, int, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> > (__first=..., __last=..., + __depth_limit=<optimized out>, __depth_limit@entry=9, __comp=__comp@entry=...) at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1962 + #6 0x00000000005e1db8 in std::__introsort_loop<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, int, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> > (__first=..., __last=..., + __depth_limit=<optimized out>, __depth_limit@entry=10, __comp=__comp@entry=...) at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1964 + #7 0x00000000005dd6fd in std::__sort<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> > (__comp=..., __last=..., __first=...) + at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:1979 + #8 std::sort<QTypedArrayData<Imap::Mailbox::TreeItem*>::iterator, bool (*)(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)> (__first=..., __last=..., __first=..., __last=..., + __comp=0x5d3130 <(anonymous namespace)::MailboxNameComparator(Imap::Mailbox::TreeItem const*, Imap::Mailbox::TreeItem const*)>) at /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_algo.h:4899 + #9 Imap::Mailbox::Model::finalizeList (this=0xbfbdb0, parser=<optimized out>, mailboxPtr=0x7ffffffe4438) at /home/jkt/work/prog/trojita/src/Imap/Model/Model.cpp:352 + #10 0x000000000061d512 in Imap::Mailbox::ListChildMailboxesTask::handleStateHelper (this=0x124d790, resp=0x124e840) at /home/jkt/work/prog/trojita/src/Imap/Tasks/ListChildMailboxesTask.cpp:96 + #11 0x00000000005deadc in Imap::Mailbox::Model::responseReceived (this=0xbfbdb0, it=...) at /home/jkt/work/prog/trojita/src/Imap/Model/Model.cpp:220 + #12 0x00007ffff396918c in QObject::event(QEvent*) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #13 0x00007ffff441776f in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Widgets.so.5 + #14 0x00007ffff393c40a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #15 0x00007ffff393f451 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #16 0x00007ffff3994d93 in ?? () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #17 0x00007ffff1883aab in g_main_context_dispatch () from /nix/store/1qiv23m1q9fk18rwkzrk29ciz87030lp-glib-2.70.1/lib/libglib-2.0.so.0 + #18 0x00007ffff1883d58 in g_main_context_iterate.constprop () from /nix/store/1qiv23m1q9fk18rwkzrk29ciz87030lp-glib-2.70.1/lib/libglib-2.0.so.0 + #19 0x00007ffff1883e0f in g_main_context_iteration () from /nix/store/1qiv23m1q9fk18rwkzrk29ciz87030lp-glib-2.70.1/lib/libglib-2.0.so.0 + #20 0x00007ffff39943f0 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #21 0x00007ffff393adab in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #22 0x00007ffff39433a0 in QCoreApplication::exec() () from /nix/store/fwc2c76yqyyj0pj6abvsyzlgd2r1rvr0-qtbase-5.15.3/lib/libQt5Core.so.5 + #23 0x000000000047fafb in main (argc=<optimized out>, argv=0x7ffffffe4b80) at /home/jkt/work/prog/trojita/src/Gui/main.cpp:205 + +[1] https://en.cppreference.com/w/cpp/named_req/Compare + +Change-Id: Ib88e377fafc94de7160c63832c8115756d360732 +--- + src/Imap/Model/Model.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/Imap/Model/Model.cpp b/src/Imap/Model/Model.cpp +index 79e34658..1d539e22 100644 +--- a/src/Imap/Model/Model.cpp ++++ b/src/Imap/Model/Model.cpp +@@ -76,10 +76,10 @@ bool MailboxNameComparator(const TreeItem *const a, const TreeItem *const b) + const TreeItemMailbox *const mailboxB = dynamic_cast<const TreeItemMailbox *const>(b); + + if (mailboxA->mailbox() == QLatin1String("INBOX")) +- return true; ++ return mailboxB->mailbox() != QLatin1String("INBOX"); + if (mailboxB->mailbox() == QLatin1String("INBOX")) + return false; +- return mailboxA->mailbox().compare(mailboxB->mailbox(), Qt::CaseInsensitive) < 1; ++ return mailboxA->mailbox().compare(mailboxB->mailbox(), Qt::CaseInsensitive) < 0; + } + + bool uidComparator(const TreeItem *const item, const uint uid) +-- +GitLab + diff --git a/user/trojita/signedness.patch b/user/trojita/signedness.patch new file mode 100644 index 000000000..693baf67a --- /dev/null +++ b/user/trojita/signedness.patch @@ -0,0 +1,71 @@ +From e4478df9389894b6498ffe252310cdecd1e58904 Mon Sep 17 00:00:00 2001 +From: Vicente Bergas <vicencb@gmail.com> +Date: Sat, 3 Feb 2018 19:02:38 +0100 +Subject: [PATCH] Fix signed vs. unsigned math on ARM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On ARM systems, `char` is not signed, but unsigned, and therefore code +like qMin(-11, ...) doesn't really do a correct thing. + +Change-Id: I1e03570c8a809cd6d8c699b3bc138a6bd05ce53c +Signed-off-by: Jan Kundrát <jkt@kde.org> +--- + src/Gui/Spinner.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/Gui/Spinner.h b/src/Gui/Spinner.h +index b8b06b85..2f60ce45 100644 +--- a/src/Gui/Spinner.h ++++ b/src/Gui/Spinner.h +@@ -82,8 +82,8 @@ private slots: + void updateAncestors(); + void updateGeometry(); + private: +- uchar m_step; +- char m_fadeStep; ++ int m_step; ++ int m_fadeStep; + int m_timer; + QTimer *m_startTimer; + QList<QWidget*> m_ancestors; +-- +GitLab + +From 2202821fad977923d2f69c044ad09b3dc46c804a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Fri, 24 Aug 2018 13:44:34 +0200 +Subject: [PATCH] Fix comparison of integer expressions of different signedness +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + src/Imap/Model/ModelTest/modeltest.cpp: In member function ‘void ModelTest::data()’: + src/Imap/Model/ModelTest/modeltest.cpp:422:27: error: comparison of integer expressions of different signedness: ‘int’ and ‘QFlags<Qt::AlignmentFlag>::Int’ {aka ‘unsigned int’} [-Werror=sign-compare] + Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); + ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Change-Id: I7007e1c0cba20b31d76f6426548ad4fb43480017 +--- + src/Imap/Model/ModelTest/modeltest.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/Imap/Model/ModelTest/modeltest.cpp b/src/Imap/Model/ModelTest/modeltest.cpp +index 24046a24..d2c8fcac 100644 +--- a/src/Imap/Model/ModelTest/modeltest.cpp ++++ b/src/Imap/Model/ModelTest/modeltest.cpp +@@ -418,8 +418,8 @@ void ModelTest::data() + // Check that the alignment is one we know about + QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); + if (textAlignmentVariant.isValid()) { +- int alignment = textAlignmentVariant.toInt(); +- Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); ++ unsigned int alignment = textAlignmentVariant.toUInt(); ++ Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); + } + + // General Purpose roles that should return a QColor +-- +GitLab + diff --git a/user/trojita/statusbar-fix.patch b/user/trojita/statusbar-fix.patch new file mode 100644 index 000000000..4eb556465 --- /dev/null +++ b/user/trojita/statusbar-fix.patch @@ -0,0 +1,167 @@ +From 654188c2806c376a4c2b9cdf44e48172c2255a18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Mon, 3 Oct 2016 22:09:17 +0200 +Subject: [PATCH] GUI: Prevent excessive newlines in the PartStatusWidget + crypto messages + +Previously, there were extra newlines in certain scenarios. The long +text should never begin with a stray newline. + +This might make it easier to see the linked bug. + +Change-Id: I72188b08f1562b6cdd30849f9958fdcc9f0504b7 +CCBUG: 369832 +--- + src/Cryptography/GpgMe++.cpp | 65 ++++++++++++++++++++++++------------ + 1 file changed, 44 insertions(+), 21 deletions(-) + +diff --git a/src/Cryptography/GpgMe++.cpp b/src/Cryptography/GpgMe++.cpp +index 54275f73..e2fcdfe7 100644 +--- a/src/Cryptography/GpgMe++.cpp ++++ b/src/Cryptography/GpgMe++.cpp +@@ -290,6 +290,8 @@ QVariant GpgMePart::data(int role) const + } + } + ++#define ENSURE_LINE_LF(X) do { if (!X.isEmpty()) { X += LF; } } while (0) ++ + void GpgMePart::extractSignatureStatus(std::shared_ptr<GpgME::Context> ctx, const GpgME::Signature &sig, + const std::vector<std::string> messageUids, const bool wasSigned, const bool wasEncrypted, + bool &sigOkDisregardingTrust, bool &sigValidVerified, +@@ -447,30 +449,38 @@ void GpgMePart::extractSignatureStatus(std::shared_ptr<GpgME::Context> ctx, cons + + // extract the individual error bits + if (sig.summary() & GpgME::Signature::KeyRevoked) { +- longStatus += LF + tr("The key or at least one certificate has been revoked."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("The key or at least one certificate has been revoked."); + } + if (sig.summary() & GpgME::Signature::KeyExpired) { + // FIXME: how to get the expiration date? +- longStatus += LF + tr("The key or one of the certificates has expired."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("The key or one of the certificates has expired."); + } + if (sig.summary() & GpgME::Signature::SigExpired) { +- longStatus += LF + tr("Signature expired on %1.") ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature expired on %1.") + .arg(QDateTime::fromTime_t(sig.expirationTime()).toString(Qt::DefaultLocaleShortDate)); + } + if (sig.summary() & GpgME::Signature::KeyMissing) { +- longStatus += LF + tr("Can't verify due to a missing key or certificate."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Can't verify due to a missing key or certificate."); + } + if (sig.summary() & GpgME::Signature::CrlMissing) { +- longStatus += LF + tr("The CRL (or an equivalent mechanism) is not available."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("The CRL (or an equivalent mechanism) is not available."); + } + if (sig.summary() & GpgME::Signature::CrlTooOld) { +- longStatus += LF + tr("Available CRL is too old."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Available CRL is too old."); + } + if (sig.summary() & GpgME::Signature::BadPolicy) { +- longStatus += LF + tr("A policy requirement was not met."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("A policy requirement was not met."); + } + if (sig.summary() & GpgME::Signature::SysError) { +- longStatus += LF + tr("A system error occurred. %1") ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("A system error occurred. %1") + .arg(QString::fromUtf8(sig.status().asString())); + } + +@@ -478,22 +488,28 @@ void GpgMePart::extractSignatureStatus(std::shared_ptr<GpgME::Context> ctx, cons + // Extract signature validity + switch (sig.validity()) { + case GpgME::Signature::Undefined: +- longStatus += LF + tr("Signature validity is undefined."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is undefined."); + break; + case GpgME::Signature::Never: +- longStatus += LF + tr("Signature validity is never to be trusted."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is never to be trusted."); + break; + case GpgME::Signature::Marginal: +- longStatus += LF + tr("Signature validity is marginal."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is marginal."); + break; + case GpgME::Signature::Full: +- longStatus += LF + tr("Signature validity is full."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is full."); + break; + case GpgME::Signature::Ultimate: +- longStatus += LF + tr("Signature validity is ultimate."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is ultimate."); + break; + case GpgME::Signature::Unknown: +- longStatus += LF + tr("Signature validity is unknown."); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Signature validity is unknown."); + break; + } + } +@@ -844,7 +860,8 @@ void GpgMeEncrypted::handleDataChanged(const QModelIndex &topLeft, const QModelI + if (tldr.isEmpty()) { + tldr = tr("Broken encrypted message"); + } +- longStatus += LF + tr("Decryption error: %1").arg(QString::fromUtf8(combinedResult.first.error().asString())); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Decryption error: %1").arg(QString::fromUtf8(combinedResult.first.error().asString())); + icon = QStringLiteral("emblem-error"); + } else if (tldr.isEmpty()) { + tldr = tr("Encrypted message"); +@@ -852,29 +869,35 @@ void GpgMeEncrypted::handleDataChanged(const QModelIndex &topLeft, const QModelI + } + + if (combinedResult.first.isWrongKeyUsage()) { +- longStatus += LF + tr("Wrong key usage, not for encryption"); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Wrong key usage, not for encryption"); + } + if (auto msg = combinedResult.first.unsupportedAlgorithm()) { +- longStatus += LF + tr("Unsupported algorithm: %1").arg(QString::fromUtf8(msg)); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Unsupported algorithm: %1").arg(QString::fromUtf8(msg)); + } + + for (const auto &recipient: combinedResult.first.recipients()) { + GpgME::Error keyError; + auto key = ctx->key(recipient.keyID(), keyError, false); + if (keyError) { +- longStatus += LF + tr("Cannot extract recipient %1: %2") ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Cannot extract recipient %1: %2") + .arg(QString::fromUtf8(recipient.keyID()), QString::fromUtf8(keyError.asString())); + } else { + if (key.numUserIDs()) { +- longStatus += LF + tr("Encrypted to %1 (%2)") ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Encrypted to %1 (%2)") + .arg(QString::fromUtf8(key.userID(0).id()), QString::fromUtf8(recipient.keyID())); + } else { +- longStatus += LF + tr("Encrypted to %1").arg(QString::fromUtf8(recipient.keyID())); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Encrypted to %1").arg(QString::fromUtf8(recipient.keyID())); + } + } + } + if (auto fname = combinedResult.first.fileName()) { +- longStatus += LF + tr("Original filename: %1").arg(QString::fromUtf8(fname)); ++ ENSURE_LINE_LF(longStatus); ++ longStatus += tr("Original filename: %1").arg(QString::fromUtf8(fname)); + } + + if (p) { +-- +GitLab + diff --git a/user/trojita/testfix.patch b/user/trojita/testfix.patch new file mode 100644 index 000000000..efe36d053 --- /dev/null +++ b/user/trojita/testfix.patch @@ -0,0 +1,85 @@ +Required for plaintext-upgrade-attack.patch to run successfully. + +From 91d19cb8530cb8df6ec0ee0580abcd98f1957395 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jkt@kde.org> +Date: Mon, 5 Sep 2016 12:47:28 +0200 +Subject: [PATCH] tests: fix more memleaks + +There's some progress, but still plenty of stuff to do: + +-SUMMARY: AddressSanitizer: 77490 byte(s) leaked in 1010 allocation(s). ++SUMMARY: AddressSanitizer: 7720 byte(s) leaked in 95 allocation(s). + +Change-Id: I133fda902a9bd3f9fe697d7ffe8c57a159c887d8 +--- + tests/Imap/test_Imap_Tasks_OpenConnection.cpp | 16 ++++++++-------- + tests/Imap/test_Imap_Tasks_OpenConnection.h | 14 +++++++------- + 2 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/tests/Imap/test_Imap_Tasks_OpenConnection.cpp b/tests/Imap/test_Imap_Tasks_OpenConnection.cpp +index b3a95636..c40297ab 100644 +--- a/tests/Imap/test_Imap_Tasks_OpenConnection.cpp ++++ b/tests/Imap/test_Imap_Tasks_OpenConnection.cpp +@@ -35,12 +35,11 @@ void ImapModelOpenConnectionTest::initTestCase() + { + LibMailboxSync::initTestCase(); + qRegisterMetaType<Imap::Mailbox::ImapTask*>(); +- completedSpy = 0; +- m_enableAutoLogin = true; + } + + void ImapModelOpenConnectionTest::init() + { ++ m_enableAutoLogin = true; + reinit(TlsRequired::No); + } + +@@ -56,13 +55,14 @@ void ImapModelOpenConnectionTest::reinit(const TlsRequired tlsRequired) + connect(model, &Imap::Mailbox::Model::needsSslDecision, this, &ImapModelOpenConnectionTest::acceptSsl, Qt::QueuedConnection); + LibMailboxSync::setModelNetworkPolicy(model, Imap::Mailbox::NETWORK_ONLINE); + QCoreApplication::processEvents(); ++ delete task; + task = new Imap::Mailbox::OpenConnectionTask(model); +- completedSpy = new QSignalSpy(task, SIGNAL(completed(Imap::Mailbox::ImapTask*))); +- failedSpy = new QSignalSpy(task, SIGNAL(failed(QString))); +- authSpy = new QSignalSpy(model, SIGNAL(authRequested())); +- connErrorSpy = new QSignalSpy(model, SIGNAL(imapError(QString))); +- startTlsUpgradeSpy = new QSignalSpy(model, SIGNAL(requireStartTlsInFuture())); +- authErrorSpy = new QSignalSpy(model, SIGNAL(imapAuthErrorChanged(const QString&))); ++ completedSpy.reset(new QSignalSpy(task, SIGNAL(completed(Imap::Mailbox::ImapTask*)))); ++ failedSpy.reset(new QSignalSpy(task, SIGNAL(failed(QString)))); ++ authSpy.reset(new QSignalSpy(model, SIGNAL(authRequested()))); ++ connErrorSpy.reset(new QSignalSpy(model, SIGNAL(imapError(QString)))); ++ startTlsUpgradeSpy.reset(new QSignalSpy(model, SIGNAL(requireStartTlsInFuture()))); ++ authErrorSpy.reset(new QSignalSpy(model, SIGNAL(imapAuthErrorChanged(const QString&)))); + t.reset(); + } + +diff --git a/tests/Imap/test_Imap_Tasks_OpenConnection.h b/tests/Imap/test_Imap_Tasks_OpenConnection.h +index 30f531a2..4df65c05 100644 +--- a/tests/Imap/test_Imap_Tasks_OpenConnection.h ++++ b/tests/Imap/test_Imap_Tasks_OpenConnection.h +@@ -78,13 +78,13 @@ protected: + void reinit(const TlsRequired tlsRequired = TlsRequired::No); + + private: +- Imap::Mailbox::OpenConnectionTask* task; +- QSignalSpy* completedSpy; +- QSignalSpy* failedSpy; +- QSignalSpy* authSpy; +- QSignalSpy *connErrorSpy; +- QSignalSpy *startTlsUpgradeSpy; +- QSignalSpy *authErrorSpy; ++ QPointer<Imap::Mailbox::OpenConnectionTask> task; ++ std::unique_ptr<QSignalSpy> completedSpy; ++ std::unique_ptr<QSignalSpy> failedSpy; ++ std::unique_ptr<QSignalSpy> authSpy; ++ std::unique_ptr<QSignalSpy> connErrorSpy; ++ std::unique_ptr<QSignalSpy> startTlsUpgradeSpy; ++ std::unique_ptr<QSignalSpy> authErrorSpy; + + bool m_enableAutoLogin; + }; +-- +GitLab + |