summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-09-23 15:35:46 +0200
committerMarc Mutz <marc.mutz@kdab.com>2016-09-24 17:16:19 +0000
commit6a7b6c376be27390f359f0638f61147478323dae (patch)
tree79dc4bbe88c9509b2902c4866a2cbb723e472b53
parent456ae0dfeb7f537266995c66b180cddf0c587743 (diff)
QApplication: Fix UB (invalid cast) in notify()
Found by UBSan, which was so shocked that it crashed: #6 <signal handler called> #7 __dynamic_cast () at ../../../../gcc/libstdc++-v3/libsupc++/dyncast.cc:50 #8 0x00002b9278fa1c3b in __ubsan::checkDynamicType(void*, void*, unsigned long) () from /opt/gcc/trunk/lib64/libubsan.so.0 #9 0x00002b9278fa10c3 in HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions) () from /opt/gcc/trunk/lib64/libubsan.so.0 #10 0x00002b9278fa1783 in __ubsan_handle_dynamic_type_cache_miss () from /opt/gcc/trunk/lib64/libubsan.so.0 #11 0x00002b926c08ab8d in QApplication::notify(QObject*, QEvent*) () at /home/marc/Qt/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3120 (full backtrace originates in tst_QWidget::testDeletionInEventHandlers(), testing key events). Fix is simple: just perform the cast before delivering the event. Change-Id: Ic26e36f47ef57e980c0dba00900927ff39fe6392 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/widgets/kernel/qapplication.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 917273e8cf..b64d6e2159 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3178,11 +3178,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
key->accept();
else
key->ignore();
- res = d->notify_helper(receiver, e);
QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
#ifndef QT_NO_GRAPHICSVIEW
QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
#endif
+ res = d->notify_helper(receiver, e);
if ((res && key->isAccepted())
/*