From a0e7fbd4d54ddbea5c2b155b0f828df3ce3c98fb Mon Sep 17 00:00:00 2001 From: Li Xi Date: Thu, 11 Nov 2021 15:23:04 +0800 Subject: [PATCH] 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. Pick-to: 6.2 Fixes: QTBUG-98247 Change-Id: Iff1dbd24fa7ca09098fe49c179770356c966251d Reviewed-by: Volker Hilsheimer --- src/widgets/widgets/qmainwindow.cpp | 13 +++++++------ .../widgets/widgets/qmainwindow/tst_qmainwindow.cpp | 13 +++++++++++++ 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(topLayout->menuBar()); - if (menuBar) { + QMenuBar *oldMenuBar = qobject_cast(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 0eb59fbce6..f2a7981b4c 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(); @@ -674,6 +675,18 @@ void tst_QMainWindow::menuBar() } } +// QTBUG-98247 +void tst_QMainWindow::customMenuBar() +{ + QMainWindow w; + std::unique_ptr 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() {