Browse Source

Set thread locale to en_US.UTF-8 for system::unarchiveToDirectory() on Mac, which fixes libarchive error when a non-ASCII filename is extracted.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
420e781fa7
1 changed files with 17 additions and 0 deletions
  1. +17
    -0
      src/system.cpp

+ 17
- 0
src/system.cpp View File

@@ -33,6 +33,9 @@

#include <archive.h>
#include <archive_entry.h>
#if defined ARCH_MAC
#include <locale.h>
#endif

#include <system.hpp>
#include <string.hpp>
@@ -457,11 +460,24 @@ static la_ssize_t archiveReadVectorCallback(struct archive *a, void* client_data
}

static void unarchiveToDirectory(const std::string& archivePath, const std::vector<uint8_t>* archiveData, const std::string& dirPath) {
#if defined ARCH_MAC
// libarchive depends on locale so set thread
// 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);
freelocale(loc);
DEFER({
uselocale(oldLoc);
});
#endif

// Based on minitar.c extract() in libarchive examples
int r;

// Open archive for reading
struct archive* a = archive_read_new();
if (!a)
throw Exception("Unarchiver could not be created");
DEFER({archive_read_free(a);});
archive_read_support_filter_zstd(a);
// archive_read_support_filter_all(a);
@@ -505,6 +521,7 @@ static void unarchiveToDirectory(const std::string& archivePath, const std::vect

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


Loading…
Cancel
Save