From 7dd0c2eb45874d3df9a9ee2034501659548a1b97 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sat, 23 Jan 2016 13:15:31 +0100 Subject: Remap StringView instances pointing into the cache It turns out that StringViews might need to be remapped in some places because they come from the cache. For example, some sites pass a Ver.VerStr() to NewProvides(). Such a StringView would become invalid during the duration of the call if the cache is remapped, causing the program to die with a segmentation fault. We can take care of those issues by remapping string views in the same way we remap all the iterators. String views are only remapped if they point into the cache though, this allows us to write more generic code on the callee site without having to check whether the view points into the cache or not. That's not as efficient as possible, but the overhead does not appear to be measurable. Closes: #812251 --- apt-pkg/pkgcachegen.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index a472babeb..d8f161e6d 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -177,6 +177,14 @@ 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); + for (APT::StringView* ViewP : Dynamic::toReMap) { + // Ignore views outside of the cache. + if (ViewP->data() < static_cast(oldMap) + || ViewP->data() > static_cast(oldMap) + oldSize) + continue; + const char *data = ViewP->data() + (static_cast(newMap) - static_cast(oldMap)); + *ViewP = StringView(data , ViewP->size()); + } } /*}}}*/ // CacheGenerator::WriteStringInMap /*{{{*/ map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String, @@ -503,6 +511,7 @@ bool pkgCacheGenerator::AddNewDescription(ListParser &List, pkgCache::VerIterato /* This creates a new group structure and adds it to the hash table */ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name) { + Dynamic DName(Name); Grp = Cache.FindGrp(Name); if (Grp.end() == false) return true; @@ -537,6 +546,8 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name) bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name, StringView Arch) { pkgCache::GrpIterator Grp; + Dynamic DName(Name); + Dynamic DArch(Arch); Dynamic DynGrp(Grp); if (unlikely(NewGroup(Grp, Name) == false)) return false; @@ -1014,6 +1025,9 @@ bool pkgCacheListParser::NewDepends(pkgCache::VerIterator &Ver, { pkgCache::GrpIterator Grp; Dynamic DynGrp(Grp); + Dynamic DynPackageName(PackageName); + Dynamic DynArch(Arch); + Dynamic DynVersion(Version); if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) return false; @@ -1081,6 +1095,9 @@ bool pkgCacheListParser::NewProvides(pkgCache::VerIterator &Ver, uint8_t const Flags) { pkgCache const &Cache = Owner->Cache; + Dynamic DynPkgName(PkgName); + Dynamic DynArch(PkgArch); + Dynamic DynVersion(Version); // We do not add self referencing provides if (Ver.ParentPkg().Name() == PkgName && (PkgArch == Ver.ParentPkg().Arch() || @@ -1134,6 +1151,8 @@ bool pkgCacheListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, StringVi pkgCache &Cache = Owner->Cache; pkgCache::GrpIterator Grp = Cache.FindGrp(Package); Dynamic DynGrp(Grp); + Dynamic DynPackage(Package); + Dynamic DynVersion(Version); if (Grp.end() == true) return NewProvides(Ver, Package, Cache.NativeArch(), Version, Flags); -- cgit v1.2.3