Fix to crash in QWindow::event when delete this called on closeEvent

Starting from Qt 5.11 QWindow::event is called after QDialog::closeEvent
which would cause a crash if "delete this" was called on closeEvent.  The commit
that changed this was e0b5ff4ad583befbecbcbe462998e3ed80899531. Added
a check before QWindow::event call utilizing QPointer to prevent the
function call in case object is destroyed by a user in close event handler.

Change-Id: I64a4a0f3271714e55bf7e806177f0d8b39b67fa3
Fixes: QTBUG-84222
Pick-to: 5.15 5.12
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Miika Pernu 2020-05-14 15:26:51 +03:00 committed by Volker Hilsheimer
parent c7b457e287
commit 036c3c19e7
2 changed files with 25 additions and 2 deletions

View File

@ -249,10 +249,14 @@ bool QWidgetWindow::event(QEvent *event)
}
switch (event->type()) {
case QEvent::Close:
case QEvent::Close: {
// The widget might be deleted in the close event handler.
QPointer<QObject> guard = this;
handleCloseEvent(static_cast<QCloseEvent *>(event));
QWindow::event(event);
if (guard)
QWindow::event(event);
return true;
}
case QEvent::Enter:
case QEvent::Leave:

View File

@ -419,6 +419,7 @@ private slots:
void receivesLanguageChangeEvent();
void receivesApplicationFontChangeEvent();
void receivesApplicationPaletteChangeEvent();
void deleteWindowInCloseEvent();
private:
bool ensureScreenSize(int width, int height);
@ -11774,5 +11775,23 @@ void tst_QWidget::receivesApplicationPaletteChangeEvent()
QApplication::setPalette(origPalette);
}
class DeleteOnCloseEventWidget : public QWidget
{
protected:
virtual void closeEvent(QCloseEvent *e) override
{
e->accept();
delete this;
}
};
void tst_QWidget::deleteWindowInCloseEvent()
{
// Just checking if closing this widget causes a crash
auto widget = new DeleteOnCloseEventWidget;
widget->close();
QVERIFY(true);
}
QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc"