From cfee3304bec85d78140072bff419a59897a3d504 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 18 Oct 2024 12:13:53 +0200 Subject: [PATCH] a11y: add more nullptr checks for the view Interface implementations related to child navigation might be called while the object is getting destroyed, in which case the view might already be degenerated to a widget. In that case, qobject_cast will fail and we would dereference a nullptr later. Prevent that by adding more nullptr checks. As a drive-by, reuse the down-cast pointer in more of the implementation. Pick-to: 6.5 Fixes: QTBUG-129582 Change-Id: I06a80576a5d71150787f493e2b6c9a58696eac99 Reviewed-by: Michael Weghorn Reviewed-by: Dheerendra Purohit Reviewed-by: Volker Hilsheimer (cherry picked from commit 9965f9a191a426e65e32b3f833f2aedcc19ef405) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/accessible/itemviews.cpp | 33 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index eb7446b10b1..fc969e17380 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -545,6 +545,8 @@ QAccessibleInterface *QAccessibleTable::focusChild() const int QAccessibleTable::childCount() const { const QAbstractItemView *theView = view(); + if (!theView) + return 0; const QAbstractItemModel *theModel = theView->model(); if (!theModel) return 0; @@ -557,6 +559,8 @@ int QAccessibleTable::childCount() const int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const { const QAbstractItemView *theView = view(); + if (!theView) + return -1; const QAbstractItemModel *theModel = theView->model(); if (!theModel) return -1; @@ -614,6 +618,9 @@ QAccessibleInterface *QAccessibleTable::parent() const QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const { QAbstractItemView *theView = view(); + if (!theView) + return nullptr; + const QAbstractItemModel *theModel = theView->model(); if (!theModel) return nullptr; @@ -804,11 +811,13 @@ QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const { const QAbstractItemView *theView = view(); + if (!theView) + return nullptr; const QAbstractItemModel *theModel = theView->model(); if (!theModel) return nullptr; - const QPoint viewportOffset = theView->viewport()->mapTo(view(), QPoint(0, 0)); + const QPoint viewportOffset = theView->viewport()->mapTo(theView, QPoint(0, 0)); const QPoint indexPosition = theView->mapFromGlobal(QPoint(x, y) - viewportOffset); const QModelIndex index = theView->indexAt(indexPosition); @@ -826,6 +835,8 @@ QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const QAccessibleInterface *QAccessibleTree::focusChild() const { const QAbstractItemView *theView = view(); + if (!theView) + return nullptr; const QAbstractItemModel *theModel = theView->model(); const QModelIndex index = theView->currentIndex(); if (!index.isValid()) @@ -842,7 +853,8 @@ QAccessibleInterface *QAccessibleTree::focusChild() const int QAccessibleTree::childCount() const { const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); + if (!treeView) + return 0; const QAbstractItemModel *theModel = treeView->model(); if (!theModel) return 0; @@ -854,7 +866,9 @@ int QAccessibleTree::childCount() const QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const { - const QAbstractItemView *theView = view(); + QAbstractItemView *theView = view(); + if (!theView) + return nullptr; const QAbstractItemModel *theModel = theView->model(); const QModelIndex rootIndex = theView->rootIndex(); if (logicalIndex < 0 || !theModel || !theModel->columnCount(rootIndex)) @@ -869,7 +883,7 @@ QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const if (horizontalHeader()) { if (index < theModel->columnCount(rootIndex)) - iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal); + iface = new QAccessibleTableHeaderCell(theView, index, Qt::Horizontal); else index -= theModel->columnCount(rootIndex); } @@ -880,7 +894,7 @@ QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const const QModelIndex modelIndex = indexFromLogical(row, column); if (!modelIndex.isValid()) return nullptr; - iface = new QAccessibleTableCell(view(), modelIndex, cellRole()); + iface = new QAccessibleTableCell(theView, modelIndex, cellRole()); } QAccessible::registerAccessibleInterface(iface); childToId.insert(logicalIndex, QAccessible::uniqueId(iface)); @@ -890,18 +904,21 @@ QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const int QAccessibleTree::rowCount() const { const QTreeView *treeView = qobject_cast(view()); - Q_ASSERT(treeView); + if (!treeView) + return 0; return treeView->d_func()->viewItems.size(); } int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const { const QAbstractItemView *theView = view(); + if (!theView) + return -1; const QAbstractItemModel *theModel = theView->model(); if (!theModel) return -1; QAccessibleInterface *parent = iface->parent(); - if (parent->object() != view()) + if (parent->object() != theView) return -1; if (iface->role() == QAccessible::TreeItem) { @@ -990,6 +1007,8 @@ bool QAccessibleTree::selectRow(int row) QAccessibleInterface *QAccessibleList::child(int logicalIndex) const { QAbstractItemView *theView = view(); + if (!theView) + return nullptr; const QAbstractItemModel *theModel = theView->model(); if (!theModel) return nullptr;