Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 break; | 318 break; |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 | 322 |
| 323 unzCloseCurrentFile(zip_file_); | 323 unzCloseCurrentFile(zip_file_); |
| 324 | 324 |
| 325 return success; | 325 return success; |
| 326 } | 326 } |
| 327 | 327 |
| 328 bool ZipReader::ExtractPartOfCurrentEntry(WriterDelegate* delegate, | |
|
satorux1
2017/07/18 07:46:37
This function looks similar to ExtractCurrentEntry
mortonm
2017/07/18 19:58:49
Done.
| |
| 329 size_t num_bytes_to_extract) const { | |
| 330 DCHECK(zip_file_); | |
| 331 | |
| 332 const int open_result = unzOpenCurrentFile(zip_file_); | |
| 333 if (open_result != UNZ_OK) | |
| 334 return false; | |
| 335 | |
| 336 if (!delegate->PrepareOutput()) | |
| 337 return false; | |
| 338 | |
| 339 bool success = true; // This becomes false when something bad happens. | |
| 340 std::unique_ptr<char[]> buf(new char[num_bytes_to_extract]); | |
| 341 base::CheckedNumeric<size_t> total_num_bytes_read = 0; | |
| 342 while (true) { | |
| 343 // This should never result in a negative value, as |num_bytes_to_extract| | |
| 344 // will always be greater than |total_num_bytes_read|. | |
| 345 auto bytes_to_read = base::CheckedNumeric<size_t>(num_bytes_to_extract) - | |
| 346 total_num_bytes_read; | |
| 347 if (!bytes_to_read.IsValid()) { | |
| 348 DLOG(ERROR) << "Size of bytes to read underflows"; | |
| 349 return false; | |
| 350 } | |
| 351 const int num_bytes_read = unzReadCurrentFile( | |
| 352 zip_file_, buf.get(), | |
| 353 base::checked_cast<unsigned int>(bytes_to_read.ValueOrDie())); | |
| 354 | |
| 355 if (num_bytes_read == 0) { | |
| 356 // Reached the end of the file, which should not happen unless |num_bytes| | |
| 357 // is greater than the file length. | |
| 358 return false; | |
| 359 } else if (num_bytes_read < 0) { | |
| 360 // If num_bytes_read < 0, then it's a specific UNZ_* error code. | |
| 361 success = false; | |
| 362 break; | |
| 363 } else if (num_bytes_read > 0) { | |
| 364 // Some data is read. | |
| 365 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) { | |
| 366 success = false; | |
| 367 break; | |
| 368 } | |
| 369 } | |
| 370 // Previous check ensures that num_bytes_read is not negative here. | |
| 371 total_num_bytes_read += base::checked_cast<size_t>(num_bytes_read); | |
| 372 if (!total_num_bytes_read.IsValid()) { | |
| 373 DLOG(ERROR) << "Size of total_num_bytes_read overflows"; | |
| 374 return false; | |
| 375 } | |
| 376 if (total_num_bytes_read.ValueOrDie() == num_bytes_to_extract) { | |
| 377 // Read all the data. | |
| 378 break; | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 unzCloseCurrentFile(zip_file_); | |
| 383 | |
| 384 return success; | |
| 385 } | |
| 386 | |
| 328 bool ZipReader::ExtractCurrentEntryToFilePath( | 387 bool ZipReader::ExtractCurrentEntryToFilePath( |
| 329 const base::FilePath& output_file_path) const { | 388 const base::FilePath& output_file_path) const { |
| 330 DCHECK(zip_file_); | 389 DCHECK(zip_file_); |
| 331 | 390 |
| 332 // If this is a directory, just create it and return. | 391 // If this is a directory, just create it and return. |
| 333 if (current_entry_info()->is_directory()) | 392 if (current_entry_info()->is_directory()) |
| 334 return base::CreateDirectory(output_file_path); | 393 return base::CreateDirectory(output_file_path); |
| 335 | 394 |
| 336 bool success = false; | 395 bool success = false; |
| 337 { | 396 { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), | 498 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), |
| 440 current_entry_info()->original_size()))); | 499 current_entry_info()->original_size()))); |
| 441 | 500 |
| 442 StringWriterDelegate writer(max_read_bytes, &contents); | 501 StringWriterDelegate writer(max_read_bytes, &contents); |
| 443 if (!ExtractCurrentEntry(&writer)) | 502 if (!ExtractCurrentEntry(&writer)) |
| 444 return false; | 503 return false; |
| 445 output->swap(contents); | 504 output->swap(contents); |
| 446 return true; | 505 return true; |
| 447 } | 506 } |
| 448 | 507 |
| 508 bool ZipReader::ExtractPartOfCurrentEntryToString(size_t num_bytes, | |
|
satorux1
2017/07/18 07:46:37
ditto. this looks similar to ExtractCurrentEntryTo
mortonm
2017/07/18 19:58:49
Done.
| |
| 509 std::string* output) const { | |
| 510 DCHECK(output); | |
| 511 DCHECK(zip_file_); | |
| 512 | |
| 513 if (num_bytes == 0U) { | |
| 514 output->clear(); | |
| 515 return true; | |
| 516 } | |
| 517 | |
| 518 if (current_entry_info()->is_directory()) { | |
| 519 output->clear(); | |
| 520 return true; | |
| 521 } | |
| 522 | |
| 523 std::string contents; | |
| 524 contents.reserve(num_bytes); | |
| 525 | |
| 526 StringWriterDelegate writer(num_bytes, &contents); | |
| 527 if (!ExtractPartOfCurrentEntry(&writer, num_bytes)) { | |
| 528 output->clear(); | |
| 529 return false; | |
| 530 } | |
| 531 output->swap(contents); | |
| 532 return true; | |
| 533 } | |
| 534 | |
| 449 bool ZipReader::OpenInternal() { | 535 bool ZipReader::OpenInternal() { |
| 450 DCHECK(zip_file_); | 536 DCHECK(zip_file_); |
| 451 | 537 |
| 452 unz_global_info zip_info = {}; // Zero-clear. | 538 unz_global_info zip_info = {}; // Zero-clear. |
| 453 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { | 539 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { |
| 454 return false; | 540 return false; |
| 455 } | 541 } |
| 456 num_entries_ = zip_info.number_entry; | 542 num_entries_ = zip_info.number_entry; |
| 457 if (num_entries_ < 0) | 543 if (num_entries_ < 0) |
| 458 return false; | 544 return false; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 } | 610 } |
| 525 | 611 |
| 526 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { | 612 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { |
| 527 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); | 613 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); |
| 528 if (bytes_written > 0) | 614 if (bytes_written > 0) |
| 529 file_length_ += bytes_written; | 615 file_length_ += bytes_written; |
| 530 return bytes_written == num_bytes; | 616 return bytes_written == num_bytes; |
| 531 } | 617 } |
| 532 | 618 |
| 533 } // namespace zip | 619 } // namespace zip |
| OLD | NEW |