summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Xi <lixi@uniontech.com>2021-11-11 15:23:04 +0800
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-16 01:38:34 +0000
commitf9ea9e9b0a57e4b7db929a2b179ba0f3f622431c (patch)
tree2830ff9ab7f83c1ec1d6bebc7862e621bacafd04
parent7fd062560add3bb0eb8f048ebea43c5e1bb9cc77 (diff)
Test result of qobject_cast before dereferencing
Since QMainWindow::setMenuWidget accepts a QWidget (allowing users to implement their own menu widget), we need to use qobject_cast on the stored widget to see if it is a QMenuBar before calling QMenuBar APIs. This qobject_cast may return nullptr. Fixes: QTBUG-98247 Change-Id: Iff1dbd24fa7ca09098fe49c179770356c966251d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit a0e7fbd4d54ddbea5c2b155b0f828df3ce3c98fb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/widgets/widgets/qmainwindow.cpp13
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp13
2 files changed, 20 insertions, 6 deletions
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 7cffd90aba..5aeea88e4e 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -522,10 +522,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
{
QLayout *topLayout = layout();
- if (topLayout->menuBar() && topLayout->menuBar() != menuBar) {
+ if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
// Reparent corner widgets before we delete the old menu bar.
- QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(topLayout->menuBar());
- if (menuBar) {
+ QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(existingMenuBar);
+ if (oldMenuBar && menuBar) {
// TopLeftCorner widget.
QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
if (cornerWidget)
@@ -535,9 +535,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
if (cornerWidget)
menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
}
- oldMenuBar->hide();
- oldMenuBar->setParent(nullptr);
- oldMenuBar->deleteLater();
+
+ existingMenuBar->hide();
+ existingMenuBar->setParent(nullptr);
+ existingMenuBar->deleteLater();
}
topLayout->setMenuBar(menuBar);
}
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index b31acb2b7a..21eceae5f2 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -111,6 +111,7 @@ private slots:
void iconSize();
void toolButtonStyle();
void menuBar();
+ void customMenuBar();
void centralWidget();
void takeCentralWidget();
void corner();
@@ -672,6 +673,18 @@ void tst_QMainWindow::menuBar()
}
}
+// QTBUG-98247
+void tst_QMainWindow::customMenuBar()
+{
+ QMainWindow w;
+ std::unique_ptr<QWidget> menuWidget(new QWidget);
+ w.setMenuWidget(menuWidget.get());
+ QVERIFY(menuWidget->parentWidget());
+ QVERIFY(w.menuBar()); // implicitly calls setMenuBar
+ QVERIFY(!menuWidget->parentWidget());
+ menuWidget.reset();
+}
+
#ifdef QT_BUILD_INTERNAL
void tst_QMainWindow::statusBar()
{