diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-09-23 15:35:46 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2016-09-24 17:16:19 +0000 |
commit | 6a7b6c376be27390f359f0638f61147478323dae (patch) | |
tree | 79dc4bbe88c9509b2902c4866a2cbb723e472b53 | |
parent | 456ae0dfeb7f537266995c66b180cddf0c587743 (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.cpp | 2 |
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()) /* |