aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2024-02-26 12:29:46 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2024-03-04 16:30:32 +0100
commit10536ea75063210e78563e35e4ad3a755b172530 (patch)
tree5b31eef622e6e48fbf84bb33ddc315f0b93d24f2 /tests/auto/quick
parentf373e6407424bc23f0327b82a0b500d120339632 (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.cpp34
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"