From ba2ebc24a1b29020699dc2282b05a60506b56c6d Mon Sep 17 00:00:00 2001 From: Arno Rehn Date: Tue, 5 Sep 2023 09:25:43 +0200 Subject: QtFuture: Prevent whenAll()/whenAny() from creating reference cycles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit whenAll() and whenAny() create a shared context object which is referenced by the continuation lambda. The refcount of context is only correctly managed when it is copied non-const to the lambda's capture list. Fixes: QTBUG-116731 Pick-to: 6.6 6.6.0 Change-Id: I8e79e1a0dc867f69bbacf1ed873f353a18f6ad38 Reviewed-by: MÃ¥rten Nordheim --- tests/auto/corelib/thread/qfuture/tst_qfuture.cpp | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'tests/auto/corelib/thread') diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 128a9bd837..f54ea940f7 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -5011,6 +5011,40 @@ void tst_QFuture::continuationsDontLeak() QVERIFY(continuationIsRun); } QCOMPARE(InstanceCounter::count, 0); + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QtFuture::whenAll(f).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QList fs{f}; + QtFuture::whenAll(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QtFuture::whenAny(f).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } + + { + // QTBUG-116731: Must pass with ASan enabled + bool continuationIsRun = false; + auto f = QtFuture::makeReadyValueFuture(42); + QList fs{f}; + QtFuture::whenAny(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; }); + QVERIFY(continuationIsRun); + } } // This test checks that we do not get use-after-free -- cgit v1.2.3