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);