From 243b2a381f4a12939d91084ecf100ee6d3dcb007 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 4 Jun 2014 12:39:36 +0200 Subject: [PATCH] Add compat mode for old (32bit FileSize) CacheDB (LP: #1274466) --- ftparchive/cachedb.cc | 69 +++++++++++++++--- ftparchive/cachedb.h | 20 ++++- .../cachedb-lp1274466-old-format.db | Bin 0 -> 8192 bytes test/integration/deb-lp1274466-cachedb.deb | Bin 0 -> 1270 bytes .../test-apt-ftparchive-cachedb-lp1274466 | 51 +++++++++++++ 5 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 test/integration/cachedb-lp1274466-old-format.db create mode 100644 test/integration/deb-lp1274466-cachedb.deb create mode 100755 test/integration/test-apt-ftparchive-cachedb-lp1274466 diff --git a/ftparchive/cachedb.cc b/ftparchive/cachedb.cc index 12eac20d8..0901492f7 100644 --- a/ftparchive/cachedb.cc +++ b/ftparchive/cachedb.cc @@ -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); } diff --git a/ftparchive/cachedb.h b/ftparchive/cachedb.h index edb8594bf..29d710d2c 100644 --- a/ftparchive/cachedb.h +++ b/ftparchive/cachedb.h @@ -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; diff --git a/test/integration/cachedb-lp1274466-old-format.db b/test/integration/cachedb-lp1274466-old-format.db new file mode 100644 index 0000000000000000000000000000000000000000..88da5f1ee468cce23eb0bc9b54152560c6b2f4b4 GIT binary patch literal 8192 zcmeH~J!lj`6vyYpgkLnx~o?aA`NHVuOw>!Ewv&_trTMcMo z8U+y>OTj`cZPY>tiXhsEU}3KaDq>+FDuT|O9!cbSn>R4KZ|1#u??1oY<`F_j&Q3RK z#V*q8j16|SjAftOZjX0cw{>sqA>{j}i6@t*+Pj3T`D=oGw{tFg(Lw@900|%gB!C2v z01`j~NB{{S0VIF~{wD#~tFP?WyU9#G*Y$q=r9xbImcN^y$*)$2{r_qnxIzL*00|%g zB!C2v01`j~NB{{`T3yvh_3D>0A#1-bzWmVh_|A=_(0BTydj0m%;+5Vl*M=TkKUEkX z8NcrzIQVn)#qP?j=TGk~eZH_G4VH$FzWTKAu=(T2x`}U73u6=Kf1MnSLAVrU9=xj5wci@ zoqRIM6b~cQ^3}NbliL~gXunfxe}_)meL=`vE?1%cSsJnu*l_OzQ<_Urf}%I3{D>Ro zn^ak+%i|rUTo^lX5<)*D`P#e5#qYQeAyj2O*(#J4lpFq-Jj}-u61Pj|uq=du#mv literal 0 HcmV?d00001 diff --git a/test/integration/deb-lp1274466-cachedb.deb b/test/integration/deb-lp1274466-cachedb.deb new file mode 100644 index 0000000000000000000000000000000000000000..43d7ee6f1db8d6ca8072040ecedbf19a699657a4 GIT binary patch literal 1270 zcmY$iNi0gvu;WTeP0CEn(@o0EODw8XP*5;5F)*|+H#ab}R8TMg@?oT*fq|KciGl(U zK|unSk)8opa(-S(QGSkINn(*+dKF>)W=7_4{qo%$3?RV5{C3*eyekF*$G^{6F7a;5 z&!RagtQ}q=D?L0!qjy+;Q!z|=JN5AjUiEox?2kPQ#7eI&3i8tqHJGMkE!F@0{r!qL zbB?WEyj^9>CXKL#-lvsz-qv5XbnPXb^vb|xp7YqNPjc^Tdi3IyQ$yyLLyT)SY<{+} zqJFdev)?Vb%QtR0W^FAK_;^ynxf^%)+@IHcbc)EE?SGbM9-Azx;(nzh;+OsT|4S#t zyR>I#tnIa1D81D*+heh@diC4DUnf}?pVOAxD}L+8hXv7xt-Ci|G~fMzSKltWrq?`a zxAccAyWWMCBsvB1GOwE4`%mi5W~*B*OTT$X-*4Brxb*V1O#Af*--$I#EHbz7TK+vh zTY&AzliYU2IUiOy_}+fIXGP7-V{-2D2VJ>0&s}iU?V!a;IToF&LwOGOxfrsidGZ~r z{Ia7~?qJ6D7uC5|JKP>G+0`{v`!c`Jsk>w?B6LnkM!9&-t(O#ozq0Ggs>c6?) zY{--nU{rEo>0l64U~*~TAk6u3oZ}D6NiH!a1`P%Vu9U=*M0jEarbL42-4v1w6ciG; zVCj{K`R$BY|Jw#4ZN+!v3lqd^wrzZD!N_)b8K=pPC(gV1USJ6<&Ykm z$e^^Q-|4++P{1Cvvhy>3-6be_!)1t`@@2@%(th0 z=UU6U+CA?PKXXs7T-j3Q8kfu69p*THH@%`z`R%VH>`p>;{Lj6gVum2Tl zzOEDPleu%Q?&MdS9aFA+pY;Fsve-w`590UySJB-2pY_{&?fU(K>^F=4?Em+Fd&Ph6 zAp3y7{0G{5(|>Mzml&CSW7d84T*J*9e)3MeBt1L&3M)sG0tDS-^3Rp|@dgzA0KF4C AwEzGB literal 0 HcmV?d00001 diff --git a/test/integration/test-apt-ftparchive-cachedb-lp1274466 b/test/integration/test-apt-ftparchive-cachedb-lp1274466 new file mode 100755 index 000000000..211740a53 --- /dev/null +++ b/test/integration/test-apt-ftparchive-cachedb-lp1274466 @@ -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 +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 + -- 2.45.2