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