summaryrefslogtreecommitdiff
path: root/cmdline/apt-cache.cc
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-08-05 22:51:30 +0200
committerMichael Vogt <mvo@debian.org>2013-08-05 22:51:30 +0200
commitafc2891fdac29848826a7f9cdeb22ce0c2409350 (patch)
treef7c5c2ea862eca5d28bbb4d45181d6f21e60d06f /cmdline/apt-cache.cc
parent4ccd3b3ce69d6a6598e1773689a44fdec78a85cc (diff)
parent64876cf7963f897efa70c3e424527e2e8651aa29 (diff)
Merge remote-tracking branch 'upstream/debian/sid' into bugfix/coverity
Diffstat (limited to 'cmdline/apt-cache.cc')
-rw-r--r--cmdline/apt-cache.cc84
1 files changed, 57 insertions, 27 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index fb4467c2c..e847de875 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -1127,6 +1127,24 @@ bool Dotty(CommandLine &CmdL)
// ---------------------------------------------------------------------
/* This displays the package record from the proper package index file.
It is not used by DumpAvail for performance reasons. */
+
+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, TagName, TagLen) == 0)
+ DescP += TagLen;
+ else
+ break;
+ }
+ if (DescP != NULL)
+ ++DescP;
+ return DescP;
+}
bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
{
pkgCache *Cache = CacheFile.GetPkgCache();
@@ -1150,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;
@@ -1165,10 +1184,11 @@ 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))
+ size_t const length = DescP - Buffer;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Buffer, length) == false)
{
delete [] Buffer;
return false;
@@ -1184,35 +1204,37 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
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)
- {
- if (DescP[1] == ' ')
- DescP += 2;
- else if (strncmp((char*)DescP, "\nDescription", strlen("\nDescription")) == 0)
- DescP += strlen("\nDescription");
- else
- break;
- }
- if (DescP != NULL)
- ++DescP;
+ DescP = skipDescriptionFields(DescP);
}
- // if we have no translation, we found a lonely Description-md5, so don't skip it
+ // else we have no translation, so we found a lonely Description-md5 -> don't skip it
- if (DescP != NULL)
+ // write the rest of the buffer, but skip mixed in Descriptions* fields
+ while (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))
+ const unsigned char * const Start = DescP;
+ const unsigned char *End = (unsigned char*)strstr((char*)DescP, "\nDescription");
+ if (End == NULL)
+ {
+ End = &Buffer[Vf->Size];
+ DescP = NULL;
+ }
+ else
+ {
+ ++End; // get the newline into the output
+ DescP = skipDescriptionFields(End + strlen("Description"));
+ }
+ size_t const length = End - Start;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Start, length) == false)
{
delete [] Buffer;
return false;
}
}
- // write a final newline (after the description)
+ // write a final newline after the last field
cout<<endl;
- delete [] Buffer;
+ delete [] Buffer;
return true;
}
/*}}}*/
@@ -1300,7 +1322,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;
}
@@ -1315,7 +1341,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;