| @@ -33,6 +33,9 @@ | |||||
| #include <archive.h> | #include <archive.h> | ||||
| #include <archive_entry.h> | #include <archive_entry.h> | ||||
| #if defined ARCH_MAC | |||||
| #include <locale.h> | |||||
| #endif | |||||
| #include <system.hpp> | #include <system.hpp> | ||||
| #include <string.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) { | 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 | // Based on minitar.c extract() in libarchive examples | ||||
| int r; | int r; | ||||
| // Open archive for reading | // Open archive for reading | ||||
| struct archive* a = archive_read_new(); | struct archive* a = archive_read_new(); | ||||
| if (!a) | |||||
| throw Exception("Unarchiver could not be created"); | |||||
| DEFER({archive_read_free(a);}); | DEFER({archive_read_free(a);}); | ||||
| archive_read_support_filter_zstd(a); | archive_read_support_filter_zstd(a); | ||||
| // archive_read_support_filter_all(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 | // Convert relative pathname to absolute based on dirPath | ||||
| std::string entryPath = archive_entry_pathname(entry); | std::string entryPath = archive_entry_pathname(entry); | ||||
| DEBUG("entryPath: %s", entryPath.c_str()); | |||||
| if (!fs::u8path(entryPath).is_relative()) | if (!fs::u8path(entryPath).is_relative()) | ||||
| throw Exception("Unarchiver does not support absolute tar paths: %s", entryPath.c_str()); | throw Exception("Unarchiver does not support absolute tar paths: %s", entryPath.c_str()); | ||||
| entryPath = (fs::u8path(dirPath) / fs::u8path(entryPath)).generic_u8string(); | entryPath = (fs::u8path(dirPath) / fs::u8path(entryPath)).generic_u8string(); | ||||