Browse Source

Add compat mode for old (32bit FileSize) CacheDB (LP: #1274466)

tags/debian/1.0.4
Michael Vogt 7 years ago
parent
commit
243b2a381f
5 changed files with 129 additions and 11 deletions
  1. +59
    -10
      ftparchive/cachedb.cc
  2. +19
    -1
      ftparchive/cachedb.h
  3. BIN
      test/integration/cachedb-lp1274466-old-format.db
  4. BIN
      test/integration/deb-lp1274466-cachedb.deb
  5. +51
    -0
      test/integration/test-apt-ftparchive-cachedb-lp1274466

+ 59
- 10
ftparchive/cachedb.cc View File

@@ -99,7 +99,7 @@ bool CacheDB::ReadyDB(std::string const &DB)
return _error->Error(_("Unable to open DB file %s: %s"),DB.c_str(), db_strerror(err));
}
}
DBFile = DB;
DBLoaded = true;
return true;
@@ -185,6 +185,45 @@ bool CacheDB::GetFileStat(bool const &doStat)
CurStat.mtime = htonl(St.st_mtime);
CurStat.Flags |= FlSize;
return true;
}
/*}}}*/
// CacheDB::GetCurStatCompatOldFormat /*{{{*/
// ---------------------------------------------------------------------
/* Read the old (32bit FileSize) StateStore format from disk */
bool CacheDB::GetCurStatCompatOldFormat()
{
InitQueryStats();
Data.data = &CurStatOldFormat;
Data.flags = DB_DBT_USERMEM;
Data.ulen = sizeof(CurStatOldFormat);
if (Get() == false)
{
CurStat.Flags = 0;
} else {
CurStat.Flags = CurStatOldFormat.Flags;
CurStat.mtime = CurStatOldFormat.mtime;
CurStat.FileSize = CurStatOldFormat.FileSize;
memcpy(CurStat.MD5, CurStatOldFormat.MD5, sizeof(CurStat.MD5));
memcpy(CurStat.SHA1, CurStatOldFormat.SHA1, sizeof(CurStat.SHA1));
memcpy(CurStat.SHA256, CurStatOldFormat.SHA256, sizeof(CurStat.SHA256));
}
return true;
}
/*}}}*/
// CacheDB::GetCurStatCompatOldFormat /*{{{*/
// ---------------------------------------------------------------------
/* Read the new (64bit FileSize) StateStore format from disk */
bool CacheDB::GetCurStatCompatNewFormat()
{
InitQueryStats();
Data.data = &CurStat;
Data.flags = DB_DBT_USERMEM;
Data.ulen = sizeof(CurStat);
if (Get() == false)
{
CurStat.Flags = 0;
}
return true;
}
/*}}}*/
@@ -198,19 +237,29 @@ bool CacheDB::GetCurStat()
if (DBLoaded)
{
/* First see if there is anything about it
in the database */
/* Get the flags (and mtime) */
// do a first query to just get the size of the data on disk
InitQueryStats();
// Ensure alignment of the returned structure
Data.data = &CurStat;
Data.ulen = sizeof(CurStat);
Data.flags = DB_DBT_USERMEM;
if (Get() == false)
Data.ulen = 0;
Get();

if (Data.size == 0)
{
CurStat.Flags = 0;
}
// nothing needs to be done, we just have not data for this deb
}
// check if the record is written in the old format (32bit filesize)
else if(Data.size == sizeof(CurStatOldFormat))
{
GetCurStatCompatOldFormat();
}
else if(Data.size == sizeof(CurStat))
{
GetCurStatCompatNewFormat();
} else {
return _error->Error("Cache record size mismatch (%ul)", Data.size);
}

CurStat.Flags = ntohl(CurStat.Flags);
CurStat.FileSize = ntohl(CurStat.FileSize);
}


+ 19
- 1
ftparchive/cachedb.h View File

@@ -85,8 +85,12 @@ class CacheDB
bool OpenDebFile();
void CloseDebFile();

bool GetFileStat(bool const &doStat = false);
// GetCurStat needs some compat code, see lp #1274466)
bool GetCurStatCompatOldFormat();
bool GetCurStatCompatNewFormat();
bool GetCurStat();

bool GetFileStat(bool const &doStat = false);
bool LoadControl();
bool LoadContents(bool const &GenOnly);
bool LoadSource();
@@ -101,6 +105,20 @@ class CacheDB
FlSHA512=(1<<6), FlSource=(1<<7),
};

// the on-disk format changed (FileSize increased to 64bit) in
// commit 650faab0 which will lead to corruption with old caches
struct StatStoreOldFormat
{
uint32_t Flags;
uint32_t mtime;
uint32_t FileSize;
uint8_t MD5[16];
uint8_t SHA1[20];
uint8_t SHA256[32];
} CurStatOldFormat;

// WARNING: this struct is read/written to the DB so do not change the
// layout of the fields (see lp #1274466), only append to it
struct StatStore
{
uint32_t Flags;


BIN
test/integration/cachedb-lp1274466-old-format.db View File


BIN
test/integration/deb-lp1274466-cachedb.deb View File


+ 51
- 0
test/integration/test-apt-ftparchive-cachedb-lp1274466 View File

@@ -0,0 +1,51 @@
#!/bin/sh
set -e


#
# main()
#
TESTDIR=$(readlink -f $(dirname $0))
. $TESTDIR/framework
setupenvironment
configarchitecture "i386"

# gather the db and the deb, ensure mtime is not modfied as its saved in the DB
cp -p $TESTDIR/deb-lp1274466-cachedb.deb foo_1_i386.deb
cp $TESTDIR/cachedb-lp1274466-old-format.db old-format.db

# verify that the format is different
testsuccess aptftparchive --db new-format.db packages .
db_dump new-format.db > new-format.dump
db_dump old-format.db > old-format.dump
testfailure diff -u old-format.dump new-format.dump

# ensure the new format as the sha512
testsuccess grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc12a0e7cadb4b66764235c56e1009dbfe8a9a566fb1eedf47a992d1fff2cc3332c new-format.dump
# but the old format does not
testfailure grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc12a0e7cadb4b66764235c56e1009dbfe8a9a566fb1eedf47a992d1fff2cc3332c old-format.dump

# regression test for corruption with previous generation of cachedb
testequal "Package: foo
Priority: optional
Section: others
Installed-Size: 29
Maintainer: Joe Sixpack <joe@example.org>
Architecture: i386
Version: 1
Filename: ./foo_1_i386.deb
Size: 1270
MD5sum: 85d0e908c1a897700e2c5dea72d7e3c0
SHA1: 858b09169032b7925a0e463f46b6634243fc40ce
SHA256: 3750a2c9c6b5beee7f307564be3d51d3ec7cbb78fa4f0b47f84a7c41477bff59
SHA512: 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc12a0e7cadb4b66764235c56e1009dbfe8a9a566fb1eedf47a992d1fff2cc3332c
Description: an autogenerated dummy foo=1/test
If you find such a package installed on your system,
something went horribly wrong! They are autogenerated
und used only by testcases and surf no other propose…
" aptftparchive --db old-format.db packages .

# ensure that the db is updated
db_dump old-format.db > old-format.dump
testsuccess diff -u old-format.dump new-format.dump


Loading…
Cancel
Save