[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#388708: apt: Upgrading to this version makes status file unparseable



[..]
On Fri, Sep 22, 2006 at 12:49:22AM -0500, Manoj Srivastava wrote:
> #_> aptitude -u
>  ... upgrade ...
> #_> aptitude -vvv upgrade
> Reading package lists... Error!
> E: Unable to parse package file /var/lib/dpkg/status (1)
> E: The package lists or status file could not be parsed or opened.
> Reading package lists... Error!
> E: Unable to parse package file /var/lib/dpkg/status (1)
> E: The package lists or status file could not be parsed or opened.
[..]

I was able to reproduce this now (thanks for your help Manoj!). It
turned out that the buffer in the tagfile code was too small
(again!). The attached patch should fix the issue by allowing the
tagfile buffer to grow dynamically. Testing is very welcome.

Cheers,
 Michael

-- 
Linux is not The Answer. Yes is the answer. Linux is The Question. - Neo
=== modified file 'apt-pkg/tagfile.cc'
--- apt-pkg/tagfile.cc	2006-09-15 16:24:47 +0000
+++ apt-pkg/tagfile.cc	2006-09-30 21:34:13 +0000
@@ -59,19 +59,52 @@
    delete [] Buffer;
 }
 									/*}}}*/
+// TagFile::Resize - Resize the internal buffer				/*{{{*/
+// ---------------------------------------------------------------------
+/* Resize the internal buffer (double it in size). Fail if a maximum size
+ * size is reached.
+ */
+bool pkgTagFile::Resize()
+{
+   char *tmp;
+   unsigned long EndSize = End - Start;
+
+   // fail is the buffer grows too big
+   if(Size > 1024*1024+1)
+      return false;
+
+   // get new buffer and use it
+   tmp = new char[2*Size];
+   memcpy(tmp, Buffer, Size);
+   Size = Size*2;
+   delete [] Buffer;
+   Buffer = tmp;
+
+   // update the start/end pointers to the new buffer
+   Start = Buffer;
+   End = Start + EndSize;
+   return true;
+}
+
 // TagFile::Step - Advance to the next section				/*{{{*/
 // ---------------------------------------------------------------------
-/* If the Section Scanner fails we refill the buffer and try again. */
+/* If the Section Scanner fails we refill the buffer and try again. 
+ * If that fails too, double the buffer size and try again until a
+ * maximum buffer is reached.
+ */
 bool pkgTagFile::Step(pkgTagSection &Tag)
 {
-   if (Tag.Scan(Start,End - Start) == false)
+   while (Tag.Scan(Start,End - Start) == false)
    {
       if (Fill() == false)
 	 return false;
       
-      if (Tag.Scan(Start,End - Start) == false)
+      if(Tag.Scan(Start,End - Start))
+	 break;
+
+      if (Resize() == false)
 	 return _error->Error(_("Unable to parse package file %s (1)"),
-			      Fd.Name().c_str());
+				 Fd.Name().c_str());
    }
    Start += Tag.size();
    iOffset += Tag.size();

=== modified file 'apt-pkg/tagfile.h'
--- apt-pkg/tagfile.h	2006-09-30 20:50:41 +0000
+++ apt-pkg/tagfile.h	2006-09-30 21:35:25 +0000
@@ -77,6 +77,7 @@
    unsigned long Size;
    
    bool Fill();
+   bool Resize();
    
    public:
 
 


Reply to: