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

Side by Side Diff: third_party/zlib/google/zip_reader.cc

Issue 2961373002: Improve Zip File Scanning on Mac (Closed)
Patch Set: refactoring in zip_reader Created 3 years, 5 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "third_party/zlib/google/zip_reader.h" 5 #include "third_party/zlib/google/zip_reader.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file.h" 10 #include "base/files/file.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 path_in_zip.AsUTF8Unsafe().c_str(), 283 path_in_zip.AsUTF8Unsafe().c_str(),
284 kDefaultCaseSensivityOfOS); 284 kDefaultCaseSensivityOfOS);
285 if (result != UNZ_OK) 285 if (result != UNZ_OK)
286 return false; 286 return false;
287 287
288 // Then Open the entry. 288 // Then Open the entry.
289 return OpenCurrentEntryInZip(); 289 return OpenCurrentEntryInZip();
290 } 290 }
291 291
292 bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate) const { 292 bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate) const {
293 return ExtractFromBeginningOfCurrentEntry(delegate, -1);
294 }
295
296 bool ZipReader::ExtractFromBeginningOfCurrentEntry(
297 WriterDelegate* delegate,
298 int64_t num_bytes_to_extract) const {
293 DCHECK(zip_file_); 299 DCHECK(zip_file_);
294 300
295 const int open_result = unzOpenCurrentFile(zip_file_); 301 const int open_result = unzOpenCurrentFile(zip_file_);
296 if (open_result != UNZ_OK) 302 if (open_result != UNZ_OK)
297 return false; 303 return false;
298 304
299 if (!delegate->PrepareOutput()) 305 if (!delegate->PrepareOutput())
300 return false; 306 return false;
301 307
302 bool success = true; // This becomes false when something bad happens. 308 bool success = true; // This becomes false when something bad happens.
303 std::unique_ptr<char[]> buf(new char[internal::kZipBufSize]); 309 std::unique_ptr<char[]> buf(new char[internal::kZipBufSize]);
310 uint64_t total_num_bytes_read = 0;
304 while (true) { 311 while (true) {
305 const int num_bytes_read = unzReadCurrentFile(zip_file_, buf.get(), 312 uint64_t bytes_to_read = internal::kZipBufSize;
306 internal::kZipBufSize); 313 // This should never result in a negative value, as |num_bytes_to_extract|
314 // will always be greater than |total_num_bytes_read|.
315 if (num_bytes_to_extract >= 0) {
316 auto unread_bytes =
317 base::CheckedNumeric<uint64_t>(
318 base::checked_cast<uint64_t>(num_bytes_to_extract)) -
319 total_num_bytes_read;
320 if (unread_bytes.ValueOrDie() < internal::kZipBufSize) {
321 bytes_to_read = unread_bytes.ValueOrDie();
322 }
323 }
324
325 const int num_bytes_read =
326 unzReadCurrentFile(zip_file_, buf.get(), bytes_to_read);
327
307 if (num_bytes_read == 0) { 328 if (num_bytes_read == 0) {
308 // Reached the end of the file. 329 // Reached the end of the file. Return true if entire file was supposed to
309 break; 330 // be read, false if not.
331 if (num_bytes_to_extract == -1) {
332 success = true;
333 break;
334 } else {
335 success = false;
336 break;
337 }
310 } else if (num_bytes_read < 0) { 338 } else if (num_bytes_read < 0) {
311 // If num_bytes_read < 0, then it's a specific UNZ_* error code. 339 // If num_bytes_read < 0, then it's a specific UNZ_* error code.
312 success = false; 340 success = false;
313 break; 341 break;
314 } else if (num_bytes_read > 0) { 342 } else if (num_bytes_read > 0) {
315 // Some data is read. 343 // Some data is read.
316 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) { 344 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) {
317 success = false; 345 success = false;
318 break; 346 break;
319 } 347 }
320 } 348 }
349 // Previous check ensures that num_bytes_read is not negative here.
350 total_num_bytes_read += base::checked_cast<uint64_t>(num_bytes_read);
351 if (num_bytes_to_extract >= 0 &&
352 total_num_bytes_read ==
353 base::checked_cast<uint64_t>(num_bytes_to_extract)) {
354 // Read all the data.
355 break;
356 }
321 } 357 }
322 358
323 unzCloseCurrentFile(zip_file_); 359 unzCloseCurrentFile(zip_file_);
324 360
325 return success; 361 return success;
326 } 362 }
327 363
328 bool ZipReader::ExtractCurrentEntryToFilePath( 364 bool ZipReader::ExtractCurrentEntryToFilePath(
329 const base::FilePath& output_file_path) const { 365 const base::FilePath& output_file_path) const {
330 DCHECK(zip_file_); 366 DCHECK(zip_file_);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 // false. 450 // false.
415 if (current_entry_info()->is_directory()) 451 if (current_entry_info()->is_directory())
416 return false; 452 return false;
417 453
418 FileWriterDelegate writer(file); 454 FileWriterDelegate writer(file);
419 return ExtractCurrentEntry(&writer); 455 return ExtractCurrentEntry(&writer);
420 } 456 }
421 457
422 bool ZipReader::ExtractCurrentEntryToString(size_t max_read_bytes, 458 bool ZipReader::ExtractCurrentEntryToString(size_t max_read_bytes,
423 std::string* output) const { 459 std::string* output) const {
460 return ExtractFromBeginningOfCurrentEntryToString(max_read_bytes, true,
461 output);
462 }
463
464 bool ZipReader::ExtractFromBeginningOfCurrentEntryToString(
465 size_t num_bytes,
466 bool read_entire_file,
467 std::string* output) const {
424 DCHECK(output); 468 DCHECK(output);
425 DCHECK(zip_file_); 469 DCHECK(zip_file_);
426 DCHECK_NE(0U, max_read_bytes); 470
471 if (num_bytes == 0) {
472 output->clear();
473 return true;
474 }
427 475
428 if (current_entry_info()->is_directory()) { 476 if (current_entry_info()->is_directory()) {
429 output->clear(); 477 output->clear();
430 return true; 478 return true;
431 } 479 }
432 480
433 // The original_size() is the best hint for the real size, so it saves 481 // The original_size() is the best hint for the real size, so it saves
434 // doing reallocations for the common case when the uncompressed size is 482 // doing reallocations for the common case when the uncompressed size is
435 // correct. However, we need to assume that the uncompressed size could be 483 // correct. However, we need to assume that the uncompressed size could be
436 // incorrect therefore this function needs to read as much data as possible. 484 // incorrect therefore this function needs to read as much data as possible.
437 std::string contents; 485 std::string contents;
438 contents.reserve( 486 if (read_entire_file) {
439 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), 487 contents.reserve(
440 current_entry_info()->original_size()))); 488 static_cast<size_t>(std::min(static_cast<int64_t>(num_bytes),
489 current_entry_info()->original_size())));
490 } else {
491 contents.reserve(num_bytes);
492 }
441 493
442 StringWriterDelegate writer(max_read_bytes, &contents); 494 StringWriterDelegate writer(num_bytes, &contents);
443 if (!ExtractCurrentEntry(&writer)) 495 if (read_entire_file) {
444 return false; 496 if (!ExtractCurrentEntry(&writer)) {
445 output->swap(contents); 497 output->clear();
498 return false;
499 }
500 output->swap(contents);
501 } else {
502 if (!ExtractFromBeginningOfCurrentEntry(&writer, num_bytes)) {
503 output->clear();
504 return false;
505 }
506 output->swap(contents);
507 }
446 return true; 508 return true;
447 } 509 }
448 510
449 bool ZipReader::OpenInternal() { 511 bool ZipReader::OpenInternal() {
450 DCHECK(zip_file_); 512 DCHECK(zip_file_);
451 513
452 unz_global_info zip_info = {}; // Zero-clear. 514 unz_global_info zip_info = {}; // Zero-clear.
453 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { 515 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) {
454 return false; 516 return false;
455 } 517 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 } 586 }
525 587
526 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { 588 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) {
527 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); 589 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes);
528 if (bytes_written > 0) 590 if (bytes_written > 0)
529 file_length_ += bytes_written; 591 file_length_ += bytes_written;
530 return bytes_written == num_bytes; 592 return bytes_written == num_bytes;
531 } 593 }
532 594
533 } // namespace zip 595 } // namespace zip
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698