]> git.saurik.com Git - apt.git/commitdiff
don't truncate 100 char long paths in tar extraction
authorOskari Saarenmaa <os_debian@ohmu.fi>
Thu, 12 Sep 2013 11:20:01 +0000 (13:20 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 12 Sep 2013 11:52:43 +0000 (13:52 +0200)
When a data.tar.{gz,xz} contains a path name that is exactly
100 characters long, it will get truncated to 99 chars upon
extraction in ExtractTar::Go().

Using all of the 100 available characters for the filename
seems to be new behaviour in gnu tar.

Closes: #689582
Thanks: Mika Eloranta for the testcase!

apt-inst/contrib/extracttar.cc

index 49ed5db56dc14e620ad297eaa256791546b5c260..fb4db42f817261b9ba0e26f525221aa655b755d5 100644 (file)
@@ -161,8 +161,8 @@ bool ExtractTar::Go(pkgDirStream &Stream)
       return false;
    
    // Loop over all blocks
-   string LastLongLink;
-   string LastLongName;
+   string LastLongLink, ItemLink;
+   string LastLongName, ItemName;
    while (1)
    {
       bool BadRecord = false;      
@@ -208,25 +208,23 @@ bool ExtractTar::Go(pkgDirStream &Stream)
          StrToNum(Tar->Major,Itm.Major,sizeof(Tar->Major),8) == false ||
          StrToNum(Tar->Minor,Itm.Minor,sizeof(Tar->Minor),8) == false)
         return _error->Error(_("Corrupted archive"));
-      
-      // Grab the filename
+
+      // Grab the filename and link target: use last long name if one was
+      // set, otherwise use the header value as-is, but remember that it may
+      // fill the entire 100-byte block and needs to be zero-terminated.
+      // See Debian Bug #689582.
       if (LastLongName.empty() == false)
         Itm.Name = (char *)LastLongName.c_str();
       else
-      {
-        Tar->Name[sizeof(Tar->Name)-1] = 0;
-        Itm.Name = Tar->Name;
-      }      
+        Itm.Name = (char *)ItemName.assign(Tar->Name, sizeof(Tar->Name)).c_str();
       if (Itm.Name[0] == '.' && Itm.Name[1] == '/' && Itm.Name[2] != 0)
         Itm.Name += 2;
-      
-      // Grab the link target
-      Tar->Name[sizeof(Tar->LinkName)-1] = 0;
-      Itm.LinkTarget = Tar->LinkName;
 
       if (LastLongLink.empty() == false)
         Itm.LinkTarget = (char *)LastLongLink.c_str();
-      
+      else
+        Itm.LinkTarget = (char *)ItemLink.assign(Tar->LinkName, sizeof(Tar->LinkName)).c_str();
+
       // Convert the type over
       switch (Tar->LinkFlag)
       {