diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2024-02-26 12:29:46 +0100 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2024-03-04 16:30:32 +0100 |
commit | 10536ea75063210e78563e35e4ad3a755b172530 (patch) | |
tree | 5b31eef622e6e48fbf84bb33ddc315f0b93d24f2 /tests/auto/quick | |
parent | f373e6407424bc23f0327b82a0b500d120339632 (diff) |
Fix crash when item is deleted in event handler
QQuickDeliveryAgentPrivate::deliverPressOrReleaseEvent() creates a
list of possible targets and iterates over it. This would cause a read
of deleted memory if delivery to one target would cause another item in
the list to be deleted.
Fixes: QTBUG-91272
Pick-to: 6.7 6.6 6.5
Change-Id: I3f648e683d9b441ee0f14e4f721338ac59ace3cc
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r-- | tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp index 52737193a3..3c4533869b 100644 --- a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp +++ b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp @@ -19,6 +19,7 @@ #include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuickTestUtils/private/visualtestutils_p.h> #include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuick/private/qquickmousearea_p.h> #include <QtGui/private/qeventpoint_p.h> @@ -143,6 +144,7 @@ private slots: void hoverEnterOnItemMove(); void hoverEnterOnItemMoveAfterHide(); void clearItemsOnHoverLeave(); + void deleteTargetOnPress(); private: QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); @@ -596,6 +598,38 @@ void tst_qquickdeliveryagent::clearItemsOnHoverLeave() QTest::mouseMove(&window, QPoint(10, 405)); // Exit MouseArea that triggers close. } +// QTBUG-91272 +void tst_qquickdeliveryagent::deleteTargetOnPress() +{ + QQuickWindow window; + auto deliveryAgent = QQuickWindowPrivate::get(&window)->deliveryAgentPrivate(); + window.resize(200, 200); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QQuickMouseArea *lowerArea = new QQuickMouseArea(window.contentItem()); + lowerArea->setWidth(200); + lowerArea->setHeight(200); + + QQuickMouseArea *upperArea = new QQuickMouseArea(window.contentItem()); + upperArea->setWidth(180); + upperArea->setHeight(180); + bool pressed = false; + connect(upperArea, &QQuickMouseArea::pressed, this, [&]() { + pressed = true; + delete lowerArea; + lowerArea = nullptr; + }); + QTest::mouseMove(&window, QPoint(100, 100)); + QTest::mousePress(&window, Qt::MouseButton::LeftButton, {}, {100, 100}); + deliveryAgent->flushFrameSynchronousEvents(&window); + QVERIFY(pressed); + QVERIFY(upperArea->isPressed()); + QTest::mouseRelease(&window, Qt::MouseButton::LeftButton, {}, {100, 100}); + deliveryAgent->flushFrameSynchronousEvents(&window); + QVERIFY(!upperArea->isPressed()); +} + QTEST_MAIN(tst_qquickdeliveryagent) #include "tst_qquickdeliveryagent.moc" |