Hello community,

here is the log from the commit of package karchive for openSUSE:Factory 
checked in at 2015-03-16 09:33:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/karchive (Old)
 and      /work/SRC/openSUSE:Factory/.karchive.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "karchive"

Changes:
--------
--- /work/SRC/openSUSE:Factory/karchive/karchive.changes        2015-02-16 
17:30:05.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.karchive.new/karchive.changes   2015-03-16 
09:33:11.000000000 +0100
@@ -1,0 +2,8 @@
+Sat Mar  7 16:58:53 UTC 2015 - hrvoje.sen...@gmail.com
+
+- Update to 5.8.0
+  * Stop failing on ZIP files with redundant data descriptors
+  * For more details please see:
+    https://www.kde.org/announcements/kde-frameworks-5.8.0.php
+
+-------------------------------------------------------------------

Old:
----
  karchive-5.7.0.tar.xz

New:
----
  karchive-5.8.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ karchive.spec ++++++
--- /var/tmp/diff_new_pack.qL4SRr/_old  2015-03-16 09:33:11.000000000 +0100
+++ /var/tmp/diff_new_pack.qL4SRr/_new  2015-03-16 09:33:11.000000000 +0100
@@ -17,12 +17,12 @@
 
 
 %define lname   libKF5Archive5
-%define _tar_path 5.7
+%define _tar_path 5.8
 Name:           karchive
 Version:        %{_tar_path}.0
 Release:        0
 BuildRequires:  cmake >= 2.8.12
-BuildRequires:  extra-cmake-modules >= 1.7.0
+BuildRequires:  extra-cmake-modules >= 1.8.0
 BuildRequires:  fdupes
 BuildRequires:  kf5-filesystem
 BuildRequires:  pkgconfig(Qt5Core) >= 5.2.0

++++++ karchive-5.7.0.tar.xz -> karchive-5.8.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/CMakeLists.txt 
new/karchive-5.8.0/CMakeLists.txt
--- old/karchive-5.7.0/CMakeLists.txt   2015-01-23 21:27:45.000000000 +0100
+++ new/karchive-5.8.0/CMakeLists.txt   2015-02-25 15:17:06.000000000 +0100
@@ -2,7 +2,7 @@
 
 project(KArchive)
 
-find_package(ECM 1.7.0 REQUIRED NO_MODULE)
+find_package(ECM 1.8.0 REQUIRED NO_MODULE)
 
 set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
 
@@ -45,7 +45,7 @@
 include(ECMSetupVersion)
 include(ECMGenerateHeaders)
 
-set(KF5_VERSION "5.7.0") # handled by release scripts
+set(KF5_VERSION "5.8.0") # handled by release scripts
 
 ecm_setup_version(${KF5_VERSION}
     VARIABLE_PREFIX KARCHIVE
Files old/karchive-5.7.0/autotests/data/redundantDataDescriptorsNoSignature.zip 
and new/karchive-5.8.0/autotests/data/redundantDataDescriptorsNoSignature.zip 
differ
Files 
old/karchive-5.7.0/autotests/data/redundantDataDescriptorsWithSignature.zip and 
new/karchive-5.8.0/autotests/data/redundantDataDescriptorsWithSignature.zip 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/autotests/karchivetest.cpp 
new/karchive-5.8.0/autotests/karchivetest.cpp
--- old/karchive-5.7.0/autotests/karchivetest.cpp       2015-01-23 
21:27:45.000000000 +0100
+++ new/karchive-5.8.0/autotests/karchivetest.cpp       2015-02-25 
15:17:06.000000000 +0100
@@ -1020,6 +1020,45 @@
     }
 }
 
+void KArchiveTest::testZipReadRedundantDataDescriptor_data()
+{
+    QTest::addColumn<QString>("fileName");
+    QTest::newRow("noSignature") << 
"data/redundantDataDescriptorsNoSignature.zip";
+    QTest::newRow("withSignature") << 
"data/redundantDataDescriptorsWithSignature.zip";
+}
+
+/**
+ * @dataProvider testZipReadRedundantDataDescriptor_data
+ */
+void KArchiveTest::testZipReadRedundantDataDescriptor()
+{
+    QFETCH(QString, fileName);
+
+    const QString redundantDataDescriptorZipFileName = QFINDTESTDATA(fileName);
+    QVERIFY(!redundantDataDescriptorZipFileName.isEmpty());
+
+    KZip zip(redundantDataDescriptorZipFileName);
+
+    QVERIFY(zip.open(QIODevice::ReadOnly));
+
+    const KArchiveDirectory *dir = zip.directory();
+    QVERIFY(dir != 0);
+
+    const QByteArray fileData("aaaaaaaaaaaaaaa");
+
+    // ZIP has no support for per-file user/group, so omit them from the 
listing
+    const QStringList listing = recursiveListEntries(dir, "", 0);
+
+    QCOMPARE(listing.count(), 2);
+    QCOMPARE(listing[0], QString::fromUtf8("mode=100644 path=compressed 
type=file size=%2").arg(fileData.size()));
+    QCOMPARE(listing[1], QString::fromUtf8("mode=100644 path=uncompressed 
type=file size=%2").arg(fileData.size()));
+
+    const KArchiveFile *fileEntry = static_cast< const KArchiveFile * 
>(dir->entry(dir->entries()[0]));
+    QCOMPARE(fileEntry->data(), fileData);
+    fileEntry = static_cast< const KArchiveFile * 
>(dir->entry(dir->entries()[1]));
+    QCOMPARE(fileEntry->data(), fileData);
+}
+
 void KArchiveTest::testRcc()
 {
     const QString rccFile = QFINDTESTDATA("runtime_resource.rcc"); // was 
copied from qtbase/tests/auto/corelib/io/qresourceengine
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/autotests/karchivetest.h 
new/karchive-5.8.0/autotests/karchivetest.h
--- old/karchive-5.7.0/autotests/karchivetest.h 2015-01-23 21:27:45.000000000 
+0100
+++ new/karchive-5.8.0/autotests/karchivetest.h 2015-02-25 15:17:06.000000000 
+0100
@@ -87,6 +87,8 @@
     void testZipWithNonLatinFileNames();
     void testZipWithOverwrittenFileName();
     void testZipAddLocalDirectory();
+    void testZipReadRedundantDataDescriptor_data();
+    void testZipReadRedundantDataDescriptor();
 
     void testRcc();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/src/k7zip.cpp 
new/karchive-5.8.0/src/k7zip.cpp
--- old/karchive-5.7.0/src/k7zip.cpp    2015-01-23 21:27:45.000000000 +0100
+++ new/karchive-5.8.0/src/k7zip.cpp    2015-02-25 15:17:06.000000000 +0100
@@ -174,7 +174,7 @@
      * @return the content of this file.
      * Call data() with care (only once per file), this data isn't cached.
      */
-    virtual QByteArray data() const;
+    QByteArray data() const Q_DECL_OVERRIDE;
 
     /**
      * This method returns QIODevice (internal class: KLimitedIODevice)
@@ -186,7 +186,7 @@
      * The returned device auto-opens (in readonly mode), no need to open it.
      * @return the QIODevice of the file
      */
-    virtual QIODevice *createDevice() const;
+    QIODevice *createDevice() const Q_DECL_OVERRIDE;
 
 private:
     const QByteArray m_data;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/src/karchivedirectory.h 
new/karchive-5.8.0/src/karchivedirectory.h
--- old/karchive-5.7.0/src/karchivedirectory.h  2015-01-23 21:27:45.000000000 
+0100
+++ new/karchive-5.8.0/src/karchivedirectory.h  2015-02-25 15:17:06.000000000 
+0100
@@ -115,7 +115,7 @@
     bool copyTo(const QString &dest, bool recursive = true) const;
 
 protected:
-    virtual void virtual_hook(int id, void *data);
+    void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
 private:
     KArchiveDirectoryPrivate *const d;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/src/karchivefile.h 
new/karchive-5.8.0/src/karchivefile.h
--- old/karchive-5.7.0/src/karchivefile.h       2015-01-23 21:27:45.000000000 
+0100
+++ new/karchive-5.8.0/src/karchivefile.h       2015-02-25 15:17:06.000000000 
+0100
@@ -104,7 +104,7 @@
     bool copyTo(const QString &dest) const;
 
 protected:
-    virtual void virtual_hook(int id, void *data);
+    void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
 private:
     KArchiveFilePrivate *const d;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/src/krcc.cpp 
new/karchive-5.8.0/src/krcc.cpp
--- old/karchive-5.7.0/src/krcc.cpp     2015-01-23 21:27:45.000000000 +0100
+++ new/karchive-5.8.0/src/krcc.cpp     2015-02-25 15:17:06.000000000 +0100
@@ -50,7 +50,7 @@
           m_resourcePath(resourcePath)
     {}
 
-    virtual QByteArray data() const Q_DECL_OVERRIDE
+    QByteArray data() const Q_DECL_OVERRIDE
     {
          QFile f(m_resourcePath);
          if (f.open(QIODevice::ReadOnly)) {
@@ -59,7 +59,7 @@
          qWarning() << "Couldn't open" << m_resourcePath;
          return QByteArray();
     }
-    virtual QIODevice *createDevice() const Q_DECL_OVERRIDE
+    QIODevice *createDevice() const Q_DECL_OVERRIDE
     {
         return new QFile(m_resourcePath);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.7.0/src/kzip.cpp 
new/karchive-5.8.0/src/kzip.cpp
--- old/karchive-5.7.0/src/kzip.cpp     2015-01-23 21:27:45.000000000 +0100
+++ new/karchive-5.8.0/src/kzip.cpp     2015-02-25 15:17:06.000000000 +0100
@@ -294,6 +294,88 @@
     return true;
 }
 
+/**
+ * Checks if a token for a central or local header has been found and resets
+ * the device to the begin of the token. If a token for the data descriptor is
+ * found it is assumed there is a central or local header token starting right
+ * behind the data descriptor, and the device is set accordingly to the begin
+ * of that token.
+ * To be called when a 'P' has been found.
+ * @param buffer start of buffer with the 3 bytes behind 'P'
+ * @param dev device that is read from
+ * @return true if a local or central header begin is or could be reached
+ */
+static bool handlePossibleHeaderBegin(const char* buffer, QIODevice *dev)
+{
+    // we have to detect three magic tokens here:
+    // PK34 for the next local header in case there is no data descriptor
+    // PK12 for the central header in case there is no data descriptor
+    // PK78 for the data descriptor in case it is following the compressed data
+    // TODO: optimize using 32bit const data for comparison instead of 
byte-wise,
+    // given we run at least on 32bit CPUs
+
+    if (buffer[0] == 'K') {
+        if (buffer[1] == 7 && buffer[2] == 8) {
+            // data descriptor token found
+            dev->seek(dev->pos() + 12); // skip the 'data_descriptor'
+            return true;
+        }
+
+        if ((buffer[1] == 1 && buffer[2] == 2)
+            || (buffer[1] == 3 && buffer[2] == 4)) {
+            // central/local header token found
+            dev->seek(dev->pos() - 4);
+            // go back 4 bytes, so that the magic bytes can be found
+            // in the next cycle...
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Reads the device forwards from the current pos until a token for a central 
or
+ * local header has been found or is to be assumed.
+ * @param dev device that is read from
+ * @return true if a local or central header token could be reached, false on 
error
+ */
+static bool seekToNextHeaderToken(QIODevice *dev)
+{
+    bool headerTokenFound = false;
+    char buffer[3];
+
+    while (!headerTokenFound) {
+        int n = dev->read(buffer, 1);
+        if (n < 1) {
+            //qWarning() << "Invalid ZIP file. Unexpected end of file. (#2)";
+            return false;
+        }
+
+        if (buffer[0] != 'P') {
+            continue;
+        }
+
+        n = dev->read(buffer, 3);
+        if (n < 3) {
+            //qWarning() << "Invalid ZIP file. Unexpected end of file. (#3)";
+            return false;
+        }
+
+        if (handlePossibleHeaderBegin(buffer, dev)) {
+            headerTokenFound = true;
+        } else {
+            for (int i = 0; i < 3; ++i) {
+                if (buffer[i] == 'P') {
+                    // We have another P character so we must go back a little 
to check if it is a magic
+                    dev->seek(dev->pos() - 3 + i);
+                    break;
+                }
+            }
+        }
+    }
+    return true;
+}
+
 ////////////////////////////////////////////////////////////////////////
 /////////////////////////// KZip ///////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
@@ -452,46 +534,13 @@
             if (gpf & 8) {
                 // here we have to read through the compressed data to find
                 // the next PKxx
-                //qDebug() << "trying to seek for next PK78";
-                bool foundSignature = false;
-
-                while (!foundSignature) {
-                    n = dev->read(buffer, 1);
-                    if (n < 1) {
-                        //qWarning() << "Invalid ZIP file. Unexpected end of 
file. (#2)";
-                        return false;
-                    }
-
-                    if (buffer[0] != 'P') {
-                        continue;
-                    }
-
-                    n = dev->read(buffer, 3);
-                    if (n < 3) {
-                        //qWarning() << "Invalid ZIP file. Unexpected end of 
file. (#3)";
-                        return false;
-                    }
-
-                    // we have to detect three magic tokens here:
-                    // PK34 for the next local header in case there is no data 
descriptor
-                    // PK12 for the central header in case there is no data 
descriptor
-                    // PK78 for the data descriptor in case it is following 
the compressed data
-
-                    if (buffer[0] == 'K' && buffer[1] == 7 && buffer[2] == 8) {
-                        foundSignature = true;
-                        dev->seek(dev->pos() + 12); // skip the 
'data_descriptor'
-                    } else if ((buffer[0] == 'K' && buffer[1] == 1 && 
buffer[2] == 2)
-                               || (buffer[0] == 'K' && buffer[1] == 3 && 
buffer[2] == 4)) {
-                        foundSignature = true;
-                        dev->seek(dev->pos() - 4); // go back 4 bytes, so that 
the magic bytes can be found...
-                    } else if (buffer[0] == 'P' || buffer[1] == 'P' || 
buffer[2] == 'P') {
-                        // We have another P character so we must go back a 
little to check if it is a magic
-                        dev->seek(dev->pos() - 3);
-                    }
+                if (!seekToNextHeaderToken(dev)) {
+                    return false;
                 }
             } else {
                 // here we skip the compressed data and jump to the next header
                 //qDebug() << "general purpose bit flag indicates, that local 
file header contains valid size";
+                bool foundSignature = false;
                 // check if this could be a symbolic link
                 if (compression_mode == NoCompression
                         && uncomp_size <= max_path_len
@@ -507,43 +556,10 @@
                     if (compr_size > dev->size()) {
                         // here we cannot trust the compressed size, so scan 
through the compressed
                         // data to find the next header
-                        bool foundSignature = false;
-
-                        while (!foundSignature) {
-                            n = dev->read(buffer, 1);
-                            if (n < 1) {
-                                //qWarning() << "Invalid ZIP file. Unexpected 
end of file. (#2)";
-                                return false;
-                            }
-
-                            if (buffer[0] != 'P') {
-                                continue;
-                            }
-
-                            n = dev->read(buffer, 3);
-                            if (n < 3) {
-                                //qWarning() << "Invalid ZIP file. Unexpected 
end of file. (#3)";
-                                return false;
-                            }
-
-                            // we have to detect three magic tokens here:
-                            // PK34 for the next local header in case there is 
no data descriptor
-                            // PK12 for the central header in case there is no 
data descriptor
-                            // PK78 for the data descriptor in case it is 
following the compressed data
-
-                            if (buffer[0] == 'K' && buffer[1] == 7 && 
buffer[2] == 8) {
-                                foundSignature = true;
-                                dev->seek(dev->pos() + 12); // skip the 
'data_descriptor'
-                            }
-
-                            if ((buffer[0] == 'K' && buffer[1] == 1 && 
buffer[2] == 2)
-                                    || (buffer[0] == 'K' && buffer[1] == 3 && 
buffer[2] == 4)) {
-                                foundSignature = true;
-                                dev->seek(dev->pos() - 4);
-                                // go back 4 bytes, so that the magic bytes 
can be found
-                                // in the next cycle...
-                            }
+                        if (!seekToNextHeaderToken(dev)) {
+                            return false;
                         }
+                        foundSignature = true;
                     } else {
 //          qDebug() << "before interesting dev->pos(): " << dev->pos();
                         bool success = dev->seek(dev->pos() + compr_size); // 
can this fail ???
@@ -557,6 +573,21 @@
                     }
 
                 }
+                // test for optional data descriptor
+                if (!foundSignature) {
+//                     qDebug() << "Testing for optional data descriptor";
+                    // read static data descriptor
+                    n = dev->read(buffer, 4);
+                    if (n < 4) {
+//                         qWarning() << "Invalid ZIP file. Unexpected end of 
file. (#1)";
+                        return false;
+                    }
+
+                    if (buffer[0] != 'P' || 
!handlePossibleHeaderBegin(buffer+1, dev)) {
+                        // assume data descriptor without signature
+                        dev->seek(dev->pos() + 8); // skip rest of the 
'data_descriptor'
+                    }
+                }
 
 // not needed any more
                 /*                // here we calculate the length of the file 
in the zip
@@ -749,9 +780,14 @@
                 if (buffer[0] == 'K' && buffer[1] == 3 && buffer[2] == 4) {
                     foundSignature = true;
                     dev->seek(dev->pos() - 4); // go back 4 bytes, so that the 
magic bytes can be found...
-                } else if (buffer[0] == 'P' || buffer[1] == 'P' || buffer[2] 
== 'P') {
-                    // We have another P character so we must go back a little 
to check if it is a magic
-                    dev->seek(dev->pos() - 3);
+                } else {
+                    for (int i = 0; i < 3; ++i) {
+                        if (buffer[i] == 'P') {
+                            // We have another P character so we must go back 
a little to check if it is a magic
+                            dev->seek(dev->pos() - 3 + i);
+                            break;
+                        }
+                    }
                 }
             }
         } else {

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to