summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qvector.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2017-11-22 01:05:52 +0100
committerMarc Mutz <marc.mutz@kdab.com>2017-11-28 21:58:50 +0000
commit67391f0a572ddc9c53bdff35dac893b07a862fe5 (patch)
treeecbbd9bdabea8cda10bf3d8bb7caadd313e582fe /src/corelib/tools/qvector.h
parenta0871ad225bc0a7ceed67fa2eb5ed16e475ebd93 (diff)
Fix aliasing problem in QVector::removeAll()
Since removeAll() takes its argument by cref, if passing a reference to an element of the container to removeAll(), the element may be deleted (overwritten) by anyother value, leading to UB. Add a test that actually happens to fail for me without the patch, even though that might not be guaranteed (we may invoke UB). Change-Id: If8c795113aeb515f4a9bdf1e072395b932295667 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qvector.h')
-rw-r--r--src/corelib/tools/qvector.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index da15d401e3..74c37faad0 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -164,9 +164,10 @@ public:
const const_iterator ce = this->cend(), cit = std::find(this->cbegin(), ce, t);
if (cit == ce)
return 0;
- // next operation detaches, so ce, cit may become invalidated:
+ // next operation detaches, so ce, cit, t may become invalidated:
+ const T tCopy = t;
const int firstFoundIdx = std::distance(this->cbegin(), cit);
- const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, t);
+ const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, tCopy);
const int result = std::distance(it, e);
erase(it, e);
return result;