From 7caaf4eb7f8b536de2a77db59fdd7acba2a566a7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 28 Jan 2020 19:31:24 +0100 Subject: Don't rely on iterators being stable while modifying the hash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Mapping struct referred to where it got inserted into the source_index mapping table by a const iterator to the table. That is rather fragile, as changing the table invalidates the iterator. It happened to work with QHash in Qt 5, but will break with the new implementation in Qt 6. Instead simply store the key in the Mapping struct so that it can be quickly found in the hash. Also fix one place, where we unconditionally call erase on an iterator returned by constFind(). Turns out constFind() did sometimes not find the item in question and returns end(). Change-Id: I0420a06d496f640a3150478e8c644d4cc669ceff Reviewed-by: Lars Knoll Reviewed-by: MÃ¥rten Nordheim --- src/corelib/itemmodels/qabstractitemmodel.cpp | 4 +++- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/corelib/itemmodels') diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index f0eb8e5c8b..f132cba473 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -852,7 +852,9 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent, for (QVector::const_iterator it = persistent_invalidated.constBegin(); it != persistent_invalidated.constEnd(); ++it) { QPersistentModelIndexData *data = *it; - persistent.indexes.erase(persistent.indexes.constFind(data->index)); + auto pit = persistent.indexes.constFind(data->index); + if (pit != persistent.indexes.cend()) + persistent.indexes.erase(pit); data->index = QModelIndex(); } } diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 21303549ab..033e4e2f97 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -280,7 +280,7 @@ public: QVector proxy_rows; QVector proxy_columns; QVector mapped_children; - QHash::const_iterator map_iter; + QModelIndex source_parent; }; mutable QHash source_index_mapping; @@ -321,7 +321,7 @@ public: const void *p = proxy_index.internalPointer(); Q_ASSERT(p); QHash::const_iterator it = - static_cast(p)->map_iter; + source_index_mapping.constFind(static_cast(p)->source_parent); Q_ASSERT(it != source_index_mapping.constEnd()); Q_ASSERT(it.value()); return it; @@ -517,8 +517,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( m->proxy_columns.resize(source_cols); build_source_to_proxy_mapping(m->source_columns, m->proxy_columns); - it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m)); - m->map_iter = it; + m->source_parent = source_parent; if (source_parent.isValid()) { QModelIndex source_grand_parent = source_parent.parent(); @@ -527,6 +526,7 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( it2.value()->mapped_children.append(source_parent); } + it = IndexMap::const_iterator(source_index_mapping.insert(source_parent, m)); Q_ASSERT(it != source_index_mapping.constEnd()); Q_ASSERT(it.value()); @@ -1169,7 +1169,8 @@ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &sour // reinsert moved, mapped indexes QVector >::iterator it = moved_source_index_mappings.begin(); for (; it != moved_source_index_mappings.end(); ++it) { - (*it).second->map_iter = QHash::const_iterator(source_index_mapping.insert((*it).first, (*it).second)); + it->second->source_parent = it->first; + source_index_mapping.insert(it->first, it->second); } } -- cgit v1.2.3