diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2012-08-06 16:45:06 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-07 11:15:55 +0200 |
commit | b84e180263d0da3d1e6967fcf759225a778ea6ea (patch) | |
tree | 8635817a586ee10c7b6f839d17f9800f977ed185 /src | |
parent | b37849a5f54d7d3e66adb4430daa2cbd7b366f13 (diff) |
Avoid crashes when invalidating a proxy model filter.
Task-number: QTBUG-26107
Change-Id: I2df7ae6402136570c8469d3251edae6ca8290f1f
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/itemmodels/qsortfilterproxymodel.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 875bb81967..fb84dce861 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -1049,12 +1049,19 @@ void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_pare Mapping *m = it.value(); QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); - QVector<QModelIndex>::iterator it2 = m->mapped_children.end(); - while (it2 != m->mapped_children.begin()) { + + // We need to iterate over a copy of m->mapped_children because otherwise it may be changed by other code, invalidating + // the iterator it2. + // The m->mapped_children vector can be appended to when this function recurses for child indexes. + // The handle_filter_changed implementation can cause source_parent.parent() to be called, which will create + // a mapping (and do appending) while we are invalidating the filter. + QVector<QModelIndex> mappedChildren = m->mapped_children; + QVector<QModelIndex>::iterator it2 = mappedChildren.end(); + while (it2 != mappedChildren.begin()) { --it2; const QModelIndex source_child_index = *it2; if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) { - it2 = m->mapped_children.erase(it2); + it2 = mappedChildren.erase(it2); remove_from_mapping(source_child_index); } else { filter_changed(source_child_index); |