From 78df625510b73d7b7709be16f9a168ba8c3f4d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 6 Dec 2021 19:21:54 +0100 Subject: QMultiHash: fix erase returning the wrong iterator When deleting the last item in a chain, without it being the last item in the chain, then we re-use the iterator which was passed in as an argument. This is wrong if we detached earlier in the function, and means we return an iterator to the previously shared data. Pick-to: 6.2 Change-Id: I7da6309e23a32073da59e7da0cbfd1d16734f1ca Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz --- src/corelib/tools/qhash.h | 5 +++-- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 24fd24e603..d9dfda71c1 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1778,7 +1778,8 @@ public: iterator erase(const_iterator it) { Q_ASSERT(d); - iterator i = detach(it); + iterator iter = detach(it); + iterator i = iter; Chain *e = *i.e; Chain *next = e->next; *i.e = next; @@ -1788,7 +1789,7 @@ public: // last remaining entry, erase i = iterator(d->erase(i.i)); } else { - i = iterator(++it.i); + i = iterator(++iter.i); } } --m_size; diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 7cc4d3d0f0..11e7237ba4 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -550,6 +550,22 @@ void tst_QHash::erase() auto mit = h2.erase(bit); mit = h2.erase(h2.begin()); QVERIFY(mit == h2.end()); + + h2 = QMultiHash(); + h2.emplace(1, 1); + h2.emplace(1, 2); + h2.emplace(3, 1); + h2.emplace(3, 4); + QMultiHash h3 = h2; + auto it = h3.constFind(3); + ++it; + QVERIFY(h3.isSharedWith(h2)); + it = h3.erase(it); + QVERIFY(!h3.isSharedWith(h2)); + if (it != h3.cend()) { + auto it2 = h3.constFind(it.key()); + QCOMPARE(it, it2); + } } /* -- cgit v1.2.3