- Add patch for critical bug: QCache related crashes. * 0001-Fix-QCache-Crash.patch See: https://bugreports.qt.io/browse/QTBUG-89176 OBS-URL: https://build.opensuse.org/request/show/854947 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt:6.0/qt6-base?expand=0&rev=5
125 lines
4.1 KiB
Diff
125 lines
4.1 KiB
Diff
From 15b43b5ded62ad76776d69bc64ce2679ddfa8eb8 Mon Sep 17 00:00:00 2001
|
|
From: Mårten Nordheim <marten.nordheim@qt.io>
|
|
Date: Tue, 08 Dec 2020 15:47:47 +0100
|
|
Subject: [PATCH] QCache: fix updating entries breaking the internal chain
|
|
|
|
After f08492c6fd9818c7d80b1725355453e179b4d85b was
|
|
merged this bug would manifest as an entry appearing twice
|
|
in the chain when a updating an existing entry (insert with
|
|
an existing key). This could sometimes result in crashes later
|
|
as the list filled up and the list was used in trim() to remove
|
|
various entries.
|
|
|
|
Fixes: QTBUG-89176
|
|
Pick-to: 6.0
|
|
Change-Id: Ide80160fb4317dc0aefe79eec5dce7ec6813e790
|
|
---
|
|
|
|
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
|
|
index 74784af..41cf9ab 100644
|
|
--- a/src/corelib/tools/qcache.h
|
|
+++ b/src/corelib/tools/qcache.h
|
|
@@ -247,14 +247,15 @@
|
|
if (result.initialized) {
|
|
cost -= n->value.cost;
|
|
result.it.node()->emplace(object, cost);
|
|
+ relink(key);
|
|
} else {
|
|
Node::createInPlace(n, key, object, cost);
|
|
+ n->prev = &chain;
|
|
+ n->next = chain.next;
|
|
+ chain.next->prev = n;
|
|
+ chain.next = n;
|
|
}
|
|
total += cost;
|
|
- n->prev = &chain;
|
|
- n->next = chain.next;
|
|
- chain.next->prev = n;
|
|
- chain.next = n;
|
|
return true;
|
|
}
|
|
T *object(const Key &key) const noexcept
|
|
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
|
|
index b3d6844..8361470 100644
|
|
--- a/src/network/kernel/qhostinfo.cpp
|
|
+++ b/src/network/kernel/qhostinfo.cpp
|
|
@@ -916,7 +916,7 @@
|
|
QObject::connect(QCoreApplication::instance(), &QObject::destroyed,
|
|
&threadPool, [&](QObject *) { threadPool.waitForDone(); },
|
|
Qt::DirectConnection);
|
|
- threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel
|
|
+ threadPool.setMaxThreadCount(100); // do up to 20 DNS lookups in parallel
|
|
#endif
|
|
}
|
|
|
|
diff --git a/tests/auto/corelib/tools/qcache/tst_qcache.cpp b/tests/auto/corelib/tools/qcache/tst_qcache.cpp
|
|
index f122e45..2d1ca0a 100644
|
|
--- a/tests/auto/corelib/tools/qcache/tst_qcache.cpp
|
|
+++ b/tests/auto/corelib/tools/qcache/tst_qcache.cpp
|
|
@@ -48,6 +48,7 @@
|
|
void take();
|
|
void axioms_on_key_type();
|
|
void largeCache();
|
|
+ void internalChainHasFullOrder();
|
|
};
|
|
|
|
|
|
@@ -414,5 +415,18 @@
|
|
QVERIFY(cache.size() == 0);
|
|
}
|
|
|
|
+// The internal chain could lose track of some objects.
|
|
+// Make sure it doesn't happen again.
|
|
+void tst_QCache::internalChainHasFullOrder()
|
|
+{
|
|
+ QCache<QString, int> cache;
|
|
+ cache.setMaxCost(20);
|
|
+ cache.insert(QString::number(1), new int, 1);
|
|
+ cache.insert(QString::number(2), new int, 1);
|
|
+ cache.insert(QString::number(1), new int, 1);
|
|
+ cache.setMaxCost(0);
|
|
+ QCOMPARE(cache.size(), 0);
|
|
+}
|
|
+
|
|
QTEST_APPLESS_MAIN(tst_QCache)
|
|
#include "tst_qcache.moc"
|
|
diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
|
|
index 5390433..e895e94 100644
|
|
--- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
|
|
+++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
|
|
@@ -106,6 +106,8 @@
|
|
void cache();
|
|
|
|
void abortHostLookup();
|
|
+
|
|
+ void manylookup();
|
|
protected slots:
|
|
void resultsReady(const QHostInfo &);
|
|
|
|
@@ -731,5 +733,25 @@
|
|
int id;
|
|
};
|
|
|
|
+#include <QNetworkReply>
|
|
+void tst_QHostInfo::manylookup()
|
|
+{
|
|
+ QNetworkAccessManager manager;
|
|
+ auto reply = manager.get(QNetworkRequest(QUrl("https://raw.githubusercontent.com/opendns/public-domain-lists/master/opendns-top-domains.txt")));
|
|
+ QTRY_VERIFY(reply->isFinished());
|
|
+ auto domains = reply->readAll().split('\n');
|
|
+ QTestEventLoop loop;
|
|
+ int done = 0;
|
|
+ for (int i = 0; i < domains.length(); ++i) {
|
|
+ QHostInfo::lookupHost(QString::fromLatin1(domains[i]), &loop,
|
|
+ [&done, &loop](const QHostInfo &h) {
|
|
+ if (++done == 100)
|
|
+ loop.exitLoop();
|
|
+ });
|
|
+ }
|
|
+ loop.enterLoop(5000);
|
|
+ QVERIFY(!loop.timeout());
|
|
+}
|
|
+
|
|
QTEST_MAIN(tst_QHostInfo)
|
|
#include "tst_qhostinfo.moc"
|