Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > db680851aa9db923c397069e4f79cf60 > files > 24

kdelibs-4.6.5-11.fc15.src.rpm

diff -ur kdelibs-4.6.5/kdecore/io/ktar.cpp kdelibs-4.6.5-ktar-kde#258737/kdecore/io/ktar.cpp
--- kdelibs-4.6.5/kdecore/io/ktar.cpp	2011-04-01 15:56:18.000000000 +0200
+++ kdelibs-4.6.5-ktar-kde#258737/kdecore/io/ktar.cpp	2012-03-09 03:21:22.000000000 +0100
@@ -179,7 +179,9 @@
 qint64 KTar::KTarPrivate::readRawHeader( char *buffer ) {
   // Read header
   qint64 n = q->device()->read( buffer, 0x200 );
-  if ( n == 0x200 && buffer[0] != 0 ) {
+  // we need to test if there is a prefix value because the file name can be null
+  // and the prefix can have a value and in this case we don't reset n.
+  if ( n == 0x200 && (buffer[0] != 0 || buffer[0x159] != 0) ) {
     // Make sure this is actually a tar header
     if (strncmp(buffer + 257, "ustar", 5)) {
       // The magic isn't there (broken/old tars), but maybe a correct checksum?
@@ -234,7 +236,7 @@
   }/*wend*/
   // jump over the rest
   const int skip = 0x200 - (n % 0x200);
-  if (skip < 0x200) {
+  if (skip <= 0x200) {
     if (dev->read(buffer,skip) != skip)
         return false;
   }
@@ -362,6 +364,7 @@
         if (n == 0x200)
         {
             bool isdir = false;
+            bool isGlobalHeader = false;
 
             if ( name.endsWith( QLatin1Char( '/' ) ) )
             {
@@ -369,6 +372,11 @@
                 name.truncate( name.length() - 1 );
             }
 
+            QByteArray prefix = QByteArray(buffer + 0x159, 155);
+            if (prefix[0] != '\0') {
+                name = (QString::fromLatin1(prefix.constData()) + QLatin1Char('/') +  name);
+            }
+
             int pos = name.lastIndexOf( QLatin1Char('/') );
             QString nm = ( pos == -1 ) ? name : name.mid( pos + 1 );
 
@@ -393,7 +401,11 @@
             char typeflag = buffer[ 0x9c ];
             // '0' for files, '1' hard link, '2' symlink, '5' for directory
             // (and 'L' for longlink fileNames, 'K' for longlink symlink targets)
-            // and 'D' for GNU tar extension DUMPDIR
+            // 'D' for GNU tar extension DUMPDIR, 'x' for Extended header referring
+            // to the next file in the archive and 'g' for Global extended header
+            if ( typeflag == 'g' )
+                isGlobalHeader = true;
+
             if ( typeflag == '5' )
                 isdir = true;
 
@@ -450,6 +462,9 @@
                     kWarning(7041) << "skipping" << skip << "failed";
             }
 
+            if (isGlobalHeader)
+                continue;
+
             if ( pos == -1 )
             {
                 if (nm == QLatin1String(".")) { // special case