]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/deblistparser.cc
On IMS-Hit, you can't assume local compression :/.
[apt.git] / apt-pkg / deb / deblistparser.cc
index 43fc4aa3a949e3f30edafd954ffc9cda87562270..25d8e6f22493578b6ed14166989424c54272e671 100644 (file)
@@ -148,6 +148,15 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
    const char *Start;
    const char *Stop;
 
+   if (Section.Find("Name",Start,Stop) == true)
+   {
+      Ver->Display = WriteString(Start, Stop - Start);
+   }
+   else if (Section.Find("Maemo-Display-Name",Start,Stop) == true)
+   {
+      Ver->Display = WriteString(Start, Stop - Start);
+   }
+
    // Parse the section
    if (Section.Find(pkgTagSection::Key::Section,Start,Stop) == true)
    {
@@ -244,6 +253,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
    
    if (ParseProvides(Ver) == false)
       return false;
+   if (ParseTag(Ver) == false)
+      return false;
    
    return true;
 }
@@ -254,18 +265,17 @@ std::vector<std::string> debListParser::AvailableDescriptionLanguages()
    std::vector<std::string> const understood = APT::Configuration::getLanguages();
    std::vector<std::string> avail;
    static constexpr int prefixLen = 12;
-   static constexpr int avgLanguageLen = 5;
-   std::string tagname;
-
-   tagname.reserve(prefixLen + avgLanguageLen);
-   tagname.assign("Description-");
+   char buf[32] = "Description-";
    if (Section.Exists("Description") == true)
       avail.push_back("");
    for (std::vector<std::string>::const_iterator lang = understood.begin(); lang != understood.end(); ++lang)
    {
-      tagname.resize(prefixLen);
-      tagname.append(*lang);
-      if (Section.Exists(tagname) == true)
+      if (unlikely(lang->size() > sizeof(buf) - prefixLen)) {
+        _error->Warning("Ignoring translated description %s", lang->c_str());
+        continue;
+      }
+      memcpy(buf + prefixLen, lang->c_str(), lang->size());
+      if (Section.Exists(StringView(buf, prefixLen + lang->size())) == true)
         avail.push_back(*lang);
    }
    return avail;
@@ -277,31 +287,27 @@ std::vector<std::string> debListParser::AvailableDescriptionLanguages()
    description. If no Description-md5 is found in the section it will be
    calculated.
  */
-MD5SumValue debListParser::Description_md5()
+APT::StringView debListParser::Description_md5()
 {
    StringView const value = Section.Find(pkgTagSection::Key::Description_md5);
-   if (value.empty() == true)
+   if (unlikely(value.empty() == true))
    {
       StringView const desc = Section.Find(pkgTagSection::Key::Description);
       if (desc == "\n")
-        return MD5SumValue();
+        return StringView();
 
       MD5Summation md5;
       md5.Add(desc.data(), desc.size());
       md5.Add("\n");
-      return md5.Result();
+      MD5Buffer = md5.Result();
+      return StringView(MD5Buffer);
    }
    else if (likely(value.size() == 32))
    {
-      MD5SumValue sumvalue;
-      if (sumvalue.Set(value))
-        return sumvalue;
-
-      _error->Error("Malformed Description-md5 line; includes invalid character '%.*s'", (int)value.length(), value.data());
-      return MD5SumValue();
+      return value;
    }
    _error->Error("Malformed Description-md5 line; doesn't have the required length (32 != %d) '%.*s'", (int)value.size(), (int)value.length(), value.data());
-   return MD5SumValue();
+   return StringView();
 }
                                                                         /*}}}*/
 // ListParser::UsePackage - Update a package structure                 /*{{{*/
@@ -353,7 +359,6 @@ unsigned short debListParser::VersionHash()
       pkgTagSection::Key::Breaks,
       pkgTagSection::Key::Replaces};
    unsigned long Result = INIT_FCS;
-   char S[1024];
    for (auto I : Sections)
    {
       const char *Start;
@@ -363,23 +368,16 @@ unsigned short debListParser::VersionHash()
       
       /* Strip out any spaces from the text, this undoes dpkgs reformatting
          of certain fields. dpkg also has the rather interesting notion of
-         reformatting depends operators < -> <= */
-      char *J = S;
-      for (; Start != End && (J - S) < sizeof(S); ++Start)
+         reformatting depends operators < -> <=, so we drop all = from the
+        string to make that not matter. */
+      for (; Start != End; ++Start)
       {
-        if (isspace_ascii(*Start) != 0)
+        if (isspace_ascii(*Start) != 0 || *Start == '=')
            continue;
-        *J++ = tolower_ascii(*Start);
-
-        /* Normalize <= to < and >= to >. This is the wrong way around, but
-         * more efficient that the right way. And since we're only hashing
-         * it does not matter which way we normalize. */
-        if ((*Start == '<' || *Start == '>') && Start[1] == '=') {
-           Start++;
-        }
+        Result = AddCRC16Byte(Result, tolower_ascii_unsafe(*Start));
       }
 
-      Result = AddCRC16(Result,S,J - S);
+
    }
    
    return Result;
@@ -827,7 +825,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
 
       Start = ParseDepends(Start, Stop, Package, Version, Op, false, false, false);
       if (Start == 0)
-        return _error->Error("Problem parsing dependency %zu",static_cast<size_t>(Key)); // TODO
+        return _error->Warning("Problem parsing dependency %zu",static_cast<size_t>(Key)); // TODO
       size_t const found = Package.rfind(':');
 
       if (found == string::npos)
@@ -895,7 +893,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
         Start = ParseDepends(Start,Stop,Package,Version,Op, false, false, false);
         const size_t archfound = Package.rfind(':');
         if (Start == 0)
-           return _error->Error("Problem parsing Provides line");
+           return _error->Warning("Problem parsing Provides line");
         if (unlikely(Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals)) {
            _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.to_string().c_str());
         } else if (archfound != string::npos) {
@@ -963,6 +961,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
            return false;
       }
    }
+   return true;
+}
+                                                                       /*}}}*/
+// ListParser::ParseTag - Parse the tag list                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::ParseTag(pkgCache::VerIterator &Ver)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find("Tag",Start,Stop) == false)
+      return true;
+
+   while (1) {
+      while (1) {
+         if (Start == Stop)
+            return true;
+         if (Stop[-1] != ' ' && Stop[-1] != '\t')
+            break;
+         --Stop;
+      }
+
+      const char *Begin = Stop - 1;
+      while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',')
+         --Begin;
+
+      if (NewTag(Ver, Begin, Stop - Begin) == false)
+         return false;
+
+      while (1) {
+         if (Begin == Start)
+            return true;
+         if (Begin[-1] == ',')
+            break;
+         --Begin;
+      }
+
+      Stop = Begin - 1;
+   }
+
    return true;
 }
                                                                        /*}}}*/