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

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

Issue 2961373002: Improve Zip File Scanning on Mac (Closed)
Patch Set: debugging int64_t on android Created 3 years, 4 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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const int result = unzLocateFile(zip_file_, 282 const int result = unzLocateFile(zip_file_,
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,
293 int64_t num_bytes_to_extract) const {
293 DCHECK(zip_file_); 294 DCHECK(zip_file_);
294 295
295 const int open_result = unzOpenCurrentFile(zip_file_); 296 const int open_result = unzOpenCurrentFile(zip_file_);
296 if (open_result != UNZ_OK) 297 if (open_result != UNZ_OK)
297 return false; 298 return false;
298 299
299 if (!delegate->PrepareOutput()) 300 if (!delegate->PrepareOutput())
300 return false; 301 return false;
301 302 LOG(ERROR) << "done with init stuff";
302 bool success = true; // This becomes false when something bad happens. 303 bool success = true; // This becomes false when something bad happens.
303 std::unique_ptr<char[]> buf(new char[internal::kZipBufSize]); 304 std::unique_ptr<char[]> buf(new char[internal::kZipBufSize]);
305 uint64_t total_num_bytes_read = 0;
304 while (true) { 306 while (true) {
305 const int num_bytes_read = unzReadCurrentFile(zip_file_, buf.get(), 307 LOG(ERROR) << "total_num_bytes_read: " << total_num_bytes_read;
306 internal::kZipBufSize); 308 uint64_t bytes_to_read = internal::kZipBufSize;
309 // This should never result in a negative value, as |num_bytes_to_extract|
310 // will always be greater than |total_num_bytes_read|.
311 if (num_bytes_to_extract >= 0) {
312 auto unread_bytes =
313 base::CheckedNumeric<uint64_t>(
314 base::checked_cast<uint64_t>(num_bytes_to_extract)) -
315 total_num_bytes_read;
316 if (unread_bytes.ValueOrDie() < internal::kZipBufSize) {
317 bytes_to_read = unread_bytes.ValueOrDie();
318 }
319 }
320
321 const int num_bytes_read =
322 unzReadCurrentFile(zip_file_, buf.get(), bytes_to_read);
323
307 if (num_bytes_read == 0) { 324 if (num_bytes_read == 0) {
308 // Reached the end of the file. 325 // Reached the end of the file. Return true if entire file was supposed to
309 break; 326 // be read, false if not.
327 if (num_bytes_to_extract == -1) {
328 success = true;
329 break;
330 } else {
331 success = false;
332 LOG(ERROR) << "tried to read past end of file.";
333 break;
334 }
310 } else if (num_bytes_read < 0) { 335 } else if (num_bytes_read < 0) {
311 // If num_bytes_read < 0, then it's a specific UNZ_* error code. 336 // If num_bytes_read < 0, then it's a specific UNZ_* error code.
337 LOG(ERROR) << "read failed";
312 success = false; 338 success = false;
313 break; 339 break;
314 } else if (num_bytes_read > 0) { 340 } else if (num_bytes_read > 0) {
315 // Some data is read. 341 // Some data is read.
316 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) { 342 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) {
343 LOG(ERROR) << "write failed";
317 success = false; 344 success = false;
318 break; 345 break;
319 } 346 }
320 } 347 }
348 // Previous check ensures that num_bytes_read is not negative here.
349 total_num_bytes_read += base::checked_cast<uint64_t>(num_bytes_read);
350 if (num_bytes_to_extract >= 0 &&
351 total_num_bytes_read ==
352 base::checked_cast<uint64_t>(num_bytes_to_extract)) {
353 // Read all the data.
354 break;
355 }
356 LOG(ERROR) << "total_num_bytes_read: " << total_num_bytes_read;
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_);
331 367
332 // If this is a directory, just create it and return. 368 // If this is a directory, just create it and return.
333 if (current_entry_info()->is_directory()) 369 if (current_entry_info()->is_directory())
334 return base::CreateDirectory(output_file_path); 370 return base::CreateDirectory(output_file_path);
335 371
336 bool success = false; 372 bool success = false;
337 { 373 {
338 FilePathWriterDelegate writer(output_file_path); 374 FilePathWriterDelegate writer(output_file_path);
339 success = ExtractCurrentEntry(&writer); 375 success = ExtractCurrentEntry(&writer, -1);
340 } 376 }
341 377
342 if (success && 378 if (success &&
343 current_entry_info()->last_modified() != base::Time::UnixEpoch()) { 379 current_entry_info()->last_modified() != base::Time::UnixEpoch()) {
344 base::TouchFile(output_file_path, 380 base::TouchFile(output_file_path,
345 base::Time::Now(), 381 base::Time::Now(),
346 current_entry_info()->last_modified()); 382 current_entry_info()->last_modified());
347 } 383 }
348 384
349 return success; 385 return success;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 445
410 bool ZipReader::ExtractCurrentEntryToFile(base::File* file) const { 446 bool ZipReader::ExtractCurrentEntryToFile(base::File* file) const {
411 DCHECK(zip_file_); 447 DCHECK(zip_file_);
412 448
413 // If this is a directory, there's nothing to extract to the file, so return 449 // If this is a directory, there's nothing to extract to the file, so return
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, -1);
420 } 456 }
421 457
422 bool ZipReader::ExtractCurrentEntryToString(size_t max_read_bytes, 458 bool ZipReader::ExtractCurrentEntryToString(size_t num_bytes,
459 bool read_entire_file,
423 std::string* output) const { 460 std::string* output) const {
424 DCHECK(output); 461 DCHECK(output);
425 DCHECK(zip_file_); 462 DCHECK(zip_file_);
426 DCHECK_NE(0U, max_read_bytes);
427 463
464 if (num_bytes == 0) {
465 output->clear();
466 return true;
467 }
468 LOG(ERROR) << "here1";
428 if (current_entry_info()->is_directory()) { 469 if (current_entry_info()->is_directory()) {
429 output->clear(); 470 output->clear();
430 return true; 471 return true;
431 } 472 }
432 473
433 // The original_size() is the best hint for the real size, so it saves 474 // 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 475 // doing reallocations for the common case when the uncompressed size is
435 // correct. However, we need to assume that the uncompressed size could be 476 // 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. 477 // incorrect therefore this function needs to read as much data as possible.
437 std::string contents; 478 std::string contents;
438 contents.reserve( 479 if (read_entire_file) {
439 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), 480 contents.reserve(
440 current_entry_info()->original_size()))); 481 static_cast<size_t>(std::min(static_cast<int64_t>(num_bytes),
482 current_entry_info()->original_size())));
483 } else {
484 contents.reserve(num_bytes);
485 }
441 486
442 StringWriterDelegate writer(max_read_bytes, &contents); 487 StringWriterDelegate writer(num_bytes, &contents);
443 if (!ExtractCurrentEntry(&writer)) 488 int64_t size_arg = read_entire_file ? ((int64_t)-1) : num_bytes;
489 LOG(ERROR) << "size_arg: " << size_arg;
490 LOG(ERROR) << "num_bytes: " << num_bytes;
491 if (!ExtractCurrentEntry(&writer, size_arg)) {
492 output->clear();
493 LOG(ERROR) << "ExtractCurrentEntry failed";
444 return false; 494 return false;
495 }
445 output->swap(contents); 496 output->swap(contents);
446 return true; 497 return true;
447 } 498 }
448 499
449 bool ZipReader::OpenInternal() { 500 bool ZipReader::OpenInternal() {
450 DCHECK(zip_file_); 501 DCHECK(zip_file_);
451 502
452 unz_global_info zip_info = {}; // Zero-clear. 503 unz_global_info zip_info = {}; // Zero-clear.
453 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { 504 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) {
454 return false; 505 return false;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 } 575 }
525 576
526 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { 577 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) {
527 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); 578 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes);
528 if (bytes_written > 0) 579 if (bytes_written > 0)
529 file_length_ += bytes_written; 580 file_length_ += bytes_written;
530 return bytes_written == num_bytes; 581 return bytes_written == num_bytes;
531 } 582 }
532 583
533 } // namespace zip 584 } // namespace zip
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698