From 3856099d9a6c9cd90747d530819df8c99198fa54 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 9 Mar 2016 11:09:18 +0100 Subject: QGestureManager: fix UB in filterEvent() The code infers from the presence of an address in a QHash 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) --- src/widgets/kernel/qgesturemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/widgets/kernel/qgesturemanager.cpp') 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(receiver))) + QGesture *state = qobject_cast(receiver); + if (!state || !m_gestureToRecognizer.contains(state)) return false; - QGesture *state = static_cast(receiver); QMultiMap contexts; contexts.insert(state, state->gestureType()); return filterEventThroughContexts(contexts, event); -- cgit v1.2.3