QSortFilterProxyModel: don't call index(row, 0) if there are no columns

This is invalid, e.g. it asserts in
QConcatenateTablesProxyModel::index()

Fixes: QTBUG-134210
Change-Id: I21acad9497d423b0366991296e8dd498d51395ea
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 93694e99c214a5166fc842f92659e42260230dce)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
David Faure 2025-03-03 19:14:59 +01:00 committed by Qt Cherry-pick Bot
parent 4003ca0d32
commit 149be782bb
2 changed files with 38 additions and 0 deletions

View File

@ -434,6 +434,10 @@ bool QSortFilterProxyModelPrivate::recursiveChildAcceptsRow(int source_row, cons
{ {
Q_Q(const QSortFilterProxyModel); Q_Q(const QSortFilterProxyModel);
const int colCount = model->columnCount(source_parent);
if (colCount == 0) // don't call index(row, 0) if there's no such column
return false;
const QModelIndex index = model->index(source_row, 0, source_parent); const QModelIndex index = model->index(source_row, 0, source_parent);
const int count = model->rowCount(index); const int count = model->rowCount(index);

View File

@ -83,6 +83,7 @@ private Q_SLOTS:
void shouldPropagateDropBetweenItemsAtModelBoundary(); void shouldPropagateDropBetweenItemsAtModelBoundary();
void shouldPropagateDropAfterLastRow_data(); void shouldPropagateDropAfterLastRow_data();
void shouldPropagateDropAfterLastRow(); void shouldPropagateDropAfterLastRow();
void addModelWithFilterOnTop();
void qtbug91788(); void qtbug91788();
void qtbug91878(); void qtbug91878();
void createPersistentOnLayoutAboutToBeChanged(); void createPersistentOnLayoutAboutToBeChanged();
@ -864,6 +865,39 @@ void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow()
} }
class RefuseRowsProxy : public QSortFilterProxyModel
{
public:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
{
Q_UNUSED(source_row)
Q_UNUSED(source_parent)
return false;
}
};
void tst_QConcatenateTablesProxyModel::addModelWithFilterOnTop() // QTBUG-134210
{
// Given a QSFPM -> QConcatenateTablesProxyModel and a QStandardItemModel
QStandardItemModel sim;
sim.appendRow(new QStandardItem("ITEM"));
QConcatenateTablesProxyModel concat;
RefuseRowsProxy proxyFilter;
proxyFilter.setSourceModel(&concat);
proxyFilter.setRecursiveFilteringEnabled(true);
// When adding the QStandardItemModel as source model
concat.addSourceModel(&sim);
// Then the item should be filtered out
// (without hitting an assert in QConcat::index() nor an infinite recursion in QSFPM)
QCOMPARE(concat.rowCount(), 1);
QCOMPARE(concat.columnCount(), 1);
QCOMPARE(proxyFilter.rowCount(), 0);
QCOMPARE(proxyFilter.columnCount(), 1);
}
void tst_QConcatenateTablesProxyModel::qtbug91788() void tst_QConcatenateTablesProxyModel::qtbug91788()
{ {
QConcatenateTablesProxyModel proxyConcat; QConcatenateTablesProxyModel proxyConcat;