Fix a segfault in the version merger introduced in the previous patch:
[apt.git] / apt-pkg / deb / deblistparser.cc
index 6e78ed42b80b71950d7fe0bdd7c6683f5ccb89fc..66108d8220e96be3c0c76d9bc16baf217135b1bf 100644 (file)
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/crc-16.h>
 #include <apt-pkg/md5.h>
+#include <apt-pkg/macros.h>
 
 #include <ctype.h>
-
-#include <system.h>
                                                                        /*}}}*/
 
 static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
@@ -105,8 +105,12 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
       return false;
    if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
       return false;
+   if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false)
+      return false;
    if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
       return false;
+   if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
+      return false;
 
    // Obsolete.
    if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
@@ -125,10 +129,11 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
    only describe package properties */
 string debListParser::Description()
 {
-   if (DescriptionLanguage().empty())
+   string const lang = DescriptionLanguage();
+   if (lang.empty())
       return Section.FindS("Description");
    else
-      return Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str());
+      return Section.FindS(string("Description-").append(lang).c_str());
 }
                                                                         /*}}}*/
 // ListParser::DescriptionLanguage - Return the description lang string        /*{{{*/
@@ -138,19 +143,30 @@ string debListParser::Description()
    assumed to describe original description. */
 string debListParser::DescriptionLanguage()
 {
-   return Section.FindS("Description").empty() ? pkgIndexFile::LanguageCode() : "";
+   if (Section.FindS("Description").empty() == false)
+      return "";
+
+   std::vector<string> const lang = APT::Configuration::getLanguages();
+   for (std::vector<string>::const_iterator l = lang.begin();
+       l != lang.end(); l++)
+      if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false)
+        return *l;
+
+   return "";
 }
                                                                         /*}}}*/
 // ListParser::Description - Return the description_md5 MD5SumValue    /*{{{*/
 // ---------------------------------------------------------------------
-/* This is to return the md5 string to allow the check if is the right
-   description. If thisreturns a blank string then calculate the md5
-   value. */
+/* This is to return the md5 string to allow the check if it is the right
+   description. If no Description-md5 is found in the section it will be
+   calculated.
+ */
 MD5SumValue debListParser::Description_md5()
 {
    string value = Section.FindS("Description-md5");
 
-   if (value.empty()) {
+   if (value.empty()) 
+   {
       MD5Summation md5;
       md5.Add((Description() + "\n").c_str());
       return md5.Result();
@@ -191,6 +207,7 @@ unsigned short debListParser::VersionHash()
 //                            "Suggests",
 //                            "Recommends",
                             "Conflicts",
+                            "Breaks",
                             "Replaces",0};
    unsigned long Result = INIT_FCS;
    char S[1024];
@@ -208,7 +225,7 @@ unsigned short debListParser::VersionHash()
       for (; Start != End; Start++)
       {
         if (isspace(*Start) == 0)
-           *I++ = tolower(*Start);
+           *I++ = tolower_ascii(*Start);
         if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
            *I++ = '=';
         if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
@@ -288,6 +305,8 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
                             {"installed",pkgCache::State::Installed},
                             {"half-installed",pkgCache::State::HalfInstalled},
                             {"config-files",pkgCache::State::ConfigFiles},
+                            {"triggers-awaited",pkgCache::State::TriggersAwaited},
+                            {"triggers-pending",pkgCache::State::TriggersPending},
                             {"post-inst-failed",pkgCache::State::HalfConfigured},
                             {"removal-failed",pkgCache::State::HalfInstalled},
                             {}};
@@ -375,7 +394,8 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
    bit by bit. */
 const char *debListParser::ParseDepends(const char *Start,const char *Stop,
                                        string &Package,string &Ver,
-                                       unsigned int &Op, bool ParseArchFlags)
+                                       unsigned int &Op, bool const &ParseArchFlags,
+                                       bool const &StripMultiArch)
 {
    // Strip off leading space
    for (;Start != Stop && isspace(*Start) != 0; Start++);
@@ -394,7 +414,14 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
    
    // Stash the package name
    Package.assign(Start,I - Start);
-   
+
+   // We don't want to confuse library users which can't handle MultiArch
+   if (StripMultiArch == true) {
+      size_t const found = Package.rfind(':');
+      if (found != string::npos)
+        Package = Package.substr(0,found);
+   }
+
    // Skip white space to the '('
    for (;I != Stop && isspace(*I) != 0 ; I++);
    
@@ -418,12 +445,12 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
       const char *End = I;
       for (; End > Start && isspace(End[-1]); End--);
       
-      Ver = string(Start,End-Start);
+      Ver.assign(Start,End-Start);
       I++;
    }
    else
    {
-      Ver = string();
+      Ver.clear();
       Op = pkgCache::Dep::NoOp;
    }
    
@@ -545,11 +572,12 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
       Start = ParseDepends(Start,Stop,Package,Version,Op);
       if (Start == 0)
         return _error->Error("Problem parsing Provides line");
-      if (Op != pkgCache::Dep::NoOp)
-        return _error->Error("Malformed provides line");
-
-      if (NewProvides(Ver,Package,Version) == false)
-        return false;
+      if (Op != pkgCache::Dep::NoOp) {
+        _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
+      } else {
+        if (NewProvides(Ver,Package,Version) == false)
+           return false;
+      }
 
       if (Start == Stop)
         break;
@@ -605,13 +633,20 @@ bool debListParser::Step()
 // ---------------------------------------------------------------------
 /* */
 bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
-                                   FileFd &File)
+                                   FileFd &File, string component)
 {
    pkgTagFile Tags(&File, File.Size() + 256); // XXX
    pkgTagSection Section;
    if (Tags.Step(Section) == false)
       return false;
 
+   //mvo: I don't think we need to fill that in (it's unused since apt-0.6)
+   //FileI->Architecture = WriteUniqString(Arch);
+   
+   // apt-secure does no longer download individual (per-section) Release
+   // file. to provide Component pinning we use the section name now
+   FileI->Component = WriteUniqString(component);
+
    const char *Start;
    const char *Stop;
    if (Section.Find("Suite",Start,Stop) == true)
@@ -622,6 +657,8 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
       FileI->Version = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Origin",Start,Stop) == true)
       FileI->Origin = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Codename",Start,Stop) == true)
+      FileI->Codename = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Label",Start,Stop) == true)
       FileI->Label = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Architecture",Start,Stop) == true)
@@ -630,7 +667,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
    if (Section.FindFlag("NotAutomatic",FileI->Flags,
                        pkgCache::Flag::NotAutomatic) == false)
       _error->Warning("Bad NotAutomatic flag");
-   
+
    return !_error->PendingError();
 }
                                                                        /*}}}*/