]> git.saurik.com Git - apt.git/commitdiff
fix 'apt-cache search' crash with missing description
authorDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 18 Jul 2013 17:22:29 +0000 (19:22 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 18 Jul 2013 19:30:47 +0000 (21:30 +0200)
Beside the earlier fixed 'apt-cache show', 'showpkg' and 'search' deal
with descriptions. 'showpkg' was fixed by fixing the cache generation
for 'show', but 'search' still segfaulted.

On the upside, it doesn't segfault any longer, on the downside, if a
package has no description at all (aka: not in the Packages file and not
in a Translation-* file) the package can't be found with 'search', even
if we search only by name. That is a shortcoming in the code, but fixing
it means rewriting it completely for dubious gain at best.

So this commit just skips packages without a description and is done.

Closes: 647590
cmdline/apt-cache.cc
test/integration/test-bug-712435-missing-descriptions

index 336ac544b50e11a5cb2a7f7a7b9db6774ebf2409..5d1ee561592742b22424ac3f333dd20a39c37246 100644 (file)
@@ -1130,12 +1130,14 @@ bool Dotty(CommandLine &CmdL)
 
 static unsigned char const* skipDescriptionFields(unsigned char const * DescP)
 {
+   char const * const TagName = "\nDescription";
+   size_t const TagLen = strlen(TagName);
    while ((DescP = (unsigned char*)strchr((char*)DescP, '\n')) != NULL)
    {
       if (DescP[1] == ' ')
         DescP += 2;
-      else if (strncmp((char*)DescP, "\nDescription", strlen("\nDescription")) == 0)
-        DescP += strlen("\nDescription");
+      else if (strncmp((char*)DescP, TagName, TagLen) == 0)
+        DescP += TagLen;
       else
         break;
    }
@@ -1166,11 +1168,12 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
    if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
       return false;
 
-   // Read the record
-   unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+1];
-   Buffer[V.FileList()->Size] = '\n';
-   if (PkgF.Seek(V.FileList()->Offset) == false ||
-       PkgF.Read(Buffer,V.FileList()->Size) == false)
+   // Read the record (and ensure that it ends with a newline and NUL)
+   unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+2];
+   Buffer[Vf->Size] = '\n';
+   Buffer[Vf->Size+1] = '\0';
+   if (PkgF.Seek(Vf->Offset) == false ||
+       PkgF.Read(Buffer,Vf->Size) == false)
    {
       delete [] Buffer;
       return false;
@@ -1181,7 +1184,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
    if (DescP != NULL)
       ++DescP;
    else
-      DescP = Buffer + V.FileList()->Size;
+      DescP = Buffer + Vf->Size;
 
    // Write all but Description
    if (fwrite(Buffer,1,DescP - Buffer,stdout) < (size_t)(DescP - Buffer))
@@ -1211,7 +1214,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
       const unsigned char *End = (unsigned char*)strstr((char*)DescP, "\nDescription");
       if (End == NULL)
       {
-        End = &Buffer[V.FileList()->Size];
+        End = &Buffer[Vf->Size];
         DescP = NULL;
       }
       else
@@ -1318,7 +1321,11 @@ bool Search(CommandLine &CmdL)
       pkgCache::VerIterator V = Plcy->GetCandidateVer(P);
       if (V.end() == false)
       {
-        DFList[G->ID].Df = V.TranslatedDescription().FileList();
+        pkgCache::DescIterator const D = V.TranslatedDescription();
+        //FIXME: packages without a description can't be found
+        if (D.end() == true)
+           continue;
+        DFList[G->ID].Df = D.FileList();
         DFList[G->ID].ID = G->ID;
       }
 
@@ -1333,7 +1340,11 @@ bool Search(CommandLine &CmdL)
            continue;
 
         unsigned long id = Prv.OwnerPkg().Group()->ID;
-        DFList[id].Df = V.TranslatedDescription().FileList();
+        pkgCache::DescIterator const D = V.TranslatedDescription();
+        //FIXME: packages without a description can't be found
+        if (D.end() == true)
+           continue;
+        DFList[id].Df = D.FileList();
         DFList[id].ID = id;
 
         size_t const PrvPatternOffset = id * NumPatterns;
index c61bea452ade207d3f8faa5f7cc135c547a6f644..53ecbbeb3afedaf630ea4d18834f2985e2b11a5f 100755 (executable)
@@ -137,3 +137,29 @@ X-Some-Flag: yes
 X-Foo-Flag: Something with a Description
 X-Bar-Flag: no
 " aptcache show apt-intermixed3
+
+msgtest 'Test that no description does not destroy' 'showpkg'
+aptcache showpkg apt-none | sed 's#/tmp/.*_aptarchive_#/tmp/aptarchive_#' >showpkg.explosion && msgpass || msgfail
+testfileequal showpkg.explosion 'Package: apt-none
+Versions: 
+0.9.7.8 (/tmp/aptarchive_Packages)
+
+
+Reverse Depends: 
+Dependencies: 
+0.9.7.8 - 
+Provides: 
+0.9.7.8 - 
+Reverse Provides: '
+
+testempty aptcache search nonexistentstring
+
+# packages without a description can't be found
+testequal 'apt-normal - commandline package manager
+apt-both-below - commandline package manager
+apt-both-middle - commandline package manager
+apt-both-top - commandline package manager
+apt-trans - commandline package manager
+apt-intermixed - commandline package manager
+apt-intermixed2 - commandline package manager
+apt-intermixed3 - commandline package manager' aptcache search apt