Browse Source

rework hashsum verification in the acquire system

Having every item having its own code to verify the file(s) it handles
is an errorprune process and easy to break, especially if items move
through various stages (download, uncompress, patching, …). With a giant
rework we centralize (most of) the verification to have a better
enforcement rate and (hopefully) less chance for bugs, but it breaks the
ABI bigtime in exchange – and as we break it anyway, it is broken even
harder.

It shouldn't effect most frontends as they don't deal with the acquire
system at all or implement their own items, but some do and will need to
be patched (might be an opportunity to use apt on-board material).

The theory is simple: Items implement methods to decide if hashes need to
be checked (in this stage) and to return the expected hashes for this
item (in this stage). The verification itself is done in worker message
passing which has the benefit that a hashsum error is now a proper error
for the acquire system rather than a Done() which is later revised to a
Failed().
tags/debian/1.1.exp9
David Kalnischkies 6 years ago
parent
commit
448c38bdcd
22 changed files with 2411 additions and 2458 deletions
  1. +1859
    -1891
      apt-pkg/acquire-item.cc
  2. +286
    -391
      apt-pkg/acquire-item.h
  3. +4
    -1
      apt-pkg/acquire-method.cc
  4. +111
    -78
      apt-pkg/acquire-worker.cc
  5. +10
    -0
      apt-pkg/contrib/hashes.cc
  6. +9
    -0
      apt-pkg/contrib/hashes.h
  7. +2
    -2
      apt-pkg/deb/debindexfile.cc
  8. +31
    -47
      apt-pkg/deb/debmetaindex.cc
  9. +1
    -1
      apt-pkg/indexrecords.cc
  10. +6
    -1
      apt-pkg/pkgcache.h
  11. +5
    -1
      methods/file.cc
  12. +1
    -1
      test/integration/test-apt-get-source-authenticated
  13. +27
    -28
      test/integration/test-apt-sources-deb822
  14. +1
    -1
      test/integration/test-apt-update-expected-size
  15. +4
    -0
      test/integration/test-apt-update-file
  16. +6
    -5
      test/integration/test-apt-update-nofallback
  17. +28
    -2
      test/integration/test-apt-update-not-modified
  18. +4
    -5
      test/integration/test-apt-update-stale
  19. +1
    -1
      test/integration/test-bug-595691-empty-and-broken-archive-files
  20. +8
    -0
      test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum
  21. +4
    -2
      test/libapt/acqprogress_test.cc
  22. +3
    -0
      test/libapt/hashsums_test.cc

+ 1859
- 1891
apt-pkg/acquire-item.cc
File diff suppressed because it is too large
View File


+ 286
- 391
apt-pkg/acquire-item.h
File diff suppressed because it is too large
View File


+ 4
- 1
apt-pkg/acquire-method.cc View File

@@ -376,7 +376,10 @@ int pkgAcqMethod::Run(bool Single)
Tmp->ExpectedHashes.push_back(HashString(*t, hash));
}
char *End;
Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
if (Tmp->ExpectedHashes.FileSize() > 0)
Tmp->MaximumSize = Tmp->ExpectedHashes.FileSize();
else
Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
Tmp->Next = 0;
// Append it to the list


+ 111
- 78
apt-pkg/acquire-worker.cc View File

@@ -55,8 +55,8 @@ pkgAcquire::Worker::Worker(Queue *Q,MethodConfig *Cnf,
CurrentItem = 0;
TotalSize = 0;
CurrentSize = 0;
Construct();
Construct();
}
/*}}}*/
// Worker::Worker - Constructor for method config startup /*{{{*/
@@ -70,8 +70,8 @@ pkgAcquire::Worker::Worker(MethodConfig *Cnf)
CurrentItem = 0;
TotalSize = 0;
CurrentSize = 0;
Construct();
Construct();
}
/*}}}*/
// Worker::Construct - Constructor helper /*{{{*/
@@ -136,7 +136,7 @@ bool pkgAcquire::Worker::Start()
}
for (int I = 0; I != 4; I++)
SetCloseExec(Pipes[I],true);
// Fork off the process
Process = ExecFork();
if (Process == 0)
@@ -145,9 +145,9 @@ bool pkgAcquire::Worker::Start()
dup2(Pipes[1],STDOUT_FILENO);
dup2(Pipes[2],STDIN_FILENO);
SetCloseExec(STDOUT_FILENO,false);
SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
const char *Args[2];
Args[0] = Method.c_str();
Args[1] = 0;
@@ -165,7 +165,7 @@ bool pkgAcquire::Worker::Start()
close(Pipes[2]);
OutReady = false;
InReady = true;
// Read the configuration data
if (WaitFd(InFd) == false ||
ReadMessages() == false)
@@ -174,7 +174,7 @@ bool pkgAcquire::Worker::Start()
RunMessages();
if (OwnerQ != 0)
SendConfiguration();
return true;
}
/*}}}*/
@@ -201,7 +201,7 @@ bool pkgAcquire::Worker::RunMessages()

if (Debug == true)
clog << " <- " << Access << ':' << QuoteString(Message,"\n") << endl;
// Fetch the message number
char *End;
int Number = strtol(Message.c_str(),&End,10);
@@ -215,15 +215,15 @@ bool pkgAcquire::Worker::RunMessages()

// update used mirror
string UsedMirror = LookupTag(Message,"UsedMirror", "");
if (!UsedMirror.empty() &&
if (!UsedMirror.empty() &&
Itm &&
Itm->Description.find(" ") != string::npos)
Itm->Description.find(" ") != string::npos)
{
Itm->Description.replace(0, Itm->Description.find(" "), UsedMirror);
// FIXME: will we need this as well?
//Itm->ShortDesc = UsedMirror;
}
// Determine the message number and dispatch
switch (Number)
{
@@ -232,18 +232,18 @@ bool pkgAcquire::Worker::RunMessages()
if (Capabilities(Message) == false)
return _error->Error("Unable to process Capabilities message from %s",Access.c_str());
break;
// 101 Log
case 101:
if (Debug == true)
clog << " <- (log) " << LookupTag(Message,"Message") << endl;
break;
// 102 Status
case 102:
Status = LookupTag(Message,"Message");
break;
// 103 Redirect
case 103:
{
@@ -252,7 +252,7 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 103 Redirect message");
break;
}
string NewURI = LookupTag(Message,"New-URI",URI.c_str());
Itm->URI = NewURI;

@@ -272,7 +272,7 @@ bool pkgAcquire::Worker::RunMessages()
Log->Done(Desc);
break;
}
// 200 URI Start
case 200:
{
@@ -281,23 +281,23 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 200 URI Start message");
break;
}
CurrentItem = Itm;
CurrentSize = 0;
TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
ResumePoint = strtoull(LookupTag(Message,"Resume-Point","0").c_str(), NULL, 10);
Itm->Owner->Start(Message,strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10));
Itm->Owner->Start(Message, TotalSize);

// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Itm->Owner->GetOwner());
if (Log != 0)
Log->Fetch(*Itm);

break;
}
// 201 URI Done
case 201:
{
@@ -306,7 +306,7 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 201 URI Done message");
break;
}
pkgAcquire::Item *Owner = Itm->Owner;
pkgAcquire::ItemDesc Desc = *Itm;

@@ -316,22 +316,11 @@ bool pkgAcquire::Worker::RunMessages()
// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Owner->GetOwner());
OwnerQ->ItemDone(Itm);
unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
bool isHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
// Using the https method the server might return 200, but the
// If-Modified-Since condition is not satsified, libcurl will
// discard the download. In this case, however, TotalSize will be
// set to the actual size of the file, while ServerSize will be set
// to 0. Therefore, if the item is marked as a hit and the
// downloaded size (ServerSize) is 0, we ignore TotalSize.
if (TotalSize != 0 && (!isHit || ServerSize != 0) && ServerSize != TotalSize)
_error->Warning("Size of file %s is not what the server reported %s %llu",
Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);

// see if there is a hash to verify

HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
// see if we got hashes to verify
HashStringList ReceivedHashes;
for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
{
@@ -340,6 +329,18 @@ bool pkgAcquire::Worker::RunMessages()
if (hashsum.empty() == false)
ReceivedHashes.push_back(HashString(*type, hashsum));
}
// not all methods always sent Hashes our way
if (ExpectedHashes.usable() == true && ReceivedHashes.usable() == false)
{
std::string const filename = LookupTag(Message, "Filename", Owner->DestFile.c_str());
if (filename.empty() == false && RealFileExists(filename))
{
Hashes calc(ExpectedHashes);
FileFd file(filename, FileFd::ReadOnly, FileFd::None);
calc.AddFD(file);
ReceivedHashes = calc.GetHashStringList();
}
}

if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
{
@@ -348,30 +349,66 @@ bool pkgAcquire::Worker::RunMessages()
for (HashStringList::const_iterator hs = ReceivedHashes.begin(); hs != ReceivedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << "ExpectedHash:" << endl;
HashStringList expectedHashes = Owner->HashSums();
for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs)
for (HashStringList::const_iterator hs = ExpectedHashes.begin(); hs != ExpectedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << endl;
}
Owner->Done(Message, ServerSize, ReceivedHashes, Config);
ItemDone();

// Log that we are done
if (Log != 0)
// decide if what we got is what we expected
bool consideredOkay = false;
bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
if (ExpectedHashes.usable())
{
if (isHit)
if (ReceivedHashes.usable() == false)
{
/* Hide 'hits' for local only sources - we also manage to
hide gets */
if (Config->LocalOnly == false)
Log->IMSHit(Desc);
}
/* IMS-Hits can't be checked here as we will have uncompressed file,
but the hashes for the compressed file. What we have was good through
so all we have to ensure later is that we are not stalled. */
consideredOkay = isIMSHit;
}
else if (ReceivedHashes == ExpectedHashes)
consideredOkay = true;
else
Log->Done(Desc);
consideredOkay = false;

}
else if (Owner->HashesRequired() == true)
consideredOkay = false;
else
consideredOkay = true;

if (consideredOkay == true)
{
Owner->Done(Message, ReceivedHashes, Config);
ItemDone();

// Log that we are done
if (Log != 0)
{
if (isIMSHit)
{
/* Hide 'hits' for local only sources - we also manage to
hide gets */
if (Config->LocalOnly == false)
Log->IMSHit(Desc);
}
else
Log->Done(Desc);
}
}
else
{
Owner->Status = pkgAcquire::Item::StatAuthError;
Owner->Failed(Message,Config);
ItemDone();

if (Log != 0)
Log->Fail(Desc);
}
break;
}
}
// 400 URI Failure
case 400:
{
@@ -408,18 +445,18 @@ bool pkgAcquire::Worker::RunMessages()
Log->Fail(Desc);

break;
}
}
// 401 General Failure
case 401:
_error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str());
break;
// 403 Media Change
case 403:
MediaChange(Message);
MediaChange(Message);
break;
}
}
}
return true;
}
@@ -432,7 +469,7 @@ bool pkgAcquire::Worker::Capabilities(string Message)
{
if (Config == 0)
return true;
Config->Version = LookupTag(Message,"Version");
Config->SingleInstance = StringToBool(LookupTag(Message,"Single-Instance"),false);
Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false);
@@ -447,13 +484,13 @@ bool pkgAcquire::Worker::Capabilities(string Message)
clog << "Configured access method " << Config->Access << endl;
clog << "Version:" << Config->Version <<
" SingleInstance:" << Config->SingleInstance <<
" Pipeline:" << Config->Pipeline <<
" SendConfig:" << Config->SendConfig <<
" LocalOnly: " << Config->LocalOnly <<
" NeedsCleanup: " << Config->NeedsCleanup <<
" Pipeline:" << Config->Pipeline <<
" SendConfig:" << Config->SendConfig <<
" LocalOnly: " << Config->LocalOnly <<
" NeedsCleanup: " << Config->NeedsCleanup <<
" Removable: " << Config->Removable << endl;
}
return true;
}
/*}}}*/
@@ -463,10 +500,10 @@ bool pkgAcquire::Worker::Capabilities(string Message)
bool pkgAcquire::Worker::MediaChange(string Message)
{
int status_fd = _config->FindI("APT::Status-Fd",-1);
if(status_fd > 0)
if(status_fd > 0)
{
string Media = LookupTag(Message,"Media");
string Drive = LookupTag(Message,"Drive");
string Drive = LookupTag(Message,"Drive");
ostringstream msg,status;
ioprintf(msg,_("Please insert the disc labeled: "
"'%s' "
@@ -536,12 +573,12 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
{
if (OutFd == -1)
return false;
string Message = "600 URI Acquire\n";
Message.reserve(300);
Message += "URI: " + Item->URI;
Message += "\nFilename: " + Item->Owner->DestFile;
HashStringList const hsl = Item->Owner->HashSums();
HashStringList const hsl = Item->Owner->GetExpectedHashes();
for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
if(Item->Owner->FileSize > 0)
@@ -564,7 +601,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
OutQueue += Message;
OutReady = true;
return true;
}
/*}}}*/
@@ -586,7 +623,7 @@ bool pkgAcquire::Worker::OutFdReady()
OutQueue.erase(0,Res);
if (OutQueue.empty() == true)
OutReady = false;
return true;
}
/*}}}*/
@@ -608,7 +645,7 @@ bool pkgAcquire::Worker::InFdReady()
bool pkgAcquire::Worker::MethodFailure()
{
_error->Error("Method %s has died unexpectedly!",Access.c_str());
// do not reap the child here to show meaningfull error to the user
ExecWait(Process,Access.c_str(),false);
Process = -1;
@@ -620,26 +657,22 @@ bool pkgAcquire::Worker::MethodFailure()
InReady = false;
OutQueue = string();
MessageQueue.erase(MessageQueue.begin(),MessageQueue.end());
return false;
}
/*}}}*/
// Worker::Pulse - Called periodically /*{{{*/
// Worker::Pulse - Called periodically /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcquire::Worker::Pulse()
{
if (CurrentItem == 0)
return;
struct stat Buf;
if (stat(CurrentItem->Owner->DestFile.c_str(),&Buf) != 0)
return;
CurrentSize = Buf.st_size;
// Hmm? Should not happen...
if (CurrentSize > TotalSize && TotalSize != 0)
TotalSize = CurrentSize;
}
/*}}}*/
// Worker::ItemDone - Called when the current item is finished /*{{{*/


+ 10
- 0
apt-pkg/contrib/hashes.cc View File

@@ -23,6 +23,7 @@
#include <stddef.h>
#include <algorithm>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <iostream>
/*}}}*/
@@ -178,6 +179,15 @@ HashString const * HashStringList::find(char const * const type) const /*{{{*/
return NULL;
}
/*}}}*/
unsigned long long HashStringList::FileSize() const /*{{{*/
{
HashString const * const hsf = find("Checksum-FileSize");
if (hsf == NULL)
return 0;
std::string const hv = hsf->HashValue();
return strtoull(hv.c_str(), NULL, 10);
}
/*}}}*/
bool HashStringList::supported(char const * const type) /*{{{*/
{
for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t)


+ 9
- 0
apt-pkg/contrib/hashes.h View File

@@ -87,6 +87,15 @@ class HashStringList
*/
HashString const * find(char const * const type) const;
HashString const * find(std::string const &type) const { return find(type.c_str()); }

/** finds the filesize hash and returns it as number
*
* @return beware: if the size isn't known we return \b 0 here,
* just like we would do for an empty file. If that is a problem
* for you have to get the size manually out of the list.
*/
unsigned long long FileSize() const;

/** check if the given hash type is supported
*
* @param type to check


+ 2
- 2
apt-pkg/deb/debindexfile.cc View File

@@ -742,13 +742,13 @@ bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const

// and give it to the list parser
debDebFileParser Parser(DebControl, DebFile);
if(Gen.SelectFile(DebFile, "local", *this) == false)
if(Gen.SelectFile(DebFile, "local", *this, pkgCache::Flag::LocalSource) == false)
return _error->Error("Problem with SelectFile %s", DebFile.c_str());

pkgCache::PkgFileIterator File = Gen.GetCurFile();
File->Size = DebControl->Size();
File->mtime = DebControl->ModificationTime();
if (Gen.MergeList(Parser) == false)
return _error->Error("Problem with MergeLister for %s", DebFile.c_str());



+ 31
- 47
apt-pkg/deb/debmetaindex.cc View File

@@ -192,11 +192,13 @@ vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
vector<debSectionEntry const*> const SectionEntries = src->second;
for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
I != SectionEntries.end(); ++I) {
IndexTarget * Target = new IndexTarget();
Target->ShortDesc = "Sources";
Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section);
Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
char const * const ShortDesc = "Sources";
IndexTarget * const Target = new IndexTarget(
SourceIndexURISuffix(ShortDesc, (*I)->Section),
ShortDesc,
Info(ShortDesc, (*I)->Section),
SourceIndexURI(ShortDesc, (*I)->Section)
);
IndexTargets->push_back (Target);
}
}
@@ -212,11 +214,13 @@ vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
continue;
for (vector <const debSectionEntry *>::const_iterator I = a->second.begin();
I != a->second.end(); ++I) {
IndexTarget * Target = new IndexTarget();
Target->ShortDesc = "Packages";
Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first);
Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first);
Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first);
char const * const ShortDesc = "Packages";
IndexTarget * const Target = new IndexTarget(
IndexURISuffix(ShortDesc, (*I)->Section, a->first),
ShortDesc,
Info (ShortDesc, (*I)->Section, a->first),
IndexURI(ShortDesc, (*I)->Section, a->first)
);
IndexTargets->push_back (Target);
sections.insert((*I)->Section);
}
@@ -235,11 +239,13 @@ vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
s != sections.end(); ++s) {
for (std::vector<std::string>::const_iterator l = lang.begin();
l != lang.end(); ++l) {
IndexTarget * Target = new OptionalIndexTarget();
Target->ShortDesc = "Translation-" + *l;
Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
Target->URI = TranslationIndexURI(l->c_str(), *s);
Target->Description = Info (Target->ShortDesc.c_str(), *s);
std::string const ShortDesc = "Translation-" + *l;
IndexTarget * const Target = new OptionalIndexTarget(
TranslationIndexURISuffix(l->c_str(), *s),
ShortDesc,
Info (ShortDesc.c_str(), *s),
TranslationIndexURI(l->c_str(), *s)
);
IndexTargets->push_back(Target);
}
}
@@ -249,8 +255,6 @@ vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
/*}}}*/
bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
{
bool const tryInRelease = _config->FindB("Acquire::TryInRelease", true);

indexRecords * const iR = new indexRecords(Dist);
if (Trusted == ALWAYS_TRUSTED)
iR->SetTrusted(true);
@@ -258,37 +262,17 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
iR->SetTrusted(false);

// special case for --print-uris
if (GetAll) {
vector <IndexTarget *> *targets = ComputeIndexTargets();
for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target) {
new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, HashStringList());
}
delete targets;

// this is normally created in pkgAcqMetaSig, but if we run
// in --print-uris mode, we add it here
if (tryInRelease == false)
new pkgAcqMetaIndex(Owner, NULL,
MetaIndexURI("Release"),
MetaIndexInfo("Release"), "Release",
MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
ComputeIndexTargets(),
iR);
vector <IndexTarget *> const * const targets = ComputeIndexTargets();
#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X))
pkgAcqMetaBase * const TransactionManager = new pkgAcqMetaClearSig(Owner,
APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"),
targets, iR);
#undef APT_TARGET
if (GetAll)
{
for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target)
new pkgAcqIndex(Owner, TransactionManager, *Target);
}
if (tryInRelease == true)
new pkgAcqMetaClearSig(Owner,
MetaIndexURI("InRelease"), MetaIndexInfo("InRelease"), "InRelease",
MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
ComputeIndexTargets(),
iR);
else
new pkgAcqMetaIndex(Owner, NULL,
MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
ComputeIndexTargets(),
iR);

return true;
}


+ 1
- 1
apt-pkg/indexrecords.cc View File

@@ -73,7 +73,7 @@ APT_PURE indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)

APT_PURE bool indexRecords::Exists(string const &MetaKey) const
{
return Entries.count(MetaKey) == 1;
return Entries.find(MetaKey) != Entries.end();
}

bool indexRecords::Load(const string Filename) /*{{{*/


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

@@ -190,7 +190,12 @@ class pkgCache /*{{{*/
struct Flag
{
enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)};
enum PkgFFlags {NotSource=(1<<0),NotAutomatic=(1<<1),ButAutomaticUpgrades=(1<<2)};
enum PkgFFlags {
NotSource=(1<<0), /*!< packages can't be fetched from here, e.g. dpkg/status file */
NotAutomatic=(1<<1), /*!< archive has a default pin of 1 */
ButAutomaticUpgrades=(1<<2), /*!< (together with the previous) archive has a default pin of 100 */
LocalSource=(1<<3), /*!< local sources can't and will not be verified by hashes */
};
};
protected:


+ 5
- 1
methods/file.cc View File

@@ -57,7 +57,11 @@ bool FileMethod::Fetch(FetchItem *Itm)
Res.LastModified = Buf.st_mtime;
Res.IMSHit = false;
if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
Res.IMSHit = true;
{
unsigned long long const filesize = Itm->ExpectedHashes.FileSize();
if (filesize != 0 && filesize == Res.Size)
Res.IMSHit = true;
}
}

// See if the uncompressed file exists and reuse it


+ 1
- 1
test/integration/test-apt-get-source-authenticated View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# Regression test for debian bug #749795. Ensure that we fail with
# a error if apt-get source foo will download a source that comes
# an error if apt-get source foo will download a source that comes
# from a unauthenticated repository
#
set -e


+ 27
- 28
test/integration/test-apt-sources-deb822 View File

@@ -23,46 +23,45 @@ Description: summay

msgtest 'Test sources.list' 'old style'
echo "deb http://ftp.debian.org/debian stable main" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 " aptget update --print-uris
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test sources.list' 'simple deb822'
echo "$BASE" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 " aptget update --print-uris

testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test deb822 with' 'two entries'
# Two entries
echo "$BASE" > $SOURCES
echo "" >> $SOURCES
echo "$BASE" | sed s/stable/unstable/ >> $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/unstable/InRelease' ftp.debian.org_debian_dists_unstable_InRelease 0
'http://ftp.debian.org/debian/dists/unstable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_unstable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/unstable/InRelease' ftp.debian.org_debian_dists_unstable_InRelease 0 " aptget update --print-uris
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris

# two suite entries
msgtest 'Test deb822 with' 'two Suite entries'
echo "$BASE" | sed -e "s/stable/stable unstable/" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/unstable/InRelease' ftp.debian.org_debian_dists_unstable_InRelease 0
'http://ftp.debian.org/debian/dists/unstable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_unstable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/unstable/InRelease' ftp.debian.org_debian_dists_unstable_InRelease 0 " aptget update --print-uris
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test deb822' 'architecture option'
echo "$BASE" > $SOURCES
echo "Architectures: amd64 armel" >> $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/binary-amd64/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-amd64_Packages 0
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-amd64/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-amd64_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 " aptget update --print-uris
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris


msgtest 'Test old-style sources.list file which has' 'malformed dist'
@@ -85,20 +84,20 @@ testempty aptget update --print-uris
# multiple URIs
msgtest 'Test deb822 sources.list file which has' 'Multiple URIs work'
echo "$BASE" | sed -e 's#http://ftp.debian.org/debian#http://ftp.debian.org/debian http://ftp.de.debian.org/debian#' > $SOURCES
testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.de.debian.org_debian_dists_stable_main_binary-i386_Packages 0
testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp.de.debian.org_debian_dists_stable_InRelease 0
'http://ftp.de.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.de.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.de.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.de.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp.de.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 " aptget update --print-uris
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

# multiple Type in one field
msgtest 'Test deb822 sources.list file which has' 'Multiple Types work'
echo "$BASE" | sed -e 's#Types: deb#Types: deb deb-src#' > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/main/source/Sources.bz2' ftp.debian.org_debian_dists_stable_main_source_Sources 0
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/source/Sources.bz2' ftp.debian.org_debian_dists_stable_main_source_Sources 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0
'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 " aptget update --print-uris
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

# a Suite
msgtest 'Test deb822 sources.list file which has' 'a exact path and no sections'
@@ -107,6 +106,6 @@ Types: deb
URIs: http://emacs.naquadah.org
Suites: stable/
EOF
testequal --nomsg "'http://emacs.naquadah.org/stable/Packages.bz2' emacs.naquadah.org_stable_Packages 0
'http://emacs.naquadah.org/stable/en.bz2' emacs.naquadah.org_stable_en 0
'http://emacs.naquadah.org/stable/InRelease' emacs.naquadah.org_stable_InRelease 0 " aptget update --print-uris
testequal --nomsg "'http://emacs.naquadah.org/stable/InRelease' emacs.naquadah.org_stable_InRelease 0
'http://emacs.naquadah.org/stable/Packages.bz2' emacs.naquadah.org_stable_Packages 0
'http://emacs.naquadah.org/stable/en.bz2' emacs.naquadah.org_stable_en 0 " aptget update --print-uris

+ 1
- 1
test/integration/test-apt-update-expected-size View File

@@ -35,7 +35,7 @@ test_packagestoobig() {
done
NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)"
testfailuremsg "W: Failed to fetch ${1}/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE)
E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::Transaction=0
E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::Transaction=0
}

methodtest() {


+ 4
- 0
test/integration/test-apt-update-file View File

@@ -22,6 +22,10 @@ addtrap 'prefix' 'chmod 750 aptarchive/dists/unstable/main/binary-amd64;'
chmod 550 aptarchive/dists/unstable/main/binary-amd64

testsuccess aptget update

# the release files aren't an IMS-hit, but the indexes are
redatereleasefiles '+1 hour'

testsuccess aptget update -o Debug::pkgAcquire::Auth=1
cp -a rootdir/tmp/testsuccess.output rootdir/tmp/update.output



+ 6
- 5
test/integration/test-apt-update-nofallback View File

@@ -28,6 +28,7 @@ Description: an autogenerated evil package
EOF
# avoid ims hit
touch -d '+1hour' aptarchive/dists/unstable/main/binary-i386/Packages
compressfile aptarchive/dists/unstable/main/binary-i386/Packages
}

assert_update_is_refused_and_last_good_state_used()
@@ -87,16 +88,16 @@ test_from_inrelease_to_unsigned_with_override()
{
# setup archive with InRelease file
setupaptarchive_with_lists_clean
# FIXME: is not what the server reported 4104 4106
testsuccess aptget update #-o Debug::pkgAcquire::Worker=1
testsuccess aptget update

# simulate moving to a unsigned but otherwise valid repo
simulate_mitm_and_inject_evil_package
generatereleasefiles
generatereleasefiles '+2 hours'
find $APTARCHIVE -name '*Packages*' -exec touch -d '+2 hours' {} \;

# and ensure we can update to it (with enough force)
testwarning aptget update --allow-insecure-repositories \
-o Acquire::AllowDowngradeToInsecureRepositories=1
-o Acquire::AllowDowngradeToInsecureRepositories=1 -o Debug::pkgAcquire::Worker=1 -o Debug::pkgAcquire::Auth=1
# but that the individual packages are still considered untrusted
testfailureequal "WARNING: The following packages cannot be authenticated!
evil
@@ -167,7 +168,7 @@ test_inrelease_to_invalid_inrelease()
listcurrentlistsdirectory > lists.before

# now remove InRelease and subvert Release do no longer verify
sed -i 's/Codename.*/Codename: evil!'/ $APTARCHIVE/dists/unstable/InRelease
sed -i 's/^Codename:.*/Codename: evil!/' $APTARCHIVE/dists/unstable/InRelease
inject_evil_package

testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>


+ 28
- 2
test/integration/test-apt-update-not-modified View File

@@ -43,7 +43,9 @@ Version: 1
EOF
compressfile aptarchive/dists/unstable/main/binary-amd64/Packages
testfailureequal "Hit $1 unstable InRelease
Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists.good/unstable/main/binary-amd64/Packages.gz') B]
Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B]
Err $1 unstable/main amd64 Packages
Hash Sum mismatch
W: Failed to fetch $1/dists/unstable/main/binary-amd64/Packages.gz Hash Sum mismatch

E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update
@@ -87,8 +89,32 @@ Hit $1 unstable Release
Reading package lists..." aptget update
testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)"

# readd arch so its downloaded again
# readd arch so its downloaded again
configarchitecture 'amd64' 'i386'
# … but oh noes, hashsum mismatch!
find aptarchive/dists/unstable/main/binary-amd64/ -type f -delete
cat >> aptarchive/dists/unstable/main/binary-amd64/Packages <<EOF

Package: thisisbad
Architecture: amd64
Version: 1
EOF
compressfile aptarchive/dists/unstable/main/binary-amd64/Packages
testfailureequal "Ign $1 unstable InRelease
404 Not Found
Hit $1 unstable Release
Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B]
Err $1 unstable/main amd64 Packages
Hash Sum mismatch
W: Failed to fetch $1/dists/unstable/main/binary-amd64/Packages.gz Hash Sum mismatch

E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update
testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)"
rm -rf aptarchive/dists
cp -a aptarchive/dists.good aptarchive/dists
find aptarchive/dists -name 'InRelease' -delete

# … now everything is fine again
testsuccessequal "Ign $1 unstable InRelease
404 Not Found
Hit $1 unstable Release


+ 4
- 5
test/integration/test-apt-update-stale View File

@@ -18,7 +18,7 @@ setupaptarchive --no-update
changetowebserver

echo "Acquire::Languages \"none\";" > rootdir/etc/apt/apt.conf.d/00nolanguages
testsuccess aptget update
testsuccess aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::http=1
listcurrentlistsdirectory > lists.before

# insert new version
@@ -26,7 +26,7 @@ mkdir aptarchive/dists/unstable/main/binary-i386/saved
cp -p aptarchive/dists/unstable/main/binary-i386/Packages* \
aptarchive/dists/unstable/main/binary-i386/saved
insertpackage 'unstable' 'foo' 'all' '2.0'
touch -d '+1 hour' aptarchive/dists/unstable/main/binary-i386/Packages
compressfile aptarchive/dists/unstable/main/binary-i386/Packages
# ensure that we do not get a I-M-S hit for the Release file

@@ -39,7 +39,6 @@ cp -p aptarchive/dists/unstable/main/binary-i386/saved/Packages* \
aptarchive/dists/unstable/main/binary-i386/

# ensure this raises an error
testfailureequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Hash Sum mismatch

E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
testfailuremsg "W: Failed to fetch copy:$(readlink -f ./rootdir)/var/lib/apt/lists/localhost:8080_dists_unstable_main_binary-i386_Packages Hash Sum mismatch
E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::http=1
testfileequal lists.before "$(listcurrentlistsdirectory)"

+ 1
- 1
test/integration/test-bug-595691-empty-and-broken-archive-files View File

@@ -12,7 +12,7 @@ setupflataptarchive

testaptgetupdate() {
rm -rf rootdir/var/lib/apt
aptget update 2>> testaptgetupdate.diff >> testaptgetupdate.diff || true
aptget update >testaptgetupdate.diff 2>&1 || true
sed -i -e '/Ign /,+1d' -e '/Release/ d' -e 's#Get:[0-9]\+ #Get: #' -e 's#\[[0-9]* [kMGTPY]*B\]#\[\]#' testaptgetupdate.diff
GIVEN="$1"
shift


+ 8
- 0
test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum View File

@@ -176,7 +176,11 @@ testmismatch() {
Building dependency tree...
Need to get 6 B of source archives.
Get:1 http://localhost:8080/ $1 1.0 (dsc) [3 B]
Err http://localhost:8080/ $1 1.0 (dsc)
Hash Sum mismatch
Get:2 http://localhost:8080/ $1 1.0 (tar) [3 B]
Err http://localhost:8080/ $1 1.0 (tar)
Hash Sum mismatch
E: Failed to fetch http://localhost:8080/${1}_1.0.dsc Hash Sum mismatch

E: Failed to fetch http://localhost:8080/${1}_1.0.tar.gz Hash Sum mismatch
@@ -238,6 +242,8 @@ Building dependency tree...
Need to get 6 B of source archives.
Get:1 http://localhost:8080/ pkg-mixed-sha1-bad 1.0 (tar) [3 B]
Get:2 http://localhost:8080/ pkg-mixed-sha1-bad 1.0 (dsc) [3 B]
Err http://localhost:8080/ pkg-mixed-sha1-bad 1.0 (dsc)
Hash Sum mismatch
E: Failed to fetch http://localhost:8080/pkg-mixed-sha1-bad_1.0.dsc Hash Sum mismatch

E: Failed to fetch some archives.' aptget source -d pkg-mixed-sha1-bad
@@ -247,6 +253,8 @@ testfailureequal 'Reading package lists...
Building dependency tree...
Need to get 6 B of source archives.
Get:1 http://localhost:8080/ pkg-mixed-sha2-bad 1.0 (tar) [3 B]
Err http://localhost:8080/ pkg-mixed-sha2-bad 1.0 (tar)
Hash Sum mismatch
Get:2 http://localhost:8080/ pkg-mixed-sha2-bad 1.0 (dsc) [3 B]
E: Failed to fetch http://localhost:8080/pkg-mixed-sha2-bad_1.0.tar.gz Hash Sum mismatch



+ 4
- 2
test/libapt/acqprogress_test.cc View File

@@ -1,4 +1,5 @@
#include <config.h>
#include <apt-pkg/hashes.h>
#include <apt-pkg/acquire.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/configuration.h>
@@ -10,9 +11,10 @@
class TestItem: public pkgAcquire::Item
{
public:
TestItem(pkgAcquire * const Acq) : pkgAcquire::Item(Acq, "", NULL) {}
TestItem(pkgAcquire * const Acq) : pkgAcquire::Item(Acq) {}

virtual std::string DescURI() { return ""; }
virtual std::string DescURI() const { return ""; }
virtual HashStringList GetExpectedHashes() const { return HashStringList(); }

};



+ 3
- 0
test/libapt/hashsums_test.cc View File

@@ -306,6 +306,7 @@ TEST(HashSumsTest, HashStringList)
EXPECT_EQ(NULL, list.find(NULL));
EXPECT_EQ(NULL, list.find(""));
EXPECT_EQ(NULL, list.find("MD5Sum"));
EXPECT_EQ(0, list.FileSize());

// empty lists aren't equal
HashStringList list2;
@@ -316,6 +317,8 @@ TEST(HashSumsTest, HashStringList)
list.push_back(HashString("Checksum-FileSize", "29"));
EXPECT_FALSE(list.empty());
EXPECT_FALSE(list.usable());
EXPECT_EQ(1, list.size());
EXPECT_EQ(29, list.FileSize());

Hashes hashes;
hashes.Add("The quick brown fox jumps over the lazy dog");


Loading…
Cancel
Save