tst_QApplication: Fix UBs (invalid cast) in focusMouseClick()

Found by UBSan:

  tst_qapplication.cpp:1754:48: runtime error: member access within address 0x7ffda11f2220 which does not point to an object of type 'SpontaneousEvent'
  0x7ffda11f2220: note: object is of type 'QMouseEvent'

The code attempted to model the layout of a QEvent with another class
that allows public access to the memory location that (hopefully)
corresponds to QEvent::spont, gaining access by casting a QEvent
object to that specifically-crafted class.

Fix by the using the existing QSpontaneKeyEvent::setSpontaneous()
call, which, despite its name, works for all QEvent subclasses, and
which has already been fixed to not invoke UB (in bc087db).

Change-Id: I7db8b8a8a823f7d61ab17375142d19dc3874fea5
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Marc Mutz 2016-09-27 13:59:37 +02:00
parent b9e4206726
commit 5571d2bf62
1 changed files with 3 additions and 22 deletions

View File

@ -1769,25 +1769,6 @@ void tst_QApplication::focusOut()
QTest::qWait(2000);
}
class SpontaneousEvent
{
Q_GADGET
QDOC_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_ENUMS(Type)
public:
enum Type {
Void
};
virtual ~SpontaneousEvent() {}
QEventPrivate *d;
ushort t;
ushort posted : 1;
ushort spont : 1;
};
void tst_QApplication::focusMouseClick()
{
int argc = 1;
@ -1805,14 +1786,14 @@ void tst_QApplication::focusMouseClick()
// now send a mouse button press event and check what happens with the focus
// it should be given to the parent widget
QMouseEvent ev(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QSpontaneKeyEvent::setSpontaneous(&ev);
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QCOMPARE(QApplication::focusWidget(), &w);
// then we give the inner widget strong focus -> it should get focus
w2.setFocusPolicy(Qt::StrongFocus);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QSpontaneKeyEvent::setSpontaneous(&ev);
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QTRY_COMPARE(QApplication::focusWidget(), &w2);
@ -1820,7 +1801,7 @@ void tst_QApplication::focusMouseClick()
// now back to tab focus and click again (it already had focus) -> focus should stay
// (focus was revoked as of QTBUG-34042)
w2.setFocusPolicy(Qt::TabFocus);
reinterpret_cast<SpontaneousEvent *>(&ev)->spont = 1;
QSpontaneKeyEvent::setSpontaneous(&ev);
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
QCOMPARE(QApplication::focusWidget(), &w2);