From a637fc7e0bf29e8d8e09a0282445fab36ce719dd Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 28 Jan 2023 20:03:00 -0500 Subject: [PATCH] In system::unarchiveToDirectory(), set minimum file and dir permissions to 0644 and 0755. --- src/system.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 2a182fc1..05dbadae 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -499,9 +499,9 @@ static la_ssize_t archiveReadVectorCallback(struct archive *a, void* client_data return len; } -static void unarchiveToDirectory(const std::string& archivePath, const std::vector* archiveData, const std::string& dirPath) { +static void unarchiveToDirectory(const std::string& archivePath, const std::vector* archiveData, const std::string& dirPathStr) { #if defined ARCH_MAC - // libarchive depends on locale so set thread + // libarchive depends on locale so set thread locale // If locale is not found, returns NULL which resets thread to global locale locale_t loc = newlocale(LC_CTYPE_MASK, "en_US.UTF-8", NULL); locale_t oldLoc = uselocale(loc); @@ -511,6 +511,8 @@ static void unarchiveToDirectory(const std::string& archivePath, const std::vect }); #endif + fs::path dirPath = fs::u8path(dirPathStr); + // Based on minitar.c extract() in libarchive examples int r; @@ -564,20 +566,34 @@ static void unarchiveToDirectory(const std::string& archivePath, const std::vect throw Exception("Unarchiver could not read entry from archive: %s", archive_error_string(a)); // Convert relative pathname to absolute based on dirPath - std::string entryPath = archive_entry_pathname(entry); - // DEBUG("entryPath: %s", entryPath.c_str()); - if (!fs::u8path(entryPath).is_relative()) - throw Exception("Unarchiver does not support absolute tar paths: %s", entryPath.c_str()); - entryPath = (fs::u8path(dirPath) / fs::u8path(entryPath)).generic_u8string(); + fs::path entryPath = fs::u8path(archive_entry_pathname(entry)); + // DEBUG("entryPath: %s", entryPath.generic_u8string().c_str()); + if (!entryPath.is_relative()) + throw Exception("Unarchiver does not support absolute tar paths: %s", entryPath.u8string().c_str()); + + entryPath = dirPath / entryPath; #if defined ARCH_WIN - archive_entry_copy_pathname_w(entry, string::UTF8toUTF16(entryPath).c_str()); + archive_entry_copy_pathname_w(entry, string::UTF8toUTF16(entryPath.u8string()).c_str()); #else - archive_entry_set_pathname(entry, entryPath.c_str()); + archive_entry_set_pathname(entry, entryPath.u8string().c_str()); #endif + mode_t mode = archive_entry_mode(entry); + mode_t filetype = archive_entry_filetype(entry); + int64_t size = archive_entry_size(entry); + + // Force minimum modes + if (filetype == AE_IFREG) { + mode |= 0644; + } + else if (filetype == AE_IFDIR) { + mode |= 0755; + } + archive_entry_set_mode(entry, mode); + // Delete zero-byte files - if (archive_entry_filetype(entry) == AE_IFREG && archive_entry_size(entry) == 0) { - remove(entryPath); + if (filetype == AE_IFREG && size == 0) { + remove(entryPath.generic_u8string()); continue; }