]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/tagfile.cc
add a testcase for 100 char long path truncate bug #689582
[apt.git] / apt-pkg / tagfile.cc
index ff6593e26e4514e78c5378a0ac578ed5e06c5952..b91e868e2a6c9f6169038dc336bcc517efe84a23 100644 (file)
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
+#include<config.h>
+
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
 
-#include <apti18n.h>
-    
 #include <string>
 #include <stdio.h>
 #include <ctype.h>
+
+#include <apti18n.h>
                                                                        /*}}}*/
 
 using std::string;
@@ -27,7 +30,10 @@ using std::string;
 class pkgTagFilePrivate
 {
 public:
-   pkgTagFilePrivate(FileFd *pFd, unsigned long Size) : Fd(*pFd), Size(Size)
+   pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Buffer(NULL),
+                                                            Start(NULL), End(NULL),
+                                                            Done(false), iOffset(0),
+                                                            Size(Size)
    {
    }
    FileFd &Fd;
@@ -35,30 +41,36 @@ public:
    char *Start;
    char *End;
    bool Done;
-   unsigned long iOffset;
-   unsigned long Size;
+   unsigned long long iOffset;
+   unsigned long long Size;
 };
 
 // TagFile::pkgTagFile - Constructor                                   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size)
+pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size)
 {
+   /* The size is increased by 4 because if we start with the Size of the
+      filename we need to try to read 1 char more to see an EOF faster, 1
+      char the end-pointer can be on and maybe 2 newlines need to be added
+      to the end of the file -> 4 extra chars */
+   Size += 4;
    d = new pkgTagFilePrivate(pFd, Size);
 
    if (d->Fd.IsOpen() == false)
-   {
       d->Start = d->End = d->Buffer = 0;
+   else
+      d->Buffer = (char*)malloc(sizeof(char) * Size);
+
+   if (d->Buffer == NULL)
       d->Done = true;
-      d->iOffset = 0;
-      return;
-   }
-   
-   d->Buffer = new char[Size];
+   else
+      d->Done = false;
+
    d->Start = d->End = d->Buffer;
-   d->Done = false;
    d->iOffset = 0;
-   Fill();
+   if (d->Done == false)
+      Fill();
 }
                                                                        /*}}}*/
 // TagFile::~pkgTagFile - Destructor                                   /*{{{*/
@@ -66,11 +78,11 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size)
 /* */
 pkgTagFile::~pkgTagFile()
 {
-   delete [] d->Buffer;
+   free(d->Buffer);
    delete d;
 }
                                                                        /*}}}*/
-// TagFile::Offset - Return the current offset in the buffer           /*{{{*/
+// TagFile::Offset - Return the current offset in the buffer           /*{{{*/
 unsigned long pkgTagFile::Offset()
 {
    return d->iOffset;
@@ -83,19 +95,22 @@ unsigned long pkgTagFile::Offset()
  */
 bool pkgTagFile::Resize()
 {
-   char *tmp;
-   unsigned long EndSize = d->End - d->Start;
-
    // fail is the buffer grows too big
    if(d->Size > 1024*1024+1)
       return false;
 
+   return Resize(d->Size * 2);
+}
+bool pkgTagFile::Resize(unsigned long long const newSize)
+{
+   unsigned long long const EndSize = d->End - d->Start;
+
    // get new buffer and use it
-   tmp = new char[2*d->Size];
-   memcpy(tmp, d->Buffer, d->Size);
-   d->Size = d->Size*2;
-   delete [] d->Buffer;
-   d->Buffer = tmp;
+   char* newBuffer = (char*)realloc(d->Buffer, sizeof(char) * newSize);
+   if (newBuffer == NULL)
+      return false;
+   d->Buffer = newBuffer;
+   d->Size = newSize;
 
    // update the start/end pointers to the new buffer
    d->Start = d->Buffer;
@@ -136,8 +151,8 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
    then fills the rest from the file */
 bool pkgTagFile::Fill()
 {
-   unsigned long EndSize = d->End - d->Start;
-   unsigned long Actual = 0;
+   unsigned long long EndSize = d->End - d->Start;
+   unsigned long long Actual = 0;
    
    memmove(d->Buffer,d->Start,EndSize);
    d->Start = d->Buffer;
@@ -146,9 +161,10 @@ bool pkgTagFile::Fill()
    if (d->Done == false)
    {
       // See if only a bit of the file is left
-      if (d->Fd.Read(d->End, d->Size - (d->End - d->Buffer),&Actual) == false)
+      unsigned long long const dataSize = d->Size - ((d->End - d->Buffer) + 1);
+      if (d->Fd.Read(d->End, dataSize, &Actual) == false)
         return false;
-      if (Actual != d->Size - (d->End - d->Buffer))
+      if (Actual != dataSize || d->Fd.Eof() == true)
         d->Done = true;
       d->End += Actual;
    }
@@ -165,8 +181,13 @@ bool pkgTagFile::Fill()
       for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--)
         if (*E == '\n')
            LineCount++;
-      for (; LineCount < 2; LineCount++)
-        *d->End++ = '\n';
+      if (LineCount < 2)
+      {
+        if ((unsigned)(d->End - d->Buffer) >= d->Size)
+           Resize(d->Size + 3);
+        for (; LineCount < 2; LineCount++)
+           *d->End++ = '\n';
+      }
       
       return true;
    }
@@ -178,12 +199,12 @@ bool pkgTagFile::Fill()
 // ---------------------------------------------------------------------
 /* This jumps to a pre-recorded file location and reads the record
    that is there */
-bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
+bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
 {
    // We are within a buffer space of the next hit..
    if (Offset >= d->iOffset && d->iOffset + (d->End - d->Start) > Offset)
    {
-      unsigned long Dist = Offset - d->iOffset;
+      unsigned long long Dist = Offset - d->iOffset;
       d->Start += Dist;
       d->iOffset += Dist;
       return Step(Tag);
@@ -212,6 +233,16 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
    return true;
 }
                                                                        /*}}}*/
+// pkgTagSection::pkgTagSection - Constructor                          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgTagSection::pkgTagSection()
+   : Section(0), TagCount(0), d(NULL), Stop(0)
+{
+   memset(&Indexes, 0, sizeof(Indexes));
+   memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+}
+                                                                       /*}}}*/
 // TagSection::Scan - Scan for the end of the header information       /*{{{*/
 // ---------------------------------------------------------------------
 /* This looks for the first double new line in the data stream.
@@ -276,10 +307,17 @@ void pkgTagSection::Trim()
    for (; Stop > Section + 2 && (Stop[-2] == '\n' || Stop[-2] == '\r'); Stop--);
 }
                                                                        /*}}}*/
+// TagSection::Exists - return True if a tag exists                    /*{{{*/
+bool pkgTagSection::Exists(const char* const Tag)
+{
+   unsigned int tmp;
+   return Find(Tag, tmp);
+}
+                                                                       /*}}}*/
 // TagSection::Find - Locate a tag                                     /*{{{*/
 // ---------------------------------------------------------------------
 /* This searches the section for a tag that matches the given string. */
-bool pkgTagSection::Find(const char *Tag,unsigned &Pos) const
+bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const
 {
    unsigned int Length = strlen(Tag);
    unsigned int I = AlphaIndexes[AlphaHash(Tag)];
@@ -420,9 +458,13 @@ bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags,
    const char *Stop;
    if (Find(Tag,Start,Stop) == false)
       return true;
-   
-   switch (StringToBool(string(Start,Stop)))
-   {     
+   return FindFlag(Flags, Flag, Start, Stop);
+}
+bool const pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag,
+                                       char const* Start, char const* Stop)
+{
+   switch (StringToBool(string(Start, Stop)))
+   {
       case 0:
       Flags &= ~Flag;
       return true;
@@ -474,6 +516,7 @@ static const char *iTFRewritePackageOrder[] = {
                           "MD5Sum",
                           "SHA1",
                           "SHA256",
+                          "SHA512",
                            "MSDOS-Filename",   // Obsolete
                           "Description",
                           0};