Просмотр исходного кода

handle missing "Description" in apt-cache show

do not blindly assume that all packages stanzas have a "Description:"
field in 'apt-cache show' as well as in the cache creation itself.

We instead assume now that if the stanza has a Description, it will not
be the first field as we look out for "\nDescription" to take care of
MD5sum as well as (maybe ignored) translated Descriptions embedded in
the package stanza.

Closes: #712435
David Kalnischkies лет назад: 13
Родитель
Сommit
99359751ef

+ 5 - 1
apt-pkg/deb/deblistparser.cc

@@ -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))

+ 3 - 1
apt-pkg/pkgcachegen.cc

@@ -296,6 +296,8 @@ bool pkgCacheGenerator::MergeListPackage(ListParser &List, pkgCache::PkgIterator
 
    // Find the right version to write the description
    MD5SumValue CurMd5 = List.Description_md5();
+   if (CurMd5.Value().empty() == true || List.Description().empty() == true)
+      return true;
    std::string CurLang = List.DescriptionLanguage();
 
    for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
@@ -480,7 +482,7 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
 
    /* Record the Description (it is not translated) */
    MD5SumValue CurMd5 = List.Description_md5();
-   if (CurMd5.Value().empty() == true)
+   if (CurMd5.Value().empty() == true || List.Description().empty() == true)
       return true;
    std::string CurLang = List.DescriptionLanguage();
 

+ 32 - 15
cmdline/apt-cache.cc

@@ -1161,7 +1161,11 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
    }
 
    // Get a pointer to start of Description field
-   const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:");
+   const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "\nDescription");
+   if (DescP != NULL)
+      ++DescP;
+   else
+      DescP = Buffer + V.FileList()->Size;
 
    // Write all but Description
    if (fwrite(Buffer,1,DescP - Buffer,stdout) < (size_t)(DescP - Buffer))
@@ -1173,25 +1177,38 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
    // Show the right description
    pkgRecords Recs(*Cache);
    pkgCache::DescIterator Desc = V.TranslatedDescription();
-   pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
-   cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
-
-   // Find the first field after the description (if there is any)
-   for(DescP++;DescP != &Buffer[V.FileList()->Size];DescP++) 
+   if (Desc.end() == false)
    {
-      if(*DescP == '\n' && *(DescP+1) != ' ') 
+      pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+      cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
+      cout << std::endl << "Description-md5: " << Desc.md5() << std::endl;
+
+      // Find the first field after the description (if there is any)
+      while ((DescP = (unsigned char*)strchr((char*)DescP, '\n')) != NULL)
       {
-	 // write the rest of the buffer
-	 const unsigned char *end=&Buffer[V.FileList()->Size];
-	 if (fwrite(DescP,1,end-DescP,stdout) < (size_t)(end-DescP)) 
-	 {
-	    delete [] Buffer;
-	    return false;
-	 }
+	 if (DescP[1] == ' ')
+	    DescP += 2;
+	 else if (strncmp((char*)DescP, "\nDescription", strlen("\nDescription")) == 0)
+	    DescP += strlen("\nDescription");
+	 else
+	    break;
+      }
+      if (DescP != NULL)
+	 ++DescP;
+   }
+   // if we have no translation, we found a lonely Description-md5, so don't skip it
 
-	 break;
+   if (DescP != NULL)
+   {
+      // write the rest of the buffer
+      const unsigned char *end=&Buffer[V.FileList()->Size];
+      if (fwrite(DescP,1,end-DescP,stdout) < (size_t)(end-DescP))
+      {
+	 delete [] Buffer;
+	 return false;
       }
    }
+
    // write a final newline (after the description)
    cout<<endl;
    delete [] Buffer;

+ 1 - 0
debian/changelog

@@ -16,6 +16,7 @@ apt (0.9.8.3) UNRELEASED; urgency=low
   * fail in CopyFile if the FileFds have error flag set
   * ensure state-dir exists before coyping cdrom files
   * fix file location for configure-index.gz in apt.conf(5) (Closes: #711921)
+  * handle missing "Description" in apt-cache show (Closes: #712435)
 
  -- David Kalnischkies <kalnischkies@gmail.com>  Sun, 09 Jun 2013 15:06:24 +0200
 

+ 89 - 0
test/integration/test-bug-712435-missing-descriptions

@@ -0,0 +1,89 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64'
+
+PACKAGESTANZA='Version: 0.9.7.8
+Installed-Size: 3270
+Maintainer: APT Development Team <deity@lists.debian.org>
+Architecture: amd64
+Filename: pool/main/a/apt/apt_0.9.7.8_amd64.deb
+MD5sum: 3a622acda41620df50aa22a9fac6f32e'
+
+DESCRIPTION='Description: commandline package manager
+ This APT has Super Cow Powers.'
+
+TRANSDESCRIPTION='Description-en: commandline package manager
+ This APT has translated Super Cow Powers.'
+
+echo "Package: apt-normal
+$PACKAGESTANZA
+$DESCRIPTION
+Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+Package: apt-both-below
+$PACKAGESTANZA
+$DESCRIPTION
+$TRANSDESCRIPTION
+Description-md5: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+
+Package: apt-both-middle
+$PACKAGESTANZA
+$DESCRIPTION
+Description-md5: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+$TRANSDESCRIPTION
+
+Package: apt-both-top
+$PACKAGESTANZA
+Description-md5: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+$DESCRIPTION
+$TRANSDESCRIPTION
+
+Package: apt-trans
+$PACKAGESTANZA
+$TRANSDESCRIPTION
+Description-md5: cccccccccccccccccccccccccccccccc
+
+Package: apt-md5
+$PACKAGESTANZA
+Description-md5: dddddddddddddddddddddddddddddddd
+
+Package: apt-none
+$PACKAGESTANZA" > aptarchive/Packages
+
+setupaptarchive
+
+testequal "Package: apt-normal
+$PACKAGESTANZA
+$DESCRIPTION
+Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+" aptcache show apt-normal
+
+# displaying the translated Description would be equally valid,
+# but we assume only one description is in a Packages file and
+# so we prefer "Description" over "Description-*" currently.
+for variant in 'below' 'middle' 'top'; do
+	testequal "Package: apt-both-$variant
+$PACKAGESTANZA
+$DESCRIPTION
+Description-md5: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+" aptcache show apt-both-$variant
+done
+
+testequal "Package: apt-trans
+$PACKAGESTANZA
+$TRANSDESCRIPTION
+Description-md5: cccccccccccccccccccccccccccccccc
+" aptcache show apt-trans
+
+testequal "Package: apt-md5
+$PACKAGESTANZA
+Description-md5: dddddddddddddddddddddddddddddddd
+" aptcache show apt-md5
+
+testequal "Package: apt-none
+$PACKAGESTANZA
+" aptcache show apt-none