fix crash when P.Arch() was used but the cache got remapped
[ntk/apt.git] / apt-pkg / acquire-item.cc
index 1d651ba..df83d14 100644 (file)
@@ -94,7 +94,7 @@ void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 // ---------------------------------------------------------------------
 /* Stash status and the file size. Note that setting Complete means 
    sub-phases of the acquire process such as decompresion are operating */
-void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
+void pkgAcquire::Item::Start(string /*Message*/,unsigned long long Size)
 {
    Status = StatFetching;
    if (FileSize == 0 && Complete == false)
@@ -104,7 +104,7 @@ void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
 // Acquire::Item::Done - Item downloaded OK                            /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcquire::Item::Done(string Message,unsigned long Size,string Hash,
+void pkgAcquire::Item::Done(string Message,unsigned long long Size,string Hash,
                            pkgAcquire::MethodConfig *Cnf)
 {
    // We just downloaded something..
@@ -245,7 +245,7 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)   /*{{{*
    }
 }
                                                                        /*}}}*/
-void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash,    /*{{{*/
+void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash,       /*{{{*/
                           pkgAcquire::MethodConfig *Cnf)
 {
    if(Debug)
@@ -271,6 +271,14 @@ void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash,        /*{{
 
    string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
 
+   /* Downloaded invalid transindex => Error (LP: #346386) (Closes: #627642) */
+   indexRecords SubIndexParser;
+   if (FileExists(DestFile) == true && !SubIndexParser.Load(DestFile)) {
+      Status = StatError;
+      ErrorText = SubIndexParser.ErrorText;
+      return;
+   }
+
    // sucess in downloading the index
    // rename the index
    if(Debug)
@@ -536,7 +544,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)  /*{{{
    Dequeue();
 }
                                                                        /*}}}*/
-void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,   /*{{{*/
+void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,string Md5Hash,      /*{{{*/
                           pkgAcquire::MethodConfig *Cnf)
 {
    if(Debug)
@@ -702,7 +710,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff()                                      /*{{{*/
    return true;
 }
                                                                        /*}}}*/
-void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,  /*{{{*/
+void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Hash,     /*{{{*/
                            pkgAcquire::MethodConfig *Cnf)
 {
    if(Debug)
@@ -873,7 +881,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)      /*{{{*/
    to the uncompressed version of the file. If this is so the file
    is copied into the partial directory. In all other cases the file
    is decompressed with a gzip uri. */
-void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
+void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash,
                       pkgAcquire::MethodConfig *Cfg)
 {
    Item::Done(Message,Size,Hash,Cfg);
@@ -894,6 +902,30 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
         ReportMirrorFailure("HashChecksumFailure");
          return;
       }
+
+      /* Verify the index file for correctness (all indexes must
+       * have a Package field) (LP: #346386) (Closes: #627642) */
+      {
+        FileFd fd(DestFile, FileFd::ReadOnly);
+        pkgTagSection sec;
+        pkgTagFile tag(&fd);
+
+         // Only test for correctness if the file is not empty (empty is ok)
+         if (fd.Size() > 0) {
+            if (_error->PendingError() || !tag.Step(sec)) {
+               Status = StatError;
+               _error->DumpErrors();
+               Rename(DestFile,DestFile + ".FAILED");
+               return;
+            } else if (!sec.Exists("Package")) {
+               Status = StatError;
+               ErrorText = ("Encountered a section with no Package: header");
+               Rename(DestFile,DestFile + ".FAILED");
+               return;
+            }
+         }
+      }
+       
       // Done, move it into position
       string FinalFile = _config->FindDir("Dir::State::lists");
       FinalFile += URItoFileName(RealURI);
@@ -1091,7 +1123,7 @@ string pkgAcqMetaSig::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 
-void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqMetaSig::Done(string Message,unsigned long long Size,string MD5,
                         pkgAcquire::MethodConfig *Cfg)
 {
    Item::Done(Message,Size,MD5,Cfg);
@@ -1200,7 +1232,7 @@ string pkgAcqMetaIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
                                                                        /*}}}*/
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,      /*{{{*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,string Hash, /*{{{*/
                           pkgAcquire::MethodConfig *Cfg)
 {
    Item::Done(Message,Size,Hash,Cfg);
@@ -1330,6 +1362,16 @@ void pkgAcqMetaIndex::AuthDone(string Message)                           /*{{{*/
                                                                        /*}}}*/
 void pkgAcqMetaIndex::QueueIndexes(bool verify)                                /*{{{*/
 {
+#if 0
+   /* Reject invalid, existing Release files (LP: #346386) (Closes: #627642)
+    * FIXME: Disabled; it breaks unsigned repositories without hashes */
+   if (!verify && FileExists(DestFile) && !MetaIndexParser->Load(DestFile))
+   {
+      Status = StatError;
+      ErrorText = MetaIndexParser->ErrorText;
+      return;
+   }
+#endif
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         Target++)
@@ -1431,8 +1473,10 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)                       /*{{{*/
         // TRANSLATOR: The first %s is the URL of the bad Release file, the second is
         // the time since then the file is invalid - formated in the same way as in
         // the download progress display (e.g. 7d 3h 42min 1s)
-        return _error->Error(_("Release file expired, ignoring %s (invalid since %s)"),
-                             RealURI.c_str(), TimeToStr(invalid_since).c_str());
+        return _error->Error(
+            _("Release file for %s is expired (invalid since %s). "
+              "Updates for this repository will not be applied."),
+            RealURI.c_str(), TimeToStr(invalid_since).c_str());
    }
 
    if (_config->FindB("Debug::pkgAcquire::Auth", false)) 
@@ -1493,6 +1537,12 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
                         LookupTag(Message,"Message").c_str());
         RunScripts("APT::Update::Auth-Failure");
         return;
+      } else if (LookupTag(Message,"Message").find("NODATA") != string::npos) {
+        /* Invalid signature file, reject (LP: #346386) (Closes: #627642) */
+        _error->Error(_("GPG error: %s: %s"),
+                        Desc.Description.c_str(),
+                        LookupTag(Message,"Message").c_str());
+        return;
       } else {
         _error->Warning(_("GPG error: %s: %s"),
                         Desc.Description.c_str(),
@@ -1504,7 +1554,7 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 
    /* Always move the meta index, even if gpgv failed. This ensures
     * that PackageFile objects are correctly filled in */
-   {
+   if (FileExists(DestFile)) {
       string FinalFile = _config->FindDir("Dir::State::lists");
       FinalFile += URItoFileName(RealURI);
       /* InRelease files become Release files, otherwise
@@ -1645,7 +1695,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
 
    // Select a source
    if (QueueNext() == false && _error->PendingError() == false)
-      _error->Error(_("I wasn't able to locate file for the %s package. "
+      _error->Error(_("I wasn't able to locate file for the %s package. "
                    "This might mean you need to manually fix this package."),
                    Version.ParentPkg().Name());
 }
@@ -1682,6 +1732,8 @@ bool pkgAcqArchive::QueueNext()
       string PkgFile = Parse.FileName();
       if (ForceHash.empty() == false)
       {
+        if(stringcasecmp(ForceHash, "sha512") == 0)
+           ExpectedHash = HashString("SHA512", Parse.SHA512Hash());
         if(stringcasecmp(ForceHash, "sha256") == 0)
            ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
         else if (stringcasecmp(ForceHash, "sha1") == 0)
@@ -1692,7 +1744,9 @@ bool pkgAcqArchive::QueueNext()
       else
       {
         string Hash;
-        if ((Hash = Parse.SHA256Hash()).empty() == false)
+        if ((Hash = Parse.SHA512Hash()).empty() == false)
+           ExpectedHash = HashString("SHA512", Hash);
+        else if ((Hash = Parse.SHA256Hash()).empty() == false)
            ExpectedHash = HashString("SHA256", Hash);
         else if ((Hash = Parse.SHA1Hash()).empty() == false)
            ExpectedHash = HashString("SHA1", Hash);
@@ -1716,7 +1770,7 @@ bool pkgAcqArchive::QueueNext()
       if (stat(FinalFile.c_str(),&Buf) == 0)
       {
         // Make sure the size matches
-        if ((unsigned)Buf.st_size == Version->Size)
+        if ((unsigned long long)Buf.st_size == Version->Size)
         {
            Complete = true;
            Local = true;
@@ -1735,7 +1789,7 @@ bool pkgAcqArchive::QueueNext()
       if (stat(FinalFile.c_str(),&Buf) == 0)
       {
         // Make sure the size matches
-        if ((unsigned)Buf.st_size == Version->Size)
+        if ((unsigned long long)Buf.st_size == Version->Size)
         {
            Complete = true;
            Local = true;
@@ -1755,7 +1809,7 @@ bool pkgAcqArchive::QueueNext()
       if (stat(DestFile.c_str(),&Buf) == 0)
       {
         // Hmm, the partial file is too big, erase it
-        if ((unsigned)Buf.st_size > Version->Size)
+        if ((unsigned long long)Buf.st_size > Version->Size)
            unlink(DestFile.c_str());
         else
            PartialSize = Buf.st_size;
@@ -1778,7 +1832,7 @@ bool pkgAcqArchive::QueueNext()
 // AcqArchive::Done - Finished fetching                                        /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqArchive::Done(string Message,unsigned long Size,string CalcHash,
+void pkgAcqArchive::Done(string Message,unsigned long long Size,string CalcHash,
                         pkgAcquire::MethodConfig *Cfg)
 {
    Item::Done(Message,Size,CalcHash,Cfg);
@@ -1889,7 +1943,7 @@ void pkgAcqArchive::Finished()
 // ---------------------------------------------------------------------
 /* The file is added to the queue */
 pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
-                      unsigned long Size,string Dsc,string ShortDesc,
+                      unsigned long long Size,string Dsc,string ShortDesc,
                       const string &DestDir, const string &DestFilename,
                        bool IsIndexFile) :
                        Item(Owner), ExpectedHash(Hash), IsIndexFile(IsIndexFile)
@@ -1917,7 +1971,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
    if (stat(DestFile.c_str(),&Buf) == 0)
    {
       // Hmm, the partial file is too big, erase it
-      if ((unsigned)Buf.st_size > Size)
+      if ((unsigned long long)Buf.st_size > Size)
         unlink(DestFile.c_str());
       else
         PartialSize = Buf.st_size;
@@ -1929,7 +1983,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
 // AcqFile::Done - Item downloaded OK                                  /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash,
+void pkgAcqFile::Done(string Message,unsigned long long Size,string CalcHash,
                      pkgAcquire::MethodConfig *Cnf)
 {
    Item::Done(Message,Size,CalcHash,Cnf);
@@ -2017,13 +2071,3 @@ string pkgAcqFile::Custom600Headers()
    return "";
 }
                                                                        /*}}}*/
-bool IndexTarget::IsOptional() const {
-   if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0)
-      return false;
-   return true;
-}
-bool IndexTarget::IsSubIndex() const {
-   if (ShortDesc != "TranslationIndex")
-      return false;
-   return true;
-}