Skip to content

Commit

Permalink
a11y: add more nullptr checks for the view
Browse files Browse the repository at this point in the history
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.8 6.5
Fixes: QTBUG-129582
Change-Id: I06a80576a5d71150787f493e2b6c9a58696eac99
Reviewed-by: Michael Weghorn <[email protected]>
Reviewed-by: Dheerendra Purohit <[email protected]>
Reviewed-by: Volker Hilsheimer <[email protected]>
  • Loading branch information
vohi committed Nov 1, 2024
1 parent f68443d commit 9965f9a
Showing 1 changed file with 26 additions and 7 deletions.
33 changes: 26 additions & 7 deletions src/widgets/accessible/itemviews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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())
Expand All @@ -842,7 +853,8 @@ QAccessibleInterface *QAccessibleTree::focusChild() const
int QAccessibleTree::childCount() const
{
const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
Q_ASSERT(treeView);
if (!treeView)
return 0;
const QAbstractItemModel *theModel = treeView->model();
if (!theModel)
return 0;
Expand All @@ -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))
Expand All @@ -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);
}
Expand All @@ -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));
Expand All @@ -890,18 +904,21 @@ QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const
int QAccessibleTree::rowCount() const
{
const QTreeView *treeView = qobject_cast<const QTreeView*>(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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9965f9a

Please sign in to comment.