]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/deblistparser.cc
fix apport report writing (LP: #1254499)
[apt.git] / apt-pkg / deb / deblistparser.cc
index 56d5297fc6ef9fc21bdd9441dc6f9c5db55acdad..68d544e1f97add0c743cebcde236b12e863fc59a 100644 (file)
@@ -219,8 +219,12 @@ MD5SumValue debListParser::Description_md5()
    string const value = Section.FindS("Description-md5");
    if (value.empty() == true)
    {
+      std::string const desc = Description() + "\n";
+      if (desc == "\n")
+        return MD5SumValue();
+
       MD5Summation md5;
-      md5.Add((Description() + "\n").c_str());
+      md5.Add(desc.c_str());
       return md5.Result();
    }
    else if (likely(value.size() == 32))
@@ -284,7 +288,7 @@ unsigned short debListParser::VersionHash()
                             "Replaces",0};
    unsigned long Result = INIT_FCS;
    char S[1024];
-   for (const char **I = Sections; *I != 0; I++)
+   for (const char * const *I = Sections; *I != 0; ++I)
    {
       const char *Start;
       const char *End;
@@ -295,13 +299,13 @@ unsigned short debListParser::VersionHash()
          of certain fields. dpkg also has the rather interesting notion of
          reformatting depends operators < -> <= */
       char *J = S;
-      for (; Start != End; Start++)
+      for (; Start != End; ++Start)
       {
-        if (isspace(*Start) == 0)
-           *J++ = tolower_ascii(*Start);
-        if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
-           *J++ = '=';
-        if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
+        if (isspace(*Start) != 0)
+           continue;
+        *J++ = tolower_ascii(*Start);
+
+        if ((*Start == '<' || *Start == '>') && Start[1] != *Start && Start[1] != '=')
            *J++ = '=';
       }
 
@@ -631,7 +635,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
       string Version;
       unsigned int Op;
 
-      Start = ParseDepends(Start,Stop,Package,Version,Op,false,!MultiArchEnabled);
+      Start = ParseDepends(Start, Stop, Package, Version, Op, false, false);
       if (Start == 0)
         return _error->Error("Problem parsing dependency %s",Tag);
       size_t const found = Package.rfind(':');
@@ -713,9 +717,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
       }
    }
 
-   if (MultiArchEnabled == false)
-      return true;
-   else if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+   if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
    {
       string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
       return NewProvidesAllArch(Ver, Package, Ver.VerStr());
@@ -801,104 +803,28 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
    map_ptrloc const storage = WriteUniqString(component);
    FileI->Component = storage;
 
-   // FIXME: Code depends on the fact that Release files aren't compressed
-   FILE* release = fdopen(dup(File.Fd()), "r");
-   if (release == NULL)
+   pkgTagFile TagFile(&File, File.Size());
+   pkgTagSection Section;
+   if (_error->PendingError() == true || TagFile.Step(Section) == false)
       return false;
 
-   char buffer[101];
-   bool gpgClose = false;
-   while (fgets(buffer, sizeof(buffer), release) != NULL)
-   {
-      size_t len = 0;
-
-      // Skip empty lines
-      for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len)
-         /* nothing */
-         ;
-      if (buffer[len] == '\0')
-        continue;
-
-      // only evalute the first GPG section
-      if (strncmp("-----", buffer, 5) == 0)
-      {
-        if (gpgClose == true)
-           break;
-        gpgClose = true;
-        continue;
-      }
-
-      // seperate the tag from the data
-      const char* dataStart = strchr(buffer + len, ':');
-      if (dataStart == NULL)
-        continue;
-      len = dataStart - buffer;
-      for (++dataStart; *dataStart == ' '; ++dataStart)
-         /* nothing */
-         ;
-      const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
-      // The last char should be a newline, but we can never be sure: #633350
-      const char* lineEnd = dataEnd;
-      for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
-         /* nothing */
-         ;
-      ++lineEnd;
-
-      // which datastorage need to be updated
-      enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
-      if (buffer[0] == ' ')
-        ;
-      #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
-      APT_PARSER_WRITETO(Suite)
-      APT_PARSER_WRITETO(Component)
-      APT_PARSER_WRITETO(Version)
-      APT_PARSER_WRITETO(Origin)
-      APT_PARSER_WRITETO(Codename)
-      APT_PARSER_WRITETO(Label)
-      #undef APT_PARSER_WRITETO
-      #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
-        pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
-      APT_PARSER_FLAGIT(NotAutomatic)
-      APT_PARSER_FLAGIT(ButAutomaticUpgrades)
-      #undef APT_PARSER_FLAGIT
-
-      // load all data from the line and save it
-      string data;
-      if (writeTo != None)
-        data.append(dataStart, dataEnd);
-      if (sizeof(buffer) - 1 == (dataEnd - buffer))
-      {
-        while (fgets(buffer, sizeof(buffer), release) != NULL)
-        {
-           if (writeTo != None)
-              data.append(buffer);
-           if (strlen(buffer) != sizeof(buffer) - 1)
-              break;
-        }
-      }
-      if (writeTo != None)
-      {
-        // remove spaces and stuff from the end of the data line
-        for (std::string::reverse_iterator s = data.rbegin();
-             s != data.rend(); ++s)
-        {
-           if (*s != '\r' && *s != '\n' && *s != ' ')
-              break;
-           *s = '\0';
-        }
-        map_ptrloc const storage = WriteUniqString(data);
-        switch (writeTo) {
-        case Suite: FileI->Archive = storage; break;
-        case Component: FileI->Component = storage; break;
-        case Version: FileI->Version = storage; break;
-        case Origin: FileI->Origin = storage; break;
-        case Codename: FileI->Codename = storage; break;
-        case Label: FileI->Label = storage; break;
-        case None: break;
-        }
-      }
+   std::string data;
+   #define APT_INRELEASE(TAG, STORE) \
+   data = Section.FindS(TAG); \
+   if (data.empty() == false) \
+   { \
+      map_ptrloc const storage = WriteUniqString(data); \
+      STORE = storage; \
    }
-   fclose(release);
+   APT_INRELEASE("Suite", FileI->Archive)
+   APT_INRELEASE("Component", FileI->Component)
+   APT_INRELEASE("Version", FileI->Version)
+   APT_INRELEASE("Origin", FileI->Origin)
+   APT_INRELEASE("Codename", FileI->Codename)
+   APT_INRELEASE("Label", FileI->Label)
+   #undef APT_INRELEASE
+   Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
+   Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
 
    return !_error->PendingError();
 }