Loading libziparchive/unzip.cpp +33 −19 Original line number Diff line number Diff line Loading @@ -15,11 +15,11 @@ */ #include <errno.h> #include <error.h> #include <fcntl.h> #include <fnmatch.h> #include <getopt.h> #include <inttypes.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> Loading Loading @@ -64,6 +64,20 @@ static uint64_t total_uncompressed_length = 0; static uint64_t total_compressed_length = 0; static size_t file_count = 0; static const char* g_progname; static void die(int error, const char* fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", g_progname); vfprintf(stderr, fmt, ap); if (error != 0) fprintf(stderr, ": %s", strerror(error)); fprintf(stderr, "\n"); va_end(ap); exit(1); } static bool ShouldInclude(const std::string& name) { // Explicitly excluded? if (!excludes.empty()) { Loading Loading @@ -155,7 +169,7 @@ static bool PromptOverwrite(const std::string& dst) { char* line = nullptr; size_t n; if (getline(&line, &n, stdin) == -1) { error(1, 0, "(EOF/read error; assuming [N]one...)"); die(0, "(EOF/read error; assuming [N]one...)"); overwrite_mode = kNever; return false; } Loading Loading @@ -183,10 +197,10 @@ static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri uint8_t* buffer = new uint8_t[entry.uncompressed_length]; int err = ExtractToMemory(zah, &entry, buffer, entry.uncompressed_length); if (err < 0) { error(1, 0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err)); die(0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err)); } if (!android::base::WriteFully(1, buffer, entry.uncompressed_length)) { error(1, errno, "failed to write %s to stdout", name.c_str()); die(errno, "failed to write %s to stdout", name.c_str()); } delete[] buffer; } Loading @@ -194,7 +208,7 @@ static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) { // Bad filename? if (StartsWith(name, "/") || StartsWith(name, "../") || name.find("/../") != std::string::npos) { error(1, 0, "bad filename %s", name.c_str()); die(0, "bad filename %s", name.c_str()); } // Where are we actually extracting to (for human-readable output)? Loading @@ -207,7 +221,7 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& // Ensure the directory hierarchy exists. if (!MakeDirectoryHierarchy(android::base::Dirname(name))) { error(1, errno, "couldn't create directory hierarchy for %s", dst.c_str()); die(errno, "couldn't create directory hierarchy for %s", dst.c_str()); } // An entry in a zip file can just be a directory itself. Loading @@ -218,7 +232,7 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& struct stat sb; if (stat(name.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) return; } error(1, errno, "couldn't extract directory %s", dst.c_str()); die(errno, "couldn't extract directory %s", dst.c_str()); } return; } Loading @@ -231,12 +245,12 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& // Either overwrite_mode is kAlways or the user consented to this specific case. fd = open(name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, entry.unix_mode); } if (fd == -1) error(1, errno, "couldn't create file %s", dst.c_str()); if (fd == -1) die(errno, "couldn't create file %s", dst.c_str()); // Actually extract into the file. if (!flag_q) printf(" inflating: %s\n", dst.c_str()); int err = ExtractEntryToFile(zah, &entry, fd); if (err < 0) error(1, 0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err)); if (err < 0) die(0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err)); close(fd); } Loading Loading @@ -345,7 +359,7 @@ static void ProcessAll(ZipArchiveHandle zah) { void* cookie; int err = StartIteration(zah, &cookie); if (err != 0) { error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); die(0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); } ZipEntry entry; Loading @@ -354,7 +368,7 @@ static void ProcessAll(ZipArchiveHandle zah) { if (ShouldInclude(name)) ProcessOne(zah, entry, name); } if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); if (err < -1) die(0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); EndIteration(cookie); MaybeShowFooter(); Loading Loading @@ -420,14 +434,14 @@ static void HandleCommonOption(int opt) { int main(int argc, char* argv[]) { // Who am I, and what am I doing? const char* base = basename(argv[0]); if (!strcmp(base, "ziptool") && argc > 1) return main(argc - 1, argv + 1); if (!strcmp(base, "unzip")) { g_progname = basename(argv[0]); if (!strcmp(g_progname, "ziptool") && argc > 1) return main(argc - 1, argv + 1); if (!strcmp(g_progname, "unzip")) { role = kUnzip; } else if (!strcmp(base, "zipinfo")) { } else if (!strcmp(g_progname, "zipinfo")) { role = kZipinfo; } else { error(1, 0, "run as ziptool with unzip or zipinfo as the first argument, or symlink"); die(0, "run as ziptool with unzip or zipinfo as the first argument, or symlink"); } static const struct option opts[] = { Loading Loading @@ -484,19 +498,19 @@ int main(int argc, char* argv[]) { } } if (!archive_name) error(1, 0, "missing archive filename"); if (!archive_name) die(0, "missing archive filename"); // We can't support "-" to unzip from stdin because libziparchive relies on mmap. ZipArchiveHandle zah; int32_t err; if ((err = OpenArchive(archive_name, &zah)) != 0) { error(1, 0, "couldn't open %s: %s", archive_name, ErrorCodeString(err)); die(0, "couldn't open %s: %s", archive_name, ErrorCodeString(err)); } // Implement -d by changing into that directory. // We'll create implicit directories based on paths in the zip file, but we // require that the -d directory already exists. if (flag_d && chdir(flag_d) == -1) error(1, errno, "couldn't chdir to %s", flag_d); if (flag_d && chdir(flag_d) == -1) die(errno, "couldn't chdir to %s", flag_d); ProcessAll(zah); Loading Loading
libziparchive/unzip.cpp +33 −19 Original line number Diff line number Diff line Loading @@ -15,11 +15,11 @@ */ #include <errno.h> #include <error.h> #include <fcntl.h> #include <fnmatch.h> #include <getopt.h> #include <inttypes.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> Loading Loading @@ -64,6 +64,20 @@ static uint64_t total_uncompressed_length = 0; static uint64_t total_compressed_length = 0; static size_t file_count = 0; static const char* g_progname; static void die(int error, const char* fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", g_progname); vfprintf(stderr, fmt, ap); if (error != 0) fprintf(stderr, ": %s", strerror(error)); fprintf(stderr, "\n"); va_end(ap); exit(1); } static bool ShouldInclude(const std::string& name) { // Explicitly excluded? if (!excludes.empty()) { Loading Loading @@ -155,7 +169,7 @@ static bool PromptOverwrite(const std::string& dst) { char* line = nullptr; size_t n; if (getline(&line, &n, stdin) == -1) { error(1, 0, "(EOF/read error; assuming [N]one...)"); die(0, "(EOF/read error; assuming [N]one...)"); overwrite_mode = kNever; return false; } Loading Loading @@ -183,10 +197,10 @@ static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri uint8_t* buffer = new uint8_t[entry.uncompressed_length]; int err = ExtractToMemory(zah, &entry, buffer, entry.uncompressed_length); if (err < 0) { error(1, 0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err)); die(0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err)); } if (!android::base::WriteFully(1, buffer, entry.uncompressed_length)) { error(1, errno, "failed to write %s to stdout", name.c_str()); die(errno, "failed to write %s to stdout", name.c_str()); } delete[] buffer; } Loading @@ -194,7 +208,7 @@ static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) { // Bad filename? if (StartsWith(name, "/") || StartsWith(name, "../") || name.find("/../") != std::string::npos) { error(1, 0, "bad filename %s", name.c_str()); die(0, "bad filename %s", name.c_str()); } // Where are we actually extracting to (for human-readable output)? Loading @@ -207,7 +221,7 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& // Ensure the directory hierarchy exists. if (!MakeDirectoryHierarchy(android::base::Dirname(name))) { error(1, errno, "couldn't create directory hierarchy for %s", dst.c_str()); die(errno, "couldn't create directory hierarchy for %s", dst.c_str()); } // An entry in a zip file can just be a directory itself. Loading @@ -218,7 +232,7 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& struct stat sb; if (stat(name.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) return; } error(1, errno, "couldn't extract directory %s", dst.c_str()); die(errno, "couldn't extract directory %s", dst.c_str()); } return; } Loading @@ -231,12 +245,12 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& // Either overwrite_mode is kAlways or the user consented to this specific case. fd = open(name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, entry.unix_mode); } if (fd == -1) error(1, errno, "couldn't create file %s", dst.c_str()); if (fd == -1) die(errno, "couldn't create file %s", dst.c_str()); // Actually extract into the file. if (!flag_q) printf(" inflating: %s\n", dst.c_str()); int err = ExtractEntryToFile(zah, &entry, fd); if (err < 0) error(1, 0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err)); if (err < 0) die(0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err)); close(fd); } Loading Loading @@ -345,7 +359,7 @@ static void ProcessAll(ZipArchiveHandle zah) { void* cookie; int err = StartIteration(zah, &cookie); if (err != 0) { error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); die(0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); } ZipEntry entry; Loading @@ -354,7 +368,7 @@ static void ProcessAll(ZipArchiveHandle zah) { if (ShouldInclude(name)) ProcessOne(zah, entry, name); } if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); if (err < -1) die(0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); EndIteration(cookie); MaybeShowFooter(); Loading Loading @@ -420,14 +434,14 @@ static void HandleCommonOption(int opt) { int main(int argc, char* argv[]) { // Who am I, and what am I doing? const char* base = basename(argv[0]); if (!strcmp(base, "ziptool") && argc > 1) return main(argc - 1, argv + 1); if (!strcmp(base, "unzip")) { g_progname = basename(argv[0]); if (!strcmp(g_progname, "ziptool") && argc > 1) return main(argc - 1, argv + 1); if (!strcmp(g_progname, "unzip")) { role = kUnzip; } else if (!strcmp(base, "zipinfo")) { } else if (!strcmp(g_progname, "zipinfo")) { role = kZipinfo; } else { error(1, 0, "run as ziptool with unzip or zipinfo as the first argument, or symlink"); die(0, "run as ziptool with unzip or zipinfo as the first argument, or symlink"); } static const struct option opts[] = { Loading Loading @@ -484,19 +498,19 @@ int main(int argc, char* argv[]) { } } if (!archive_name) error(1, 0, "missing archive filename"); if (!archive_name) die(0, "missing archive filename"); // We can't support "-" to unzip from stdin because libziparchive relies on mmap. ZipArchiveHandle zah; int32_t err; if ((err = OpenArchive(archive_name, &zah)) != 0) { error(1, 0, "couldn't open %s: %s", archive_name, ErrorCodeString(err)); die(0, "couldn't open %s: %s", archive_name, ErrorCodeString(err)); } // Implement -d by changing into that directory. // We'll create implicit directories based on paths in the zip file, but we // require that the -d directory already exists. if (flag_d && chdir(flag_d) == -1) error(1, errno, "couldn't chdir to %s", flag_d); if (flag_d && chdir(flag_d) == -1) die(errno, "couldn't chdir to %s", flag_d); ProcessAll(zah); Loading