Browse Source

In system::unarchiveToDirectory(), set minimum file and dir permissions to 0644 and 0755.

tags/v2.3.0
Andrew Belt 1 year ago
parent
commit
a637fc7e0b
1 changed files with 27 additions and 11 deletions
  1. +27
    -11
      src/system.cpp

+ 27
- 11
src/system.cpp View File

@@ -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<uint8_t>* archiveData, const std::string& dirPath) {
static void unarchiveToDirectory(const std::string& archivePath, const std::vector<uint8_t>* 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;
}



Loading…
Cancel
Save