From 2a33cb16d6be42b253e9a4169e2c725e17cf7c1a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 19 Apr 2011 15:26:21 +0200 Subject: use the version id instead of the mmap offset as APT-ID This leads to a small performance decrease as we need to build this mapping now while interpreting the Response but a (buggy) solver can't point us to dangerous memory locations anymore this way and VersionCount remains useful for other mapping proposes --- apt-pkg/edsp.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index f8deef8b8..55bc0a0d9 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -39,7 +39,7 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output) fprintf(output, "Installed: yes\n"); if (Pkg->SelectedState == pkgCache::State::Hold) fprintf(output, "Hold: yes\n"); - fprintf(output, "APT-ID: %lu\n", Ver.Index()); + fprintf(output, "APT-ID: %d\n", Ver->ID); fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]); if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) fprintf(output, "Essential: yes\n"); @@ -146,6 +146,17 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { in.OpenDescriptor(input, FileFd::ReadOnly); pkgTagFile response(&in); pkgTagSection section; + + /* We build an map id to mmap offset here + In theory we could use the offset as ID, but then VersionCount + couldn't be used to create other versionmappings anymore and it + would be too easy for a (buggy) solver to segfault APT… */ + unsigned long long const VersionCount = Cache.Head().VersionCount; + unsigned long VerIdx[VersionCount]; + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; ++P) + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) + VerIdx[V->ID] = V.Index(); + while (response.Step(section) == true) { std::string type; if (section.Exists("Install") == true) @@ -156,13 +167,16 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { else continue; - size_t const index = section.FindULL(type.c_str(), 0); - if (index == 0) { + size_t const id = section.FindULL(type.c_str(), VersionCount); + if (id == VersionCount) { _error->Warning("Unable to parse %s request with id value '%s'!", type.c_str(), section.FindS(type.c_str()).c_str()); continue; + } else if (id > Cache.Head().VersionCount) { + _error->Warning("ID value '%s' in %s request stanza is to high to refer to a known version!", section.FindS(type.c_str()).c_str(), type.c_str()); + continue; } - pkgCache::VerIterator Ver(Cache.GetCache(), Cache.GetCache().VerP + index); + pkgCache::VerIterator Ver(Cache.GetCache(), Cache.GetCache().VerP + VerIdx[id]); Cache.SetCandidateVersion(Ver); if (type == "Install") Cache.MarkInstall(Ver.ParentPkg(), false, false); -- cgit v1.2.3