From 9e7f83533665c03b52dff5809e7ebd93928ea445 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 6 Mar 2016 14:44:53 +0100 Subject: [PATCH] Prevent double remapping of iterators and string views If an iterator or a stringview has multiple dynamic objects registered with it, it may be remapped twice. Prevent that by noting which iterators/views we have seen and not remapping one if we have already seen it. We most likely do not have any instance of multiple dynamics on a single object, but let's play safe - the overhead is not high. --- apt-pkg/pkgcachegen.cc | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 639ad215c..f9d8a8b4b 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -148,6 +148,10 @@ pkgCacheGenerator::~pkgCacheGenerator() } /*}}}*/ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newMap, size_t oldSize) {/*{{{*/ + // Prevent multiple remaps of the same iterator. If seen.insert(iterator) + // returns (something, true) the iterator was not yet seen and we can + // remap it. + std::unordered_set seen; if (oldMap == newMap) return; @@ -161,29 +165,39 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (APT::StringView* ViewP : Dynamic::toReMap) { + if (std::get<1>(seen.insert(ViewP)) == false) + continue; // Ignore views outside of the cache. if (ViewP->data() < static_cast(oldMap) || ViewP->data() > static_cast(oldMap) + oldSize) -- 2.45.2