Hello community,

here is the log from the commit of package karchive for openSUSE:Factory 
checked in at 2019-05-21 10:24:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/karchive (Old)
 and      /work/SRC/openSUSE:Factory/.karchive.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "karchive"

Tue May 21 10:24:12 2019 rev:66 rq:703329 version:5.58.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/karchive/karchive.changes        2019-04-19 
21:22:11.667706901 +0200
+++ /work/SRC/openSUSE:Factory/.karchive.new.5148/karchive.changes      
2019-05-21 10:24:58.299561832 +0200
@@ -1,0 +2,24 @@
+Wed May 15 18:16:15 UTC 2019 - lbeltr...@kde.org
+
+- Update to 5.58.0
+  * New feature release
+  * For more details please see:
+  * https://www.kde.org/announcements/kde-frameworks-5.58.0.php
+- Changes since 5.57.0:
+  * KTar: Protect against negative longlink sizes
+  * Fix invalid memory write on malformed tar files
+  * Fix memory leak when reading some tar files
+  * Fix uninitialized memory use when reading malformed tar files
+  * Fix stack-buffer-overflow read on malformed files
+  * Fix null-dereference on malformed tar files
+  * autotests: Fix leak in karchivetest
+  * Install krcc.h header
+  * Fix double delete on broken files
+  * Disallow copy of KArchiveDirectoryPrivate and KArchivePrivate
+  * "Fix" KArchive::findOrCreate running out of stack on VERY LONG paths
+  * Introduce and use KArchiveDirectory::addEntryV2
+  * removeEntry can fail so it's good to know if it did
+  * Fix obviously wrong comment
+  * KZip: fix Heap-use-after-free in broken files
+
+-------------------------------------------------------------------

Old:
----
  karchive-5.57.0.tar.xz

New:
----
  karchive-5.58.0.tar.xz

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

Other differences:
------------------
++++++ karchive.spec ++++++
--- /var/tmp/diff_new_pack.xfouaH/_old  2019-05-21 10:24:58.747561660 +0200
+++ /var/tmp/diff_new_pack.xfouaH/_new  2019-05-21 10:24:58.751561659 +0200
@@ -17,13 +17,13 @@
 
 
 %define lname   libKF5Archive5
-%define _tar_path 5.57
+%define _tar_path 5.58
 # Full KF5 version (e.g. 5.33.0)
 %{!?_kf5_version: %global _kf5_version %{version}}
 # Last major and minor KF5 version (e.g. 5.33)
 %{!?_kf5_bugfix_version: %define _kf5_bugfix_version %(echo %{_kf5_version} | 
awk -F. '{print $1"."$2}')}
 Name:           karchive
-Version:        5.57.0
+Version:        5.58.0
 Release:        0
 Summary:        Qt 5 addon providing access to numerous types of archives
 License:        LGPL-2.1-or-later

++++++ karchive-5.57.0.tar.xz -> karchive-5.58.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/CMakeLists.txt 
new/karchive-5.58.0/CMakeLists.txt
--- old/karchive-5.57.0/CMakeLists.txt  2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/CMakeLists.txt  2019-05-05 00:41:47.000000000 +0200
@@ -1,10 +1,10 @@
 cmake_minimum_required(VERSION 3.5)
 
-set(KF5_VERSION "5.57.0") # handled by release scripts
+set(KF5_VERSION "5.58.0") # handled by release scripts
 project(KArchive VERSION ${KF5_VERSION})
 
 include(FeatureSummary)
-find_package(ECM 5.57.0  NO_MODULE)
+find_package(ECM 5.58.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/autotests/karchivetest.cpp 
new/karchive-5.58.0/autotests/karchivetest.cpp
--- old/karchive-5.57.0/autotests/karchivetest.cpp      2019-04-07 
09:16:42.000000000 +0200
+++ new/karchive-5.58.0/autotests/karchivetest.cpp      2019-05-05 
00:41:47.000000000 +0200
@@ -222,6 +222,7 @@
     dev->seek(4);
     contents = dev->read(1);
     QCOMPARE(contents, QByteArray("o"));
+    delete dev;
 
     const KArchiveEntry *e = dir->entry(QStringLiteral("mediumfile"));
     QVERIFY(e && e->isFile());
@@ -756,6 +757,24 @@
 
     QVERIFY(tar.close());
 }
+
+void KArchiveTest::testTarEmptyFileMissingDir()
+{
+    KTar tar(QFINDTESTDATA(QLatin1String("tar_emptyfile_missingdir.tar.gz")));
+    QVERIFY(tar.open(QIODevice::ReadOnly));
+
+    const KArchiveDirectory *dir = tar.directory();
+    QVERIFY(dir != nullptr);
+
+    const QStringList listing = recursiveListEntries(dir, QLatin1String(""), 
0);
+
+    QCOMPARE(listing[0], QString("mode=40777 path=dir type=dir"));
+    QCOMPARE(listing[1], QString("mode=40777 path=dir/foo type=dir"));
+    QCOMPARE(listing[2], QString("mode=644 path=dir/foo/file type=file 
size=0"));
+    QCOMPARE(listing.count(), 3);
+
+    QVERIFY(tar.close());
+}
 
 void KArchiveTest::testTarRootDir() // bug 309463
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/autotests/karchivetest.h 
new/karchive-5.58.0/autotests/karchivetest.h
--- old/karchive-5.57.0/autotests/karchivetest.h        2019-04-07 
09:16:42.000000000 +0200
+++ new/karchive-5.58.0/autotests/karchivetest.h        2019-05-05 
00:41:47.000000000 +0200
@@ -74,6 +74,7 @@
     void testTarGlobalHeader();
     void testTarPrefix();
     void testTarDirectoryForgotten();
+    void testTarEmptyFileMissingDir();
     void testTarRootDir();
     void testTarDirectoryTwice();
     void testTarIgnoreRelativePathOutsideArchive();
Binary files old/karchive-5.57.0/autotests/tar_emptyfile_missingdir.tar.gz and 
new/karchive-5.58.0/autotests/tar_emptyfile_missingdir.tar.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/CMakeLists.txt 
new/karchive-5.58.0/src/CMakeLists.txt
--- old/karchive-5.57.0/src/CMakeLists.txt      2019-04-07 09:16:42.000000000 
+0200
+++ new/karchive-5.58.0/src/CMakeLists.txt      2019-05-05 00:41:47.000000000 
+0200
@@ -74,6 +74,7 @@
     KCompressionDevice
     KFilterBase
     KFilterDev
+    KRcc
     KTar
     KZip
     KZipFileEntry
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/k7zip.cpp 
new/karchive-5.58.0/src/k7zip.cpp
--- old/karchive-5.57.0/src/k7zip.cpp   2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/src/k7zip.cpp   2019-05-05 00:41:47.000000000 +0200
@@ -2893,7 +2893,8 @@
     const KArchiveEntry *entry = parentDir->entry(fileName);
     if (!entry) {
         K7ZipFileEntry *e = new K7ZipFileEntry(this, fileName, perm, mtime, 
user, group, QString()/*symlink*/, d->outData.size(), 0 /*unknown yet*/, 
d->outData);
-        parentDir->addEntry(e);
+        if (!parentDir->addEntryV2(e))
+            return false;
         d->m_entryList << e;
         d->m_currentFile = e;
     } else {
@@ -2972,7 +2973,9 @@
     K7ZipFileEntry *e = new K7ZipFileEntry(this, fileName, perm, mtime, user, 
group, target, 0, 0, nullptr);
     d->outData.append(encodedTarget);
 
-    parentDir->addEntry(e);
+    if (!parentDir->addEntryV2(e))
+        return false;
+
     d->m_entryList << e;
 
     return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/karchive.cpp 
new/karchive-5.58.0/src/karchive.cpp
--- old/karchive-5.57.0/src/karchive.cpp        2019-04-07 09:16:42.000000000 
+0200
+++ new/karchive-5.58.0/src/karchive.cpp        2019-05-05 00:41:47.000000000 
+0200
@@ -51,11 +51,76 @@
 #endif // Q_OS_WIN
 
 ////////////////////////////////////////////////////////////////////////
+/////////////////// KArchiveDirectoryPrivate ///////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+class KArchiveDirectoryPrivate
+{
+public:
+    KArchiveDirectoryPrivate(KArchiveDirectory *parent) : q(parent)
+    {
+    }
+
+    ~KArchiveDirectoryPrivate()
+    {
+        qDeleteAll(entries);
+    }
+
+    KArchiveDirectoryPrivate(const KArchiveDirectoryPrivate &) = delete;
+    KArchiveDirectoryPrivate &operator=(const KArchiveDirectoryPrivate &) = 
delete;
+
+    static KArchiveDirectoryPrivate *get(KArchiveDirectory *directory)
+    {
+        return directory->d;
+    }
+
+    // Returns in containingDirectory the directory that actually contains the 
returned entry
+    const KArchiveEntry *entry(const QString &_name, KArchiveDirectory 
**containingDirectory) const
+    {
+        *containingDirectory = q;
+
+        QString name = QDir::cleanPath(_name);
+        int pos = name.indexOf(QLatin1Char('/'));
+        if (pos == 0) { // ouch absolute path (see also KArchive::findOrCreate)
+            if (name.length() > 1) {
+                name = name.mid(1);   // remove leading slash
+                pos = name.indexOf(QLatin1Char('/'));   // look again
+            } else { // "/"
+                return q;
+            }
+        }
+        // trailing slash ? -> remove
+        if (pos != -1 && pos == name.length() - 1) {
+            name = name.left(pos);
+            pos = name.indexOf(QLatin1Char('/'));   // look again
+        }
+        if (pos != -1) {
+            const QString left = name.left(pos);
+            const QString right = name.mid(pos + 1);
+
+            //qCDebug(KArchiveLog) << "left=" << left << "right=" << right;
+
+            KArchiveEntry *e = entries.value(left);
+            if (!e || !e->isDirectory()) {
+                return nullptr;
+            }
+            *containingDirectory = static_cast<KArchiveDirectory *>(e);
+            return (*containingDirectory)->d->entry(right, 
containingDirectory);
+        }
+
+        return entries.value(name);
+    }
+
+    KArchiveDirectory *q;
+    QHash<QString, KArchiveEntry *> entries;
+};
+
+////////////////////////////////////////////////////////////////////////
 /////////////////////////// KArchive ///////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 
 KArchive::KArchive(const QString &fileName)
-    : d(new KArchivePrivate)
+    : d(new KArchivePrivate(this))
 {
     if (fileName.isEmpty()) {
         qCWarning(KArchiveLog) << "KArchive: No file name specified";
@@ -66,7 +131,7 @@
 }
 
 KArchive::KArchive(QIODevice *dev)
-    : d(new KArchivePrivate)
+    : d(new KArchivePrivate(this))
 {
     if (!dev) {
         qCWarning(KArchiveLog) << "KArchive: Null device specified";
@@ -446,10 +511,23 @@
 
 KArchiveDirectory *KArchive::findOrCreate(const QString &path)
 {
+    return d->findOrCreate(path, 0 /*recursionCounter*/);
+}
+
+KArchiveDirectory *KArchivePrivate::findOrCreate(const QString &path, int 
recursionCounter)
+{
+    // Check we're not in a path that is ultra deep, this is most probably 
fine since PATH_MAX on Linux
+    // is defined as 4096, so even on /a/a/a/a/a/a 2500 recursions puts us 
over that limit
+    // an ultra deep recursion will makes us crash due to not enough stack. 
Tests show that 1MB stack
+    // (default on Linux seems to be 8MB) gives us up to around 4000 recursions
+    if (recursionCounter > 2500) {
+        qCWarning(KArchiveLog) << "path recursion limit exceeded, bailing out";
+        return nullptr;
+    }
     //qCDebug(KArchiveLog) << path;
     if (path.isEmpty() || path == QLatin1String("/") || path == 
QLatin1String(".")) { // root dir => found
         //qCDebug(KArchiveLog) << "returning rootdir";
-        return rootDir();
+        return q->rootDir();
     }
     // Important note : for tar files containing absolute paths
     // (i.e. beginning with "/"), this means the leading "/" will
@@ -458,23 +536,24 @@
     // See also KArchiveDirectory::entry().
 
     // Already created ? => found
-    const KArchiveEntry *ent = rootDir()->entry(path);
-    if (ent) {
-        if (ent->isDirectory())
+    KArchiveDirectory *existingEntryParentDirectory;
+    const KArchiveEntry *existingEntry = 
KArchiveDirectoryPrivate::get(q->rootDir())->entry(path, 
&existingEntryParentDirectory);
+    if (existingEntry) {
+        if (existingEntry->isDirectory())
             //qCDebug(KArchiveLog) << "found it";
         {
-            const KArchiveDirectory *dir = static_cast<const KArchiveDirectory 
*>(ent);
+            const KArchiveDirectory *dir = static_cast<const KArchiveDirectory 
*>(existingEntry);
             return const_cast<KArchiveDirectory *>(dir);
         } else {
-            const KArchiveFile *file = static_cast<const KArchiveFile *>(ent);
+            const KArchiveFile *file = static_cast<const KArchiveFile 
*>(existingEntry);
             if (file->size() > 0) {
                 qCWarning(KArchiveLog) << path << "is normal file, but there 
are file paths in the archive assuming it is a directory, bailing out";
                 return nullptr;
             }
 
             qCDebug(KArchiveLog) << path << " is an empty file, assuming it is 
actually a directory and replacing";
-            KArchiveEntry *myEntry = const_cast<KArchiveEntry*>(ent);
-            rootDir()->removeEntry(myEntry);
+            KArchiveEntry *myEntry = const_cast<KArchiveEntry*>(existingEntry);
+            existingEntryParentDirectory->removeEntry(myEntry);
             delete myEntry;
         }
     }
@@ -484,12 +563,12 @@
     KArchiveDirectory *parent;
     QString dirname;
     if (pos == -1) { // no more slash => create in root dir
-        parent =  rootDir();
+        parent =  q->rootDir();
         dirname = path;
     } else {
         QString left = path.left(pos);
         dirname = path.mid(pos + 1);
-        parent = findOrCreate(left);   // recursive call... until we find an 
existing dir.
+        parent = findOrCreate(left, recursionCounter + 1);   // recursive 
call... until we find an existing dir.
     }
 
     if (!parent) {
@@ -498,11 +577,14 @@
 
     //qCDebug(KArchiveLog) << "found parent " << parent->name() << " adding " 
<< dirname << " to ensure " << path;
     // Found -> add the missing piece
-    KArchiveDirectory *e = new KArchiveDirectory(this, dirname, 
d->rootDir->permissions(),
-                                                 d->rootDir->date(), 
d->rootDir->user(),
-                                                 d->rootDir->group(), 
QString());
-    parent->addEntry(e);
-    return e; // now a directory to <path> exists
+    KArchiveDirectory *e = new KArchiveDirectory(q, dirname, 
rootDir->permissions(),
+                                                 rootDir->date(), 
rootDir->user(),
+                                                 rootDir->group(), QString());
+    if (parent->addEntryV2(e)) {
+        return e; // now a directory to <path> exists
+    } else {
+        return nullptr;
+    }
 }
 
 void KArchive::setDevice(QIODevice *dev)
@@ -517,6 +599,7 @@
 void KArchive::setRootDir(KArchiveDirectory *rootDir)
 {
     Q_ASSERT(!d->rootDir);   // Call setRootDir only once during parsing 
please ;)
+    delete d->rootDir;       // but if it happens, don't leak
     d->rootDir = rootDir;
 }
 
@@ -764,22 +847,12 @@
 //////////////////////// KArchiveDirectory /////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 
-class KArchiveDirectoryPrivate
-{
-public:
-    ~KArchiveDirectoryPrivate()
-    {
-        qDeleteAll(entries);
-    }
-    QHash<QString, KArchiveEntry *> entries;
-};
-
 KArchiveDirectory::KArchiveDirectory(KArchive *t, const QString &name, int 
access,
                                      const QDateTime &date,
                                      const QString &user, const QString &group,
                                      const QString &symlink)
     : KArchiveEntry(t, name, access, date, user, group, symlink)
-    , d(new KArchiveDirectoryPrivate)
+    , d(new KArchiveDirectoryPrivate(this))
 {
 }
 
@@ -795,35 +868,8 @@
 
 const KArchiveEntry *KArchiveDirectory::entry(const QString &_name) const
 {
-    QString name = QDir::cleanPath(_name);
-    int pos = name.indexOf(QLatin1Char('/'));
-    if (pos == 0) { // ouch absolute path (see also KArchive::findOrCreate)
-        if (name.length() > 1) {
-            name = name.mid(1);   // remove leading slash
-            pos = name.indexOf(QLatin1Char('/'));   // look again
-        } else { // "/"
-            return this;
-        }
-    }
-    // trailing slash ? -> remove
-    if (pos != -1 && pos == name.length() - 1) {
-        name = name.left(pos);
-        pos = name.indexOf(QLatin1Char('/'));   // look again
-    }
-    if (pos != -1) {
-        const QString left = name.left(pos);
-        const QString right = name.mid(pos + 1);
-
-        //qCDebug(KArchiveLog) << "left=" << left << "right=" << right;
-
-        const KArchiveEntry *e = d->entries.value(left);
-        if (!e || !e->isDirectory()) {
-            return nullptr;
-        }
-        return static_cast<const KArchiveDirectory *>(e)->entry(right);
-    }
-
-    return d->entries.value(name);
+    KArchiveDirectory *dummy;
+    return d->entry(_name, &dummy);
 }
 
 const KArchiveFile *KArchiveDirectory::file(const QString &name) const
@@ -837,13 +883,19 @@
 
 void KArchiveDirectory::addEntry(KArchiveEntry *entry)
 {
+    addEntryV2(entry);
+}
+
+bool KArchiveDirectory::addEntryV2(KArchiveEntry *entry)
+{
     if (d->entries.value(entry->name())) {
         qCWarning(KArchiveLog) << "directory " << name()
                     << "has entry" << entry->name() << "already";
         delete entry;
-        return;
+        return false;
     }
     d->entries.insert(entry->name(), entry);
+    return true;
 }
 
 void KArchiveDirectory::removeEntry(KArchiveEntry *entry)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/karchive.h 
new/karchive-5.58.0/src/karchive.h
--- old/karchive-5.57.0/src/karchive.h  2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/src/karchive.h  2019-05-05 00:41:47.000000000 +0200
@@ -396,6 +396,7 @@
 protected:
     virtual void virtual_hook(int id, void *data);
 private:
+    friend class KArchivePrivate;
     KArchivePrivate *const d;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/karchive_p.h 
new/karchive-5.58.0/src/karchive_p.h
--- old/karchive-5.57.0/src/karchive_p.h        2019-04-07 09:16:42.000000000 
+0200
+++ new/karchive-5.58.0/src/karchive_p.h        2019-05-05 00:41:47.000000000 
+0200
@@ -29,8 +29,9 @@
     Q_DECLARE_TR_FUNCTIONS(KArchivePrivate)
 
 public:
-    KArchivePrivate()
-        : rootDir(nullptr)
+    KArchivePrivate(KArchive *parent)
+        : q(parent)
+        , rootDir(nullptr)
         , saveFile(nullptr)
         , dev(nullptr)
         , fileName()
@@ -43,10 +44,17 @@
         delete saveFile;
         delete rootDir;
     }
+
+    KArchivePrivate(const KArchivePrivate &) = delete;
+    KArchivePrivate &operator=(const KArchivePrivate &) = delete;
+
     void abortWriting();
 
     static QDateTime time_tToDateTime(uint time_t);
 
+    KArchiveDirectory *findOrCreate(const QString &path, int recursionCounter);
+
+    KArchive *q;
     KArchiveDirectory *rootDir;
     QSaveFile *saveFile;
     QIODevice *dev;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/karchivedirectory.h 
new/karchive-5.58.0/src/karchivedirectory.h
--- old/karchive-5.57.0/src/karchivedirectory.h 2019-04-07 09:16:42.000000000 
+0200
+++ new/karchive-5.58.0/src/karchivedirectory.h 2019-05-05 00:41:47.000000000 
+0200
@@ -99,8 +99,15 @@
     /**
      * @internal
      * Adds a new entry to the directory.
+     * @return whether the entry was added or not. Non added entries are 
deleted
      */
-    void removeEntry(KArchiveEntry *);
+    bool addEntryV2(KArchiveEntry *); // KF6 TODO: merge with the one above
+
+    /**
+     * @internal
+     * Removes an entry from the directory.
+     */
+    void removeEntry(KArchiveEntry *); // KF6 TODO: return bool since it can 
fail
 
     /**
      * Checks whether this entry is a directory.
@@ -120,6 +127,7 @@
 protected:
     void virtual_hook(int id, void *data) override;
 private:
+    friend class KArchiveDirectoryPrivate;
     KArchiveDirectoryPrivate *const d;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/krcc.cpp 
new/karchive-5.58.0/src/krcc.cpp
--- old/karchive-5.57.0/src/krcc.cpp    2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/src/krcc.cpp    2019-05-05 00:41:47.000000000 +0200
@@ -154,8 +154,9 @@
         } else {
             KArchiveDirectory *entry = new KArchiveDirectory(q, fileName, 
0555, info.lastModified(),
                                                              
parentDir->user(), parentDir->group(), /*symlink*/ QString());
-            parentDir->addEntry(entry);
-            createEntries(QDir(entryPath), entry, q);
+            if (parentDir->addEntryV2(entry)) {
+                createEntries(QDir(entryPath), entry, q);
+            }
         }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/ktar.cpp 
new/karchive-5.58.0/src/ktar.cpp
--- old/karchive-5.57.0/src/ktar.cpp    2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/src/ktar.cpp    2019-05-05 00:41:47.000000000 +0200
@@ -238,6 +238,14 @@
     qint64 size = QByteArray(buffer + 0x7c, 12).trimmed().toLongLong(nullptr, 
8 /*octal*/);
 
     size--;    // ignore trailing null
+    if (size > std::numeric_limits<int>::max()) {
+        qCWarning(KArchiveLog) << "Failed to allocate memory for longlink of 
size" << size;
+        return false;
+    }
+    if (size < 0) {
+        qCWarning(KArchiveLog) << "Invalid longlink size" << size;
+        return false;
+    }
     longlink.resize(size);
     qint64 offset = 0;
     while (size > 0) {
@@ -274,15 +282,16 @@
         if (strcmp(buffer, "././@LongLink") == 0) {
             char typeflag = buffer[0x9c];
             QByteArray longlink;
-            readLonglink(buffer, longlink);
-            switch (typeflag) {
-            case 'L':
-                name = QFile::decodeName(longlink.constData());
-                break;
-            case 'K':
-                symlink = QFile::decodeName(longlink.constData());
-                break;
-            }/*end switch*/
+            if (readLonglink(buffer, longlink)) {
+                switch (typeflag) {
+                case 'L':
+                    name = QFile::decodeName(longlink.constData());
+                    break;
+                case 'K':
+                    symlink = QFile::decodeName(longlink.constData());
+                    break;
+                }/*end switch*/
+            }
         } else {
             break;
         }/*end if*/
@@ -421,8 +430,13 @@
             int access = strtol(p, &dummy, 8);
 
             // read user and group
-            QString user = QString::fromLocal8Bit(buffer + 0x109);
-            QString group = QString::fromLocal8Bit(buffer + 0x129);
+            const int maxUserGroupLength = 32;
+            const char *userStart = buffer + 0x109;
+            const int userLen = qstrnlen(userStart, maxUserGroupLength);
+            const QString user = QString::fromLocal8Bit(userStart, userLen);
+            const char *groupStart = buffer + 0x129;
+            const int groupLen = qstrnlen(groupStart, maxUserGroupLength);
+            const QString group = QString::fromLocal8Bit(groupStart, groupLen);
 
             // read time
             buffer[0x93] = 0;
@@ -512,7 +526,12 @@
                 QString path = QDir::cleanPath(name.left(pos));
                 // Ensure container directory exists, create otherwise
                 KArchiveDirectory *d = findOrCreate(path);
-                d->addEntry(e);
+                if (d) {
+                    d->addEntry(e);
+                } else {
+                    delete e;
+                    return false;
+                }
             }
         } else {
             //qCDebug(KArchiveLog) << "Terminating. Read " << n << " bytes, 
first one is " << buffer[0];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/karchive-5.57.0/src/kzip.cpp 
new/karchive-5.58.0/src/kzip.cpp
--- old/karchive-5.57.0/src/kzip.cpp    2019-04-07 09:16:42.000000000 +0200
+++ new/karchive-5.58.0/src/kzip.cpp    2019-05-05 00:41:47.000000000 +0200
@@ -714,6 +714,10 @@
                 entryName = name.mid(pos + 1);
             }
             Q_ASSERT(!entryName.isEmpty());
+            if (entryName.isEmpty()) {
+                setErrorString(tr("Invalid ZIP file, found empty entry name"));
+                return false;
+            }
 
             KArchiveEntry *entry;
             if (isdir) {
@@ -1108,7 +1112,9 @@
                                          0 /*size unknown yet*/, 
d->m_compression, 0 /*csize unknown yet*/);
     e->setHeaderStart(device()->pos());
     //qCDebug(KArchiveLog) << "wrote file start: " << e->position() << " name: 
" << name;
-    parentDir->addEntry(e);
+    if (!parentDir->addEntryV2(e)) {
+        return false;
+    }
 
     d->m_currentFile = e;
     d->m_fileList.append(e);


Reply via email to