From 103d9c69dd4ff3c8db52953728915ba62a340011 Mon Sep 17 00:00:00 2001 From: zhanghongyuan Date: Wed, 30 Sep 2026 16:14:34 +0800 Subject: [PATCH] fix: walk the parent chain safely in CentralDocPage isFullScreen()/openFullScreen()/quitFullScreen()/onSheetCountChanged() called parentWidget()->parentWidget()->parentWidget() unchecked; if the widget has fewer than three levels of parents (embedded use, tests) the chain dereferences a null QWidget and crashes. The existing null check only covered the final dynamic_cast result. Replace the chained calls with a parentMainWindow() helper that stops at the first null level. Log: Influence: doc page fullscreen handling --- reader/uiframe/CentralDocPage.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/reader/uiframe/CentralDocPage.cpp b/reader/uiframe/CentralDocPage.cpp index 4cd838bbb..94dc67f64 100644 --- a/reader/uiframe/CentralDocPage.cpp +++ b/reader/uiframe/CentralDocPage.cpp @@ -891,10 +891,22 @@ void CentralDocPage::prepareSearch() docSheet->prepareSearch(); } +// Walk up the fixed three-level parent chain safely: parentWidget() may +// return nullptr at any level (embedded or test environments), and calling +// parentWidget() on a null pointer crashes. +static MainWindow *parentMainWindow(CentralDocPage *page) +{ + QWidget *widget = page; + for (int i = 0; i < 3 && widget != nullptr; ++i) { + widget = widget->parentWidget(); + } + return widget != nullptr ? dynamic_cast(widget) : nullptr; +} + bool CentralDocPage::isFullScreen() { // qCInfo(appLog) << "isFullScreen"; - MainWindow *mainWindow = dynamic_cast(parentWidget()->parentWidget()->parentWidget()); + MainWindow *mainWindow = parentMainWindow(this); if (nullptr == mainWindow) return false; @@ -905,7 +917,7 @@ bool CentralDocPage::isFullScreen() void CentralDocPage::openFullScreen() { qCInfo(appLog) << "openFullScreen"; - MainWindow *mainWindow = dynamic_cast(parentWidget()->parentWidget()->parentWidget()); + MainWindow *mainWindow = parentMainWindow(this); if (nullptr == mainWindow) return; @@ -925,7 +937,7 @@ void CentralDocPage::openFullScreen() bool CentralDocPage::quitFullScreen(bool force) { qCInfo(appLog) << "quitFullScreen"; - MainWindow *mainWindow = dynamic_cast(parentWidget()->parentWidget()->parentWidget()); + MainWindow *mainWindow = parentMainWindow(this); if (nullptr == mainWindow) return false; @@ -973,7 +985,7 @@ void CentralDocPage::onSheetCountChanged(int count) m_tabBar->setVisible(true); } - MainWindow *mainWindow = dynamic_cast(parentWidget()->parentWidget()->parentWidget()); + MainWindow *mainWindow = parentMainWindow(this); if (mainWindow && mainWindow->isFullScreen()) { qCInfo(appLog) << "mainWindow && mainWindow->isFullScreen()";