summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-01-27 00:15:12 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2016-01-27 00:15:12 +0100
commita133f79c8766aee5b7d7811285e60b3d311d8473 (patch)
tree3aacdd4256d6419760d6843e7574ba6c334a136b
parent8efd5947bf7de0fc3db51b4871bcf3522018761d (diff)
deal better with (very) small apt::cache-start values
It is a bit academic to support values which aren't big enough to fit even the hashtables without resizing, but cleaning up ensures that we do the right thing (aka not segfaulting) even if something goes wrong in these deep layers. You still can't have very very small values through… Git-Dch: Ignore
-rw-r--r--apt-pkg/cachefile.cc2
-rw-r--r--apt-pkg/pkgcachegen.cc40
-rw-r--r--apt-pkg/pkgcachegen.h1
3 files changed, 26 insertions, 17 deletions
diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
index 3e3540bbd..6db0749d4 100644
--- a/apt-pkg/cachefile.cc
+++ b/apt-pkg/cachefile.cc
@@ -221,7 +221,7 @@ bool pkgCacheFile::AddIndexFile(pkgIndexFile * const File) /*{{{*/
{
{
pkgCacheGenerator Gen(dynmmap, nullptr);
- if (File->Merge(Gen, nullptr) == false)
+ if (Gen.Start() == false || File->Merge(Gen, nullptr) == false)
return false;
}
Cache = new pkgCache(Map);
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index a48fe7946..639ad215c 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -58,6 +58,9 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
Map(*pMap), Cache(pMap,false), Progress(Prog),
CurrentRlsFile(NULL), CurrentFile(NULL), d(NULL)
{
+}
+bool pkgCacheGenerator::Start()
+{
if (Map.Size() == 0)
{
// Setup the map interface..
@@ -67,7 +70,9 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
bool const newError = _error->PendingError();
_error->MergeWithStack();
if (newError)
- return;
+ return false;
+ if (Map.Size() <= 0)
+ return false;
Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
@@ -76,16 +81,15 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
// make room for the hashtables for packages and groups
if (Map.RawAllocate(2 * (Cache.HeaderP->GetHashTableSize() * sizeof(map_pointer_t))) == 0)
- return;
+ return false;
map_stringitem_t const idxVerSysName = WriteStringInMap(_system->VS->Label);
if (unlikely(idxVerSysName == 0))
- return;
- Cache.HeaderP->VerSysName = idxVerSysName;
+ return false;
map_stringitem_t const idxArchitecture = StoreString(MIXED, _config->Find("APT::Architecture"));
if (unlikely(idxArchitecture == 0))
- return;
- Cache.HeaderP->Architecture = idxArchitecture;
+ return false;
+ map_stringitem_t idxArchitectures;
std::vector<std::string> archs = APT::Configuration::getArchitectures();
if (archs.size() > 1)
@@ -94,13 +98,17 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
std::string list = *a;
for (++a; a != archs.end(); ++a)
list.append(",").append(*a);
- map_stringitem_t const idxArchitectures = WriteStringInMap(list);
+ idxArchitectures = WriteStringInMap(list);
if (unlikely(idxArchitectures == 0))
- return;
- Cache.HeaderP->SetArchitectures(idxArchitectures);
+ return false;
}
else
- Cache.HeaderP->SetArchitectures(idxArchitecture);
+ idxArchitectures = idxArchitecture;
+
+ Cache.HeaderP = (pkgCache::Header *)Map.Data();
+ Cache.HeaderP->VerSysName = idxVerSysName;
+ Cache.HeaderP->Architecture = idxArchitecture;
+ Cache.HeaderP->SetArchitectures(idxArchitectures);
// Calculate the hash for the empty map, so ReMap does not fail
Cache.HeaderP->CacheFileSize = Cache.CacheHash();
@@ -112,14 +120,12 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
Cache.ReMap();
Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
if (Cache.VS != _system->VS)
- {
- _error->Error(_("Cache has an incompatible versioning system"));
- return;
- }
+ return _error->Error(_("Cache has an incompatible versioning system"));
}
Cache.HeaderP->Dirty = true;
Map.Sync(0,sizeof(pkgCache::Header));
+ return true;
}
/*}}}*/
// CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/
@@ -1607,7 +1613,7 @@ static bool loadBackMMapFromFile(std::unique_ptr<pkgCacheGenerator> &Gen,
if (CacheF.Read((unsigned char *)Map->Data() + alloc, CacheF.Size()) == false)
return false;
Gen.reset(new pkgCacheGenerator(Map.get(),Progress));
- return true;
+ return Gen->Start();
}
bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
MMap **OutMap, bool AllowMem)
@@ -1713,6 +1719,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
if (Debug == true)
std::clog << "srcpkgcache.bin is NOT valid - rebuild" << std::endl;
Gen.reset(new pkgCacheGenerator(Map.get(),Progress));
+ if (Gen->Start() == false)
+ return false;
TotalSize += ComputeSize(&List, Files.begin(),Files.end());
if (BuildCache(*Gen, Progress, CurrentSize, TotalSize, &List,
@@ -1790,7 +1798,7 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
if (Progress != NULL)
Progress->OverallProgress(0,1,1,_("Reading package lists"));
pkgCacheGenerator Gen(Map.get(),Progress);
- if (_error->PendingError() == true)
+ if (Gen.Start() == false || _error->PendingError() == true)
return false;
if (BuildCache(Gen,Progress,CurrentSize,TotalSize, NULL,
Files.begin(), Files.end()) == false)
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index d0ae67997..228b9f71d 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -153,6 +153,7 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/
APT_PUBLIC static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap);
void ReMap(void const * const oldMap, void const * const newMap, size_t oldSize);
+ bool Start();
pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
virtual ~pkgCacheGenerator();