Commit d3a7d7bb authored by Elvis Angelaccio's avatar Elvis Angelaccio

libzip: preserve permissions when extracting files

Summary:
The zip format reserves the 2 leftmost bytes of the extended file
attribute field (32 bits) for the UNIX permissions.
If the zip archive was crated with such metadata, we can just use the
libzip api to retrieve the extended file attribute and extract the
mode_t value from it.

BUG: 381499
FIXED-IN: 17.07.80

Test Plan: This fixes the 2 failing libzip test cases in ExtractTest::testPreservePermissions().

Reviewers: #ark, rthomsen

Subscribers: kde-utils-devel

Tags: #ark

Differential Revision: https://phabricator.kde.org/D6408
parent 4738a299
......@@ -21,7 +21,7 @@ configure_file(
kerfuffle_add_plugin(kerfuffle_libzip ${kerfuffle_libzip_SRCS})
target_link_libraries(kerfuffle_libzip ${LibZip_LIBRARIES})
target_link_libraries(kerfuffle_libzip KF5::KIOCore ${LibZip_LIBRARIES})
set(INSTALLED_LIBZIP_PLUGINS "${INSTALLED_LIBZIP_PLUGINS}kerfuffle_libzip;")
......
......@@ -27,6 +27,7 @@
#include "ark_debug.h"
#include "queries.h"
#include <KIO/Global>
#include <KLocalizedString>
#include <KPluginFactory>
......@@ -639,6 +640,33 @@ bool LibzipPlugin::extractEntry(zip_t *archive, const QString &entry, const QStr
sum += len;
}
const auto index = zip_name_locate(archive, entry.toUtf8(), ZIP_FL_ENC_GUESS);
if (index == -1) {
qCCritical(ARK) << "Could not locate entry:" << entry;
emit error(xi18n("Failed to locate entry: %1", entry));
return false;
}
zip_uint8_t opsys;
zip_uint32_t attributes;
if (zip_file_get_external_attributes(archive, index, ZIP_FL_UNCHANGED, &opsys, &attributes) == -1) {
qCCritical(ARK) << "Could not read external attributes for entry:" << entry;
emit error(xi18n("Failed to read metadata for entry: %1", entry));
return false;
}
// Inspired by fuse-zip source code: fuse-zip/lib/fileNode.cpp
switch (opsys) {
case ZIP_OPSYS_UNIX:
// Unix permissions are stored in the leftmost 16 bits of the external file attribute.
file.setPermissions(KIO::convertPermissions(attributes >> 16));
break;
default: // TODO: non-UNIX.
break;
}
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment