Browse Source

Add support for calculating hashes over the entire cache

tags/debian/1.1.10
Julian Andres Klode 6 years ago
parent
commit
25c7a09d4a
3 changed files with 43 additions and 5 deletions
  1. +33
    -3
      apt-pkg/pkgcache.cc
  2. +3
    -1
      apt-pkg/pkgcache.h
  3. +7
    -1
      apt-pkg/pkgcachegen.cc

+ 33
- 3
apt-pkg/pkgcache.cc View File

@@ -39,6 +39,7 @@
#include <vector>
#include <string>
#include <sys/stat.h>
#include <zlib.h>

#include <apti18n.h>
/*}}}*/
@@ -173,9 +174,6 @@ bool pkgCache::ReMap(bool const &Errorchecks)
HeaderP->CheckSizes(DefHeader) == false)
return _error->Error(_("The package cache file is an incompatible version"));

if (Map.Size() < HeaderP->CacheFileSize)
return _error->Error(_("The package cache file is corrupted, it is too small"));

if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0)
return _error->Error(_("The package cache file is corrupted"));

@@ -193,6 +191,13 @@ bool pkgCache::ReMap(bool const &Errorchecks)
list != StrP + HeaderP->GetArchitectures())
return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str());


auto hash = CacheHash();
if (_config->FindB("Debug::pkgCacheGen", false))
std::clog << "Opened cache with hash " << hash << ", expecting " << HeaderP->CacheFileSize << "\n";
if (hash != HeaderP->CacheFileSize)
return _error->Error(_("The package cache file is corrupted, it has the wrong hash"));

return true;
}
/*}}}*/
@@ -216,6 +221,31 @@ map_id_t pkgCache::sHash(const char *Str) const
Hash = 33 * Hash + tolower_ascii(*I);
return Hash % HeaderP->GetHashTableSize();
}

uint32_t pkgCache::CacheHash()
{
pkgCache::Header header = {};
uLong adler = adler32(0L, Z_NULL, 0);

if (Map.Size() < sizeof(header))
return adler;
memcpy(&header, GetMap().Data(), sizeof(header));

header.Dirty = false;
header.CacheFileSize = 0;

adler = adler32(adler,
reinterpret_cast<const unsigned char *>(&header),
sizeof(header));

if (Map.Size() > sizeof(header)) {
adler = adler32(adler,
static_cast<const unsigned char *>(GetMap().Data()) + sizeof(header),
GetMap().Size() - sizeof(header));
}

return adler;
}
/*}}}*/
// Cache::FindPkg - Locate a package by name /*{{{*/
// ---------------------------------------------------------------------


+ 3
- 1
apt-pkg/pkgcache.h View File

@@ -224,6 +224,8 @@ class pkgCache /*{{{*/
inline map_id_t Hash(const std::string &S) const {return sHash(S);}
inline map_id_t Hash(const char *S) const {return sHash(S);}

APT_HIDDEN uint32_t CacheHash();

// Useful transformation things
static const char *Priority(unsigned char Priority);
@@ -364,7 +366,7 @@ struct pkgCache::Header
map_pointer_t * PkgHashTableP() const { return (map_pointer_t*) (this + 1); }
map_pointer_t * GrpHashTableP() const { return PkgHashTableP() + GetHashTableSize(); }

/** \brief Size of the complete cache file */
/** \brief Hash of the file (TODO: Rename) */
map_filesize_small_t CacheFileSize;

bool CheckSizes(Header &Against) const APT_PURE;


+ 7
- 1
apt-pkg/pkgcachegen.cc View File

@@ -101,6 +101,8 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
else
Cache.HeaderP->SetArchitectures(idxArchitecture);

// Calculate the hash for the empty map, so ReMap does not fail
Cache.HeaderP->CacheFileSize = Cache.CacheHash();
Cache.ReMap();
}
else
@@ -131,7 +133,10 @@ pkgCacheGenerator::~pkgCacheGenerator()
return;
Cache.HeaderP->Dirty = false;
Cache.HeaderP->CacheFileSize = Map.Size();
Cache.HeaderP->CacheFileSize = Cache.CacheHash();

if (_config->FindB("Debug::pkgCacheGen", false))
std::clog << "Produced cache with hash " << Cache.HeaderP->CacheFileSize << std::endl;
Map.Sync(0,sizeof(pkgCache::Header));
}
/*}}}*/
@@ -1534,6 +1539,7 @@ static bool writeBackMMapToFile(pkgCacheGenerator * const Gen, DynamicMMap * con

// Write out the proper header
Gen->GetCache().HeaderP->Dirty = false;
Gen->GetCache().HeaderP->CacheFileSize = Gen->GetCache().CacheHash();
if (SCacheF.Seek(0) == false ||
SCacheF.Write(Map->Data(),sizeof(*Gen->GetCache().HeaderP)) == false)
return _error->Error(_("IO Error saving source cache"));


Loading…
Cancel
Save