summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-03-09 11:09:18 +0100
committerMarc Mutz <marc.mutz@kdab.com>2016-03-09 13:18:19 +0000
commit3856099d9a6c9cd90747d530819df8c99198fa54 (patch)
treea5ca82c704b1ab2b75d610cdbe19ea3afbdc0a81 /src
parent1bfc7f680fc3dd839eac553c80d151a2cc7bfa3d (diff)
QGestureManager: fix UB in filterEvent()
The code infers from the presence of an address in a QHash<QGesture *, ...> that the address belongs to a QGesture. So far that is fine enough. But in order to perform the lookup, it static_cast<>s the QObject* argument to a QGesture* for the QHash:: contains() call. Even though the pointer is not dereferenced, the cast is UB. Says UBSan: qgesturemanager.cpp:558:73: runtime error: downcast of address 0x2ab83364f3a0 which does not point to an object of type 'QGesture' 0x2ab83364f3a0: note: object is of type 'QDBusConnectionManager' which is a particularly hideous error message because of the constantly-changing completely-unrelated actual type in the second line of the message: 52 QDBusConnectionManager 19 QSocketNotifier 14 QFusionStyle 13 QAction 6 QApplication 3 QGraphicsWidget 1 Window 1 TestRunnable 1 RectWidget 1 QTimer 1 QSingleShotTimer 1 QOffscreenSurface 1 QGraphicsProxyWidget 1 QDefaultAnimationDriver 1 QDBusPendingCallWatcherHelper This error is also _very_ common, triggered 116 times in a single run of make -C tests/auto check. Fix by using qobject_cast first and then doing the lookup only when the cast succeeded. Depending on the performance of qobject_cast<>, this may actually perform better, too. Change-Id: I884ec7d885711acc3c1d004ce93c628268d8fc18 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index fb2914d53a..967ef6b40c 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -548,9 +548,9 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
if (widgetWindow)
return filterEvent(widgetWindow->widget(), event);
- if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
+ QGesture *state = qobject_cast<QGesture *>(receiver);
+ if (!state || !m_gestureToRecognizer.contains(state))
return false;
- QGesture *state = static_cast<QGesture *>(receiver);
QMultiMap<QObject *, Qt::GestureType> contexts;
contexts.insert(state, state->gestureType());
return filterEventThroughContexts(contexts, event);