From 03daf6685eda50d79b9b4598ebf6c301def73daa Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 26 Mar 2025 21:40:00 +0100 Subject: [PATCH] QTapGestureRecognizer: fix UB (invalid downcast) in recognize() The old code cast the event to QTouchEvent* ahead of checking that it actually is of a type() that suggests is-a QTouchEvent. I'm not sure this was UB, because we weren't dereferencing the result until after we checked type(). Then again, who am I to argue with compiler writers (= same people that write ubsan)? Says UBSan: qstandardgestures.cpp:402:29: runtime error: downcast of address 0x7fffedb894f0 which does not point to an object of type 'QTouchEvent' 0x7fffedb894f0: note: object is of type 'QEvent' ff 7f 00 00 c0 db 01 cf 99 7f 00 00 15 00 00 00 01 00 00 00 01 00 00 00 99 7f 00 00 b6 c4 14 f5 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for 'QEvent' Fix my delaying the cast until after we know that event is-a QTouchEvent. All other recognize() overload already behaved correctly. As a drive-by, use auto (RHS contains the type) and mark the result const. Amends the start of the public history. Pick-to: 6.9 6.8 6.5 5.15 Change-Id: Ifa9e940232b93b2ecf666c35536519a8385c9800 Reviewed-by: Axel Spoerl --- src/widgets/kernel/qstandardgestures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp index 9e56c5a8d79..fe331419ca4 100644 --- a/src/widgets/kernel/qstandardgestures.cpp +++ b/src/widgets/kernel/qstandardgestures.cpp @@ -399,12 +399,11 @@ QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state, QTapGesture *q = static_cast(state); QTapGesturePrivate *d = q->d_func(); - const QTouchEvent *ev = static_cast(event); - QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture; switch (event->type()) { case QEvent::TouchBegin: { + const auto ev = static_cast(event); d->position = ev->points().at(0).position(); q->setHotSpot(ev->points().at(0).globalPosition()); result = QGestureRecognizer::TriggerGesture; @@ -412,6 +411,7 @@ QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state, } case QEvent::TouchUpdate: case QEvent::TouchEnd: { + const auto ev = static_cast(event); if (q->state() != Qt::NoGesture && ev->points().size() == 1) { const QEventPoint &p = ev->points().at(0); QPoint delta = p.position().toPoint() - p.pressPosition().toPoint();