diff options
author | Miika Pernu <miika.pernu@qt.io> | 2020-05-14 15:26:51 +0300 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-06-05 15:53:05 +0200 |
commit | 62b08b50d05098d8215fcf59c23096dbc7420f45 (patch) | |
tree | d3e54d9e7cf9db479e52be2a443b4a5d6f78e4d4 | |
parent | c39dbabde9d98b805f1d1884d3aeee5c8dcb4d03 (diff) | |
download | qtbase-62b08b50d05098d8215fcf59c23096dbc7420f45.tar.gz |
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
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 036c3c19e7da5f1a280750d3c68a0cff38678029)
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 8 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 19 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 0fa3fb4c67..40d8311c25 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -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: diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index ae2eedede5..d913fc7604 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -417,6 +417,7 @@ private slots: void winIdAfterClose(); void receivesLanguageChangeEvent(); + void deleteWindowInCloseEvent(); private: bool ensureScreenSize(int width, int height); @@ -11705,5 +11706,23 @@ void tst_QWidget::receivesLanguageChangeEvent() QCOMPARE(ww.languageChangeCount, 1); } +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" |