Hello community, here is the log from the commit of package ark for openSUSE:Factory checked in at 2015-06-04 09:57:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ark (Old) and /work/SRC/openSUSE:Factory/.ark.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ark" Changes: -------- --- /work/SRC/openSUSE:Factory/ark/ark.changes 2015-05-15 09:55:50.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ark.new/ark.changes 2015-06-04 09:57:52.000000000 +0200 @@ -1,0 +2,5 @@ +Sat May 30 13:29:37 UTC 2015 - [email protected] + +- Update + +------------------------------------------------------------------- Old: ---- ark-15.04.1.tar.xz New: ---- ark-15.04.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ark.spec ++++++ --- /var/tmp/diff_new_pack.bMCBAm/_old 2015-06-04 09:57:52.000000000 +0200 +++ /var/tmp/diff_new_pack.bMCBAm/_new 2015-06-04 09:57:52.000000000 +0200 @@ -17,7 +17,7 @@ Name: ark -Version: 15.04.1 +Version: 15.04.2 Release: 0 Summary: KDE Archiver Tool License: GPL-2.0+ ++++++ ark-15.04.1.tar.xz -> ark-15.04.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ark-15.04.1/plugins/libarchive/libarchivehandler.cpp new/ark-15.04.2/plugins/libarchive/libarchivehandler.cpp --- old/ark-15.04.1/plugins/libarchive/libarchivehandler.cpp 2015-04-12 08:31:28.000000000 +0200 +++ new/ark-15.04.2/plugins/libarchive/libarchivehandler.cpp 2015-05-20 23:33:45.000000000 +0200 @@ -36,6 +36,7 @@ #include <KDebug> #include <KLocale> +#include <KSaveFile> #include <kde_file.h> #include <QDateTime> @@ -45,6 +46,20 @@ #include <QList> #include <QStringList> +/** + * Custom QScopedPointer deleter for KSaveFile that inverts KSaveFile's + * semantics: while by default KSaveFile will call finalize() when being + * destroyed, this deleter will call abort() if the file is still open. + */ +struct KSaveFileSafeDeleter // KDE5: use QSaveFile, it has proper semantics. +{ + static inline void cleanup(KSaveFile *saveFile) { + if (saveFile->isOpen()) { + saveFile->abort(); + } + } +}; + struct LibArchiveInterface::ArchiveReadCustomDeleter { static inline void cleanup(struct archive *a) @@ -337,7 +352,6 @@ bool LibArchiveInterface::addFiles(const QStringList& files, const CompressionOptions& options) { const bool creatingNewFile = !QFileInfo(filename()).exists(); - const QString tempFilename = filename() + QLatin1String( ".arkWriting" ); const QString globalWorkDir = options.value(QLatin1String( "GlobalWorkDir" )).toString(); if (!globalWorkDir.isEmpty()) { @@ -370,6 +384,15 @@ } } + // |tempFile| needs to be created before |arch_writer| so that when we go + // out of scope in a `return false' case we ArchiveWriteCustomDeleter is + // called before KSaveFileSafeDeleter (ie. we call archive_write_close() + // before close()'ing the file descriptor). + QScopedPointer<KSaveFile, KSaveFileSafeDeleter> tempFile(new KSaveFile(filename())); + if (!tempFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) { + return false; + } + ArchiveWrite arch_writer(archive_write_new()); if (!(arch_writer.data())) { emit error(i18n("The archive writer could not be initialized.")); @@ -443,7 +466,7 @@ } } - ret = archive_write_open_filename(arch_writer.data(), QFile::encodeName(tempFilename)); + ret = archive_write_open_fd(arch_writer.data(), tempFile->handle()); if (ret != ARCHIVE_OK) { emit error(i18nc("@info", "Opening the archive for writing failed with the following error: <message>%1</message>", QLatin1String(archive_error_string(arch_writer.data())))); return false; @@ -456,7 +479,6 @@ success = writeFile(selectedFile, arch_writer.data()); if (!success) { - QFile::remove(tempFilename); return false; } @@ -481,7 +503,6 @@ arch_writer.data()); if (!success) { - QFile::remove(tempFilename); return false; } } @@ -508,28 +529,26 @@ copyData(arch_reader.data(), arch_writer.data(), false); } else { kDebug() << "Writing header failed with error code " << header_response; - QFile::remove(tempFilename); return false; } archive_entry_clear(entry); } - - //everything seems OK, so we remove the source file and replace it with - //the new one. - //TODO: do some extra checks to see if this is really OK - QFile::remove(filename()); } - QFile::rename(tempFilename, filename()); + // In the success case, we need to manually close the archive_writer before + // calling KSaveFile::finalize(), otherwise the latter will close() the + // file descriptor archive_writer is still working on. + // TODO: We need to abstract this code better so that we only deal with one + // object that manages both KSaveFile and ArchiveWriter. + archive_write_close(arch_writer.data()); + tempFile->finalize(); return true; } bool LibArchiveInterface::deleteFiles(const QVariantList& files) { - const QString tempFilename = filename() + QLatin1String( ".arkWriting" ); - ArchiveRead arch_reader(archive_read_new()); if (!(arch_reader.data())) { emit error(i18n("The archive reader could not be initialized.")); @@ -549,6 +568,15 @@ return false; } + // |tempFile| needs to be created before |arch_writer| so that when we go + // out of scope in a `return false' case we ArchiveWriteCustomDeleter is + // called before KSaveFileSafeDeleter (ie. we call archive_write_close() + // before close()'ing the file descriptor). + QScopedPointer<KSaveFile, KSaveFileSafeDeleter> tempFile(new KSaveFile(filename())); + if (!tempFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) { + return false; + } + ArchiveWrite arch_writer(archive_write_new()); if (!(arch_writer.data())) { emit error(i18n("The archive writer could not be initialized.")); @@ -589,7 +617,7 @@ return false; } - ret = archive_write_open_filename(arch_writer.data(), QFile::encodeName(tempFilename)); + ret = archive_write_open_fd(arch_writer.data(), tempFile->handle()); if (ret != ARCHIVE_OK) { emit error(i18nc("@info", "Opening the archive for writing failed with the following error: <message>%1</message>", QLatin1String(archive_error_string(arch_writer.data())))); return false; @@ -619,11 +647,13 @@ } } - //everything seems OK, so we remove the source file and replace it with - //the new one. - //TODO: do some extra checks to see if this is really OK - QFile::remove(filename()); - QFile::rename(tempFilename, filename()); + // In the success case, we need to manually close the archive_writer before + // calling KSaveFile::finalize(), otherwise the latter will close() the + // file descriptor archive_writer is still working on. + // TODO: We need to abstract this code better so that we only deal with one + // object that manages both KSaveFile and ArchiveWriter. + archive_write_close(arch_writer.data()); + tempFile->finalize(); return true; }
