summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2015-02-21 09:57:09 +0100
committerMarc Mutz <marc.mutz@kdab.com>2015-02-22 13:45:50 +0000
commit6716fe8cfdeb5f8cd63d6dde8252b25d86622404 (patch)
tree7b2aec6aaad0335b509718e32d2fb54a2a8e3390 /src/corelib/tools
parent9a950655feb709ea515edbbdb66fa5d900dc62ec (diff)
QVector: fix use of invalid iterators in removeAll()
The c2m() function which converts a const_iterator into an iterator is a broken concept for an implicitly shared container such as QVector, because the act of calling begin() as the starting point already detaches and invalidates the c2m argument. This could be fixed in c2m, but the bug wasn't even in c2m, but in removeAll(), which called end() before c2m, so the c2m argument was already invalidated when entering c2m. The solution is to store the positions as indices instead of iterators before calling the first detaching function. Task-number: QTBUG-44592 Change-Id: I66cf4f1277e71148a4d5b5bbfb6a3369ad02db68 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qvector.h4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 07c66bc393..e263b99c02 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -153,7 +153,9 @@ public:
const const_iterator ce = this->cend(), cit = std::find(this->cbegin(), ce, t);
if (cit == ce)
return 0;
- const iterator e = end(), it = std::remove(c2m(cit), e, t);
+ // next operation detaches, so ce, cit may become invalidated:
+ const int firstFoundIdx = std::distance(this->cbegin(), cit);
+ const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, t);
const int result = std::distance(it, e);
erase(it, e);
return result;