diff options
author | Julian Andres Klode <jak@debian.org> | 2016-03-06 14:44:53 +0100 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2016-03-06 14:57:41 +0100 |
commit | 9e7f83533665c03b52dff5809e7ebd93928ea445 (patch) | |
tree | 51263d7a81e53b27b58c026e51b2ac1777a05ad4 | |
parent | dfcf7f356b790338f0a3e9df3c5d6f159814fe53 (diff) |
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.
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 30 |
1 files 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<void *> seen; if (oldMap == newMap) return; @@ -161,29 +165,39 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM for (std::vector<pkgCache::GrpIterator*>::const_iterator i = Dynamic<pkgCache::GrpIterator>::toReMap.begin(); i != Dynamic<pkgCache::GrpIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::PkgIterator*>::const_iterator i = Dynamic<pkgCache::PkgIterator>::toReMap.begin(); i != Dynamic<pkgCache::PkgIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::VerIterator*>::const_iterator i = Dynamic<pkgCache::VerIterator>::toReMap.begin(); i != Dynamic<pkgCache::VerIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::DepIterator*>::const_iterator i = Dynamic<pkgCache::DepIterator>::toReMap.begin(); i != Dynamic<pkgCache::DepIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::DescIterator*>::const_iterator i = Dynamic<pkgCache::DescIterator>::toReMap.begin(); i != Dynamic<pkgCache::DescIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::PrvIterator*>::const_iterator i = Dynamic<pkgCache::PrvIterator>::toReMap.begin(); i != Dynamic<pkgCache::PrvIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::PkgFileIterator*>::const_iterator i = Dynamic<pkgCache::PkgFileIterator>::toReMap.begin(); i != Dynamic<pkgCache::PkgFileIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (std::vector<pkgCache::RlsFileIterator*>::const_iterator i = Dynamic<pkgCache::RlsFileIterator>::toReMap.begin(); i != Dynamic<pkgCache::RlsFileIterator>::toReMap.end(); ++i) - (*i)->ReMap(oldMap, newMap); + if (std::get<1>(seen.insert(*i)) == true) + (*i)->ReMap(oldMap, newMap); for (APT::StringView* ViewP : Dynamic<APT::StringView>::toReMap) { + if (std::get<1>(seen.insert(ViewP)) == false) + continue; // Ignore views outside of the cache. if (ViewP->data() < static_cast<const char*>(oldMap) || ViewP->data() > static_cast<const char*>(oldMap) + oldSize) |