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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « third_party/ijar/zip.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 Google Inc. All rights reserved. 1 // Copyright 2015 The Bazel Authors. All rights reserved.
2 // 2 //
3 // Author: Alan Donovan <adonovan@google.com>
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
8 // 6 //
9 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
10 // 8 //
11 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
15 // limitations under the License. 13 // limitations under the License.
16 14
17 // 15 //
18 // Zip / Unzip file using ijar zip implementation. 16 // Zip / Unzip file using ijar zip implementation.
19 // 17 //
20 // Note that this Zip implementation intentionally don't compute CRC-32 18 // Note that this Zip implementation intentionally don't compute CRC-32
21 // because it is useless computation for jar because Java doesn't care. 19 // because it is useless computation for jar because Java doesn't care.
22 // CRC-32 of all files in the zip file will be set to 0. 20 // CRC-32 of all files in the zip file will be set to 0.
23 // 21 //
24 22
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <limits.h>
26 #include <stdint.h>
25 #include <stdio.h> 27 #include <stdio.h>
28 #include <stdlib.h>
26 #include <string.h> 29 #include <string.h>
27 #include <stdlib.h>
28 #include <limits.h>
29 #include <fcntl.h>
30 #include <unistd.h> 30 #include <unistd.h>
31 #include <sys/mman.h>
32 #include <errno.h>
33 #include <memory> 31 #include <memory>
34 32
35 #include "third_party/ijar/zip.h" 33 #include "third_party/ijar/zip.h"
36 34
37 namespace devtools_ijar { 35 namespace devtools_ijar {
38 36
39 #define SYSCALL(expr) do { \ 37 #define SYSCALL(expr) do { \
40 if ((expr) < 0) { \ 38 if ((expr) < 0) { \
41 perror(#expr); \ 39 perror(#expr); \
42 abort(); \ 40 abort(); \
(...skipping 22 matching lines...) Expand all
65 const char *output_root_; 63 const char *output_root_;
66 const bool verbose_; 64 const bool verbose_;
67 const bool extract_; 65 const bool extract_;
68 }; 66 };
69 67
70 // Concatene 2 path, path1 and path2, using / as a directory separator and 68 // Concatene 2 path, path1 and path2, using / as a directory separator and
71 // puting the result in "out". "size" specify the size of the output buffer 69 // puting the result in "out". "size" specify the size of the output buffer
72 void concat_path(char* out, const size_t size, 70 void concat_path(char* out, const size_t size,
73 const char *path1, const char *path2) { 71 const char *path1, const char *path2) {
74 int len1 = strlen(path1); 72 int len1 = strlen(path1);
75 int l = len1; 73 size_t l = len1;
76 strncpy(out, path1, size-1); 74 strncpy(out, path1, size - 1);
77 out[size-1] = 0; 75 out[size-1] = 0;
78 if (l < size - 1 && path1[len1] != '/' && path2[0] != '/') { 76 if (l < size - 1 && path1[len1] != '/' && path2[0] != '/') {
79 out[l] = '/'; 77 out[l] = '/';
80 l++; 78 l++;
81 out[l] = 0; 79 out[l] = 0;
82 } 80 }
83 if (l < size - 1) { 81 if (l < size - 1) {
84 strncat(out, path2, size - 1 - l); 82 strncat(out, path2, size - 1 - l);
85 } 83 }
86 } 84 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 const char *pointer = strrchr(path, '/'); 145 const char *pointer = strrchr(path, '/');
148 if (pointer == NULL) { 146 if (pointer == NULL) {
149 pointer = path; 147 pointer = path;
150 } else { 148 } else {
151 pointer++; // Skip the leading slash. 149 pointer++; // Skip the leading slash.
152 } 150 }
153 strncpy(output, pointer, output_size); 151 strncpy(output, pointer, output_size);
154 output[output_size-1] = 0; 152 output[output_size-1] = 0;
155 } 153 }
156 154
155 // copy size bytes from file descriptor fd into buffer.
156 int copy_file_to_buffer(int fd, size_t size, void *buffer) {
157 size_t nb_read = 0;
158 while (nb_read < size) {
159 size_t to_read = size - nb_read;
160 if (to_read > 16384 /* 16K */) {
161 to_read = 16384;
162 }
163 ssize_t r = read(fd, static_cast<uint8_t *>(buffer) + nb_read, to_read);
164 if (r < 0) {
165 return -1;
166 }
167 nb_read += r;
168 }
169 return 0;
170 }
157 171
158 // Execute the extraction (or just listing if just v is provided) 172 // Execute the extraction (or just listing if just v is provided)
159 int extract(char *zipfile, bool verbose, bool extract) { 173 int extract(char *zipfile, bool verbose, bool extract) {
160 char output_root[PATH_MAX]; 174 char output_root[PATH_MAX];
161 getcwd(output_root, PATH_MAX); 175 if (getcwd(output_root, PATH_MAX) == NULL) {
176 fprintf(stderr, "getcwd() failed: %s.\n", strerror(errno));
177 return -1;
178 }
162 179
163 UnzipProcessor processor(output_root, verbose, extract); 180 UnzipProcessor processor(output_root, verbose, extract);
164 std::unique_ptr<ZipExtractor> extractor(ZipExtractor::Create(zipfile, 181 std::unique_ptr<ZipExtractor> extractor(ZipExtractor::Create(zipfile,
165 &processor)); 182 &processor));
166 if (extractor.get() == NULL) { 183 if (extractor.get() == NULL) {
167 fprintf(stderr, "Unable to open zip file %s: %s.\n", zipfile, 184 fprintf(stderr, "Unable to open zip file %s: %s.\n", zipfile,
168 strerror(errno)); 185 strerror(errno));
169 return -1; 186 return -1;
170 } 187 }
171 188
172 if (extractor->ProcessAll() < 0) { 189 if (extractor->ProcessAll() < 0) {
173 fprintf(stderr, "%s.\n", extractor->GetError()); 190 fprintf(stderr, "%s.\n", extractor->GetError());
174 return -1; 191 return -1;
175 } 192 }
176 return 0; 193 return 0;
177 } 194 }
178 195
196 // add a file to the zip
197 int add_file(std::unique_ptr<ZipBuilder> const &builder, char *file,
198 bool flatten, bool verbose, bool compress) {
199 struct stat statst;
200 if (stat(file, &statst) < 0) {
201 fprintf(stderr, "Cannot stat file %s: %s.\n", file, strerror(errno));
202 return -1;
203 }
204 bool isdir = (statst.st_mode & S_IFDIR) != 0;
205
206 if (flatten && isdir) {
207 return 0;
208 }
209
210 // Compute the path, flattening it if requested
211 char path[PATH_MAX];
212 size_t len = strlen(file);
213 if (len > PATH_MAX) {
214 fprintf(stderr, "Path too long: %s.\n", file);
215 return -1;
216 }
217 if (flatten) {
218 basename(file, path, PATH_MAX);
219 } else {
220 strncpy(path, file, PATH_MAX);
221 path[PATH_MAX - 1] = 0;
222 if (isdir && len < PATH_MAX - 1) {
223 // Add the trailing slash for folders
224 path[len] = '/';
225 path[len + 1] = 0;
226 }
227 }
228
229 if (verbose) {
230 mode_t perm = statst.st_mode & 0777;
231 printf("%c %o %s\n", isdir ? 'd' : 'f', perm, path);
232 }
233
234 u1 *buffer = builder->NewFile(path, mode_to_zipattr(statst.st_mode));
235 if (isdir || statst.st_size == 0) {
236 builder->FinishFile(0);
237 } else {
238 // read the input file
239 int fd = open(file, O_RDONLY);
240 if (fd < 0) {
241 fprintf(stderr, "Can't open file %s for reading: %s.\n", file,
242 strerror(errno));
243 return -1;
244 }
245 if (copy_file_to_buffer(fd, statst.st_size, buffer) < 0) {
246 fprintf(stderr, "Can't read file %s: %s.\n", file, strerror(errno));
247 close(fd);
248 return -1;
249 }
250 close(fd);
251 builder->FinishFile(statst.st_size, compress, true);
252 }
253 return 0;
254 }
255
256 // Read a list of files separated by newlines. The resulting array can be
257 // freed using the free method.
258 char **read_filelist(char *filename) {
259 struct stat statst;
260 int fd = open(filename, O_RDONLY);
261 if (fd < 0) {
262 fprintf(stderr, "Can't open file %s for reading: %s.\n", filename,
263 strerror(errno));
264 return NULL;
265 }
266 if (fstat(fd, &statst) < 0) {
267 fprintf(stderr, "Cannot stat file %s: %s.\n", filename, strerror(errno));
268 return NULL;
269 }
270
271 char *data = static_cast<char *>(malloc(statst.st_size));
272 if (copy_file_to_buffer(fd, statst.st_size, data) < 0) {
273 fprintf(stderr, "Can't read file %s: %s.\n", filename, strerror(errno));
274 close(fd);
275 return NULL;
276 }
277 close(fd);
278
279 int nb_entries = 1;
280 for (int i = 0; i < statst.st_size; i++) {
281 if (data[i] == '\n') {
282 nb_entries++;
283 }
284 }
285
286 size_t sizeof_array = sizeof(char *) * (nb_entries + 1);
287 void *result = malloc(sizeof_array + statst.st_size);
288 // copy the content
289 char **filelist = static_cast<char **>(result);
290 char *content = static_cast<char *>(result) + sizeof_array;
291 memcpy(content, data, statst.st_size);
292 free(data);
293 // Create the corresponding array
294 int j = 1;
295 filelist[0] = content;
296 for (int i = 0; i < statst.st_size; i++) {
297 if (content[i] == '\n') {
298 content[i] = 0;
299 if (i + 1 < statst.st_size) {
300 filelist[j] = content + i + 1;
301 j++;
302 }
303 }
304 }
305 filelist[j] = NULL;
306 return filelist;
307 }
308
179 // Execute the create operation 309 // Execute the create operation
180 int create(char *zipfile, char **files, bool flatten, bool verbose, 310 int create(char *zipfile, char **files, bool flatten, bool verbose,
181 bool compress) { 311 bool compress) {
182 struct stat statst;
183 u8 size = ZipBuilder::EstimateSize(files); 312 u8 size = ZipBuilder::EstimateSize(files);
184 if (size == 0) { 313 if (size == 0) {
185 return -1; 314 return -1;
186 } 315 }
187 std::unique_ptr<ZipBuilder> builder(ZipBuilder::Create(zipfile, size)); 316 std::unique_ptr<ZipBuilder> builder(ZipBuilder::Create(zipfile, size));
188 if (builder.get() == NULL) { 317 if (builder.get() == NULL) {
189 fprintf(stderr, "Unable to create zip file %s: %s.\n", 318 fprintf(stderr, "Unable to create zip file %s: %s.\n",
190 zipfile, strerror(errno)); 319 zipfile, strerror(errno));
191 return -1; 320 return -1;
192 } 321 }
193 for (int i = 0; files[i] != NULL; i++) { 322 for (int i = 0; files[i] != NULL; i++) {
194 stat(files[i], &statst); 323 if (add_file(builder, files[i], flatten, verbose, compress) < 0) {
195 char path[PATH_MAX]; 324 return -1;
196 bool isdir = (statst.st_mode & S_IFDIR) != 0;
197
198 if (flatten && isdir) {
199 continue;
200 }
201
202 // Compute the path, flattening it if requested
203 if (flatten) {
204 basename(files[i], path, PATH_MAX);
205 } else {
206 strncpy(path, files[i], PATH_MAX);
207 path[PATH_MAX-1] = 0;
208 size_t len = strlen(path);
209 if (isdir && len < PATH_MAX - 1) {
210 // Add the trailing slash for folders
211 path[len] = '/';
212 path[len+1] = 0;
213 }
214 }
215
216 if (verbose) {
217 mode_t perm = statst.st_mode & 0777;
218 printf("%c %o %s\n", isdir ? 'd' : 'f', perm, path);
219 }
220
221 u1 *buffer = builder->NewFile(path, mode_to_zipattr(statst.st_mode));
222 if (isdir || statst.st_size == 0) {
223 builder->FinishFile(0);
224 } else {
225 // mmap the input file and memcpy
226 int fd = open(files[i], O_RDONLY);
227 if (fd < 0) {
228 fprintf(stderr, "Can't open file %s for reading: %s.\n",
229 files[i], strerror(errno));
230 return -1;
231 }
232 void *data = mmap(NULL, statst.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
233 if (data == MAP_FAILED) {
234 fprintf(stderr, "Can't mmap file %s for reading: %s.\n",
235 files[i], strerror(errno));
236 return -1;
237 }
238 memcpy(buffer, data, statst.st_size);
239 munmap(data, statst.st_size);
240 builder->FinishFile(statst.st_size, compress);
241 } 325 }
242 } 326 }
243 if (builder->Finish() < 0) { 327 if (builder->Finish() < 0) {
244 fprintf(stderr, "%s\n", builder->GetError()); 328 fprintf(stderr, "%s\n", builder->GetError());
245 return -1; 329 return -1;
246 } 330 }
247 return 0; 331 return 0;
248 } 332 }
249 333
250 } // namespace devtools_ijar 334 } // namespace devtools_ijar
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 break; 378 break;
295 default: 379 default:
296 usage(argv[0]); 380 usage(argv[0]);
297 } 381 }
298 } 382 }
299 if (create) { 383 if (create) {
300 if (extract) { 384 if (extract) {
301 usage(argv[0]); 385 usage(argv[0]);
302 } 386 }
303 // Create a zip 387 // Create a zip
304 return devtools_ijar::create(argv[2], argv + 3, flatten, verbose, compress); 388 char **filelist = argv + 3;
389 if (argc == 4 && argv[3][0] == '@') {
390 // We never free that list because it needs to be allocated during the
391 // whole execution, the system will reclaim memory.
392 filelist = devtools_ijar::read_filelist(argv[3] + 1);
393 if (filelist == NULL) {
394 return -1;
395 }
396 }
397 return devtools_ijar::create(argv[2], filelist, flatten, verbose, compress);
305 } else { 398 } else {
306 if (flatten) { 399 if (flatten) {
307 usage(argv[0]); 400 usage(argv[0]);
308 } 401 }
309 // Extraction / list mode 402 // Extraction / list mode
310 return devtools_ijar::extract(argv[2], verbose, extract); 403 return devtools_ijar::extract(argv[2], verbose, extract);
311 } 404 }
312 } 405 }
OLDNEW
« 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