Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: third_party/ijar/zip_main.cc

Issue 1901473003: 🐞 Update version of third_party/ijar (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/ijar/zip.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/ijar/zip_main.cc
diff --git a/third_party/ijar/zip_main.cc b/third_party/ijar/zip_main.cc
index 6c2a97439734cd70020f5da3c0e67c5eb315c6de..1c55ee9fdcf44cf2251242d92a0821927ac981aa 100644
--- a/third_party/ijar/zip_main.cc
+++ b/third_party/ijar/zip_main.cc
@@ -1,6 +1,4 @@
-// Copyright 2015 Google Inc. All rights reserved.
-//
-// Author: Alan Donovan <adonovan@google.com>
+// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,14 +20,14 @@
// CRC-32 of all files in the zip file will be set to 0.
//
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
-#include <limits.h>
-#include <fcntl.h>
+#include <string.h>
#include <unistd.h>
-#include <sys/mman.h>
-#include <errno.h>
#include <memory>
#include "third_party/ijar/zip.h"
@@ -72,8 +70,8 @@ class UnzipProcessor : public ZipExtractorProcessor {
void concat_path(char* out, const size_t size,
const char *path1, const char *path2) {
int len1 = strlen(path1);
- int l = len1;
- strncpy(out, path1, size-1);
+ size_t l = len1;
+ strncpy(out, path1, size - 1);
out[size-1] = 0;
if (l < size - 1 && path1[len1] != '/' && path2[0] != '/') {
out[l] = '/';
@@ -154,11 +152,30 @@ void basename(const char *path, char *output, size_t output_size) {
output[output_size-1] = 0;
}
+// copy size bytes from file descriptor fd into buffer.
+int copy_file_to_buffer(int fd, size_t size, void *buffer) {
+ size_t nb_read = 0;
+ while (nb_read < size) {
+ size_t to_read = size - nb_read;
+ if (to_read > 16384 /* 16K */) {
+ to_read = 16384;
+ }
+ ssize_t r = read(fd, static_cast<uint8_t *>(buffer) + nb_read, to_read);
+ if (r < 0) {
+ return -1;
+ }
+ nb_read += r;
+ }
+ return 0;
+}
// Execute the extraction (or just listing if just v is provided)
int extract(char *zipfile, bool verbose, bool extract) {
char output_root[PATH_MAX];
- getcwd(output_root, PATH_MAX);
+ if (getcwd(output_root, PATH_MAX) == NULL) {
+ fprintf(stderr, "getcwd() failed: %s.\n", strerror(errno));
+ return -1;
+ }
UnzipProcessor processor(output_root, verbose, extract);
std::unique_ptr<ZipExtractor> extractor(ZipExtractor::Create(zipfile,
@@ -176,10 +193,122 @@ int extract(char *zipfile, bool verbose, bool extract) {
return 0;
}
+// add a file to the zip
+int add_file(std::unique_ptr<ZipBuilder> const &builder, char *file,
+ bool flatten, bool verbose, bool compress) {
+ struct stat statst;
+ if (stat(file, &statst) < 0) {
+ fprintf(stderr, "Cannot stat file %s: %s.\n", file, strerror(errno));
+ return -1;
+ }
+ bool isdir = (statst.st_mode & S_IFDIR) != 0;
+
+ if (flatten && isdir) {
+ return 0;
+ }
+
+ // Compute the path, flattening it if requested
+ char path[PATH_MAX];
+ size_t len = strlen(file);
+ if (len > PATH_MAX) {
+ fprintf(stderr, "Path too long: %s.\n", file);
+ return -1;
+ }
+ if (flatten) {
+ basename(file, path, PATH_MAX);
+ } else {
+ strncpy(path, file, PATH_MAX);
+ path[PATH_MAX - 1] = 0;
+ if (isdir && len < PATH_MAX - 1) {
+ // Add the trailing slash for folders
+ path[len] = '/';
+ path[len + 1] = 0;
+ }
+ }
+
+ if (verbose) {
+ mode_t perm = statst.st_mode & 0777;
+ printf("%c %o %s\n", isdir ? 'd' : 'f', perm, path);
+ }
+
+ u1 *buffer = builder->NewFile(path, mode_to_zipattr(statst.st_mode));
+ if (isdir || statst.st_size == 0) {
+ builder->FinishFile(0);
+ } else {
+ // read the input file
+ int fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open file %s for reading: %s.\n", file,
+ strerror(errno));
+ return -1;
+ }
+ if (copy_file_to_buffer(fd, statst.st_size, buffer) < 0) {
+ fprintf(stderr, "Can't read file %s: %s.\n", file, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ builder->FinishFile(statst.st_size, compress, true);
+ }
+ return 0;
+}
+
+// Read a list of files separated by newlines. The resulting array can be
+// freed using the free method.
+char **read_filelist(char *filename) {
+ struct stat statst;
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open file %s for reading: %s.\n", filename,
+ strerror(errno));
+ return NULL;
+ }
+ if (fstat(fd, &statst) < 0) {
+ fprintf(stderr, "Cannot stat file %s: %s.\n", filename, strerror(errno));
+ return NULL;
+ }
+
+ char *data = static_cast<char *>(malloc(statst.st_size));
+ if (copy_file_to_buffer(fd, statst.st_size, data) < 0) {
+ fprintf(stderr, "Can't read file %s: %s.\n", filename, strerror(errno));
+ close(fd);
+ return NULL;
+ }
+ close(fd);
+
+ int nb_entries = 1;
+ for (int i = 0; i < statst.st_size; i++) {
+ if (data[i] == '\n') {
+ nb_entries++;
+ }
+ }
+
+ size_t sizeof_array = sizeof(char *) * (nb_entries + 1);
+ void *result = malloc(sizeof_array + statst.st_size);
+ // copy the content
+ char **filelist = static_cast<char **>(result);
+ char *content = static_cast<char *>(result) + sizeof_array;
+ memcpy(content, data, statst.st_size);
+ free(data);
+ // Create the corresponding array
+ int j = 1;
+ filelist[0] = content;
+ for (int i = 0; i < statst.st_size; i++) {
+ if (content[i] == '\n') {
+ content[i] = 0;
+ if (i + 1 < statst.st_size) {
+ filelist[j] = content + i + 1;
+ j++;
+ }
+ }
+ }
+ filelist[j] = NULL;
+ return filelist;
+}
+
// Execute the create operation
int create(char *zipfile, char **files, bool flatten, bool verbose,
bool compress) {
- struct stat statst;
u8 size = ZipBuilder::EstimateSize(files);
if (size == 0) {
return -1;
@@ -191,53 +320,8 @@ int create(char *zipfile, char **files, bool flatten, bool verbose,
return -1;
}
for (int i = 0; files[i] != NULL; i++) {
- stat(files[i], &statst);
- char path[PATH_MAX];
- bool isdir = (statst.st_mode & S_IFDIR) != 0;
-
- if (flatten && isdir) {
- continue;
- }
-
- // Compute the path, flattening it if requested
- if (flatten) {
- basename(files[i], path, PATH_MAX);
- } else {
- strncpy(path, files[i], PATH_MAX);
- path[PATH_MAX-1] = 0;
- size_t len = strlen(path);
- if (isdir && len < PATH_MAX - 1) {
- // Add the trailing slash for folders
- path[len] = '/';
- path[len+1] = 0;
- }
- }
-
- if (verbose) {
- mode_t perm = statst.st_mode & 0777;
- printf("%c %o %s\n", isdir ? 'd' : 'f', perm, path);
- }
-
- u1 *buffer = builder->NewFile(path, mode_to_zipattr(statst.st_mode));
- if (isdir || statst.st_size == 0) {
- builder->FinishFile(0);
- } else {
- // mmap the input file and memcpy
- int fd = open(files[i], O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Can't open file %s for reading: %s.\n",
- files[i], strerror(errno));
- return -1;
- }
- void *data = mmap(NULL, statst.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (data == MAP_FAILED) {
- fprintf(stderr, "Can't mmap file %s for reading: %s.\n",
- files[i], strerror(errno));
- return -1;
- }
- memcpy(buffer, data, statst.st_size);
- munmap(data, statst.st_size);
- builder->FinishFile(statst.st_size, compress);
+ if (add_file(builder, files[i], flatten, verbose, compress) < 0) {
+ return -1;
}
}
if (builder->Finish() < 0) {
@@ -301,7 +385,16 @@ int main(int argc, char **argv) {
usage(argv[0]);
}
// Create a zip
- return devtools_ijar::create(argv[2], argv + 3, flatten, verbose, compress);
+ char **filelist = argv + 3;
+ if (argc == 4 && argv[3][0] == '@') {
+ // We never free that list because it needs to be allocated during the
+ // whole execution, the system will reclaim memory.
+ filelist = devtools_ijar::read_filelist(argv[3] + 1);
+ if (filelist == NULL) {
+ return -1;
+ }
+ }
+ return devtools_ijar::create(argv[2], filelist, flatten, verbose, compress);
} else {
if (flatten) {
usage(argv[0]);
« no previous file with comments | « third_party/ijar/zip.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698