| Index: third_party/zlib/google/zip_reader.cc
|
| diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc
|
| index 59d96da14263cbfb88d2230e8250396152e8b85c..a1dddfb85388a429ffc2e1308a4c39be57f87b5d 100644
|
| --- a/third_party/zlib/google/zip_reader.cc
|
| +++ b/third_party/zlib/google/zip_reader.cc
|
| @@ -22,103 +22,6 @@
|
| #endif // defined(USE_SYSTEM_MINIZIP)
|
|
|
| namespace zip {
|
| -
|
| -namespace {
|
| -
|
| -// FilePathWriterDelegate ------------------------------------------------------
|
| -
|
| -// A writer delegate that writes a file at a given path.
|
| -class FilePathWriterDelegate : public WriterDelegate {
|
| - public:
|
| - explicit FilePathWriterDelegate(const base::FilePath& output_file_path);
|
| - ~FilePathWriterDelegate() override;
|
| -
|
| - // WriterDelegate methods:
|
| -
|
| - // Creates the output file and any necessary intermediate directories.
|
| - bool PrepareOutput() override;
|
| -
|
| - // Writes |num_bytes| bytes of |data| to the file, returning false if not all
|
| - // bytes could be written.
|
| - bool WriteBytes(const char* data, int num_bytes) override;
|
| -
|
| - private:
|
| - base::FilePath output_file_path_;
|
| - base::File file_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(FilePathWriterDelegate);
|
| -};
|
| -
|
| -FilePathWriterDelegate::FilePathWriterDelegate(
|
| - const base::FilePath& output_file_path)
|
| - : output_file_path_(output_file_path) {
|
| -}
|
| -
|
| -FilePathWriterDelegate::~FilePathWriterDelegate() {
|
| -}
|
| -
|
| -bool FilePathWriterDelegate::PrepareOutput() {
|
| - // We can't rely on parent directory entries being specified in the
|
| - // zip, so we make sure they are created.
|
| - if (!base::CreateDirectory(output_file_path_.DirName()))
|
| - return false;
|
| -
|
| - file_.Initialize(output_file_path_,
|
| - base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
|
| - return file_.IsValid();
|
| -}
|
| -
|
| -bool FilePathWriterDelegate::WriteBytes(const char* data, int num_bytes) {
|
| - return num_bytes == file_.WriteAtCurrentPos(data, num_bytes);
|
| -}
|
| -
|
| -
|
| -// StringWriterDelegate --------------------------------------------------------
|
| -
|
| -// A writer delegate that writes no more than |max_read_bytes| to a given
|
| -// std::string.
|
| -class StringWriterDelegate : public WriterDelegate {
|
| - public:
|
| - StringWriterDelegate(size_t max_read_bytes, std::string* output);
|
| - ~StringWriterDelegate() override;
|
| -
|
| - // WriterDelegate methods:
|
| -
|
| - // Returns true.
|
| - bool PrepareOutput() override;
|
| -
|
| - // Appends |num_bytes| bytes from |data| to the output string. Returns false
|
| - // if |num_bytes| will cause the string to exceed |max_read_bytes|.
|
| - bool WriteBytes(const char* data, int num_bytes) override;
|
| -
|
| - private:
|
| - size_t max_read_bytes_;
|
| - std::string* output_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(StringWriterDelegate);
|
| -};
|
| -
|
| -StringWriterDelegate::StringWriterDelegate(size_t max_read_bytes,
|
| - std::string* output)
|
| - : max_read_bytes_(max_read_bytes),
|
| - output_(output) {
|
| -}
|
| -
|
| -StringWriterDelegate::~StringWriterDelegate() {
|
| -}
|
| -
|
| -bool StringWriterDelegate::PrepareOutput() {
|
| - return true;
|
| -}
|
| -
|
| -bool StringWriterDelegate::WriteBytes(const char* data, int num_bytes) {
|
| - if (output_->size() + num_bytes > max_read_bytes_)
|
| - return false;
|
| - output_->append(data, num_bytes);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
|
|
| // TODO(satorux): The implementation assumes that file names in zip files
|
| // are encoded in UTF-8. This is true for zip files created by Zip()
|
| @@ -284,20 +187,33 @@
|
| return OpenCurrentEntryInZip();
|
| }
|
|
|
| -bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate) const {
|
| - DCHECK(zip_file_);
|
| +bool ZipReader::ExtractCurrentEntryToFilePath(
|
| + const base::FilePath& output_file_path) {
|
| + DCHECK(zip_file_);
|
| +
|
| + // If this is a directory, just create it and return.
|
| + if (current_entry_info()->is_directory())
|
| + return base::CreateDirectory(output_file_path);
|
|
|
| const int open_result = unzOpenCurrentFile(zip_file_);
|
| if (open_result != UNZ_OK)
|
| return false;
|
|
|
| - if (!delegate->PrepareOutput())
|
| + // We can't rely on parent directory entries being specified in the
|
| + // zip, so we make sure they are created.
|
| + base::FilePath output_dir_path = output_file_path.DirName();
|
| + if (!base::CreateDirectory(output_dir_path))
|
| + return false;
|
| +
|
| + base::File file(output_file_path,
|
| + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
|
| + if (!file.IsValid())
|
| return false;
|
|
|
| bool success = true; // This becomes false when something bad happens.
|
| - scoped_ptr<char[]> buf(new char[internal::kZipBufSize]);
|
| while (true) {
|
| - const int num_bytes_read = unzReadCurrentFile(zip_file_, buf.get(),
|
| + char buf[internal::kZipBufSize];
|
| + const int num_bytes_read = unzReadCurrentFile(zip_file_, buf,
|
| internal::kZipBufSize);
|
| if (num_bytes_read == 0) {
|
| // Reached the end of the file.
|
| @@ -307,39 +223,21 @@
|
| success = false;
|
| break;
|
| } else if (num_bytes_read > 0) {
|
| - // Some data is read.
|
| - if (!delegate->WriteBytes(buf.get(), num_bytes_read)) {
|
| + // Some data is read. Write it to the output file.
|
| + if (num_bytes_read != file.WriteAtCurrentPos(buf, num_bytes_read)) {
|
| success = false;
|
| break;
|
| }
|
| }
|
| }
|
|
|
| + file.Close();
|
| unzCloseCurrentFile(zip_file_);
|
|
|
| - return success;
|
| -}
|
| -
|
| -bool ZipReader::ExtractCurrentEntryToFilePath(
|
| - const base::FilePath& output_file_path) const {
|
| - DCHECK(zip_file_);
|
| -
|
| - // If this is a directory, just create it and return.
|
| - if (current_entry_info()->is_directory())
|
| - return base::CreateDirectory(output_file_path);
|
| -
|
| - bool success = false;
|
| - {
|
| - FilePathWriterDelegate writer(output_file_path);
|
| - success = ExtractCurrentEntry(&writer);
|
| - }
|
| -
|
| - if (success &&
|
| - current_entry_info()->last_modified() != base::Time::UnixEpoch()) {
|
| + if (current_entry_info()->last_modified() != base::Time::UnixEpoch())
|
| base::TouchFile(output_file_path,
|
| base::Time::Now(),
|
| current_entry_info()->last_modified());
|
| - }
|
|
|
| return success;
|
| }
|
| @@ -398,7 +296,7 @@
|
| }
|
|
|
| bool ZipReader::ExtractCurrentEntryIntoDirectory(
|
| - const base::FilePath& output_directory_path) const {
|
| + const base::FilePath& output_directory_path) {
|
| DCHECK(current_entry_info_.get());
|
|
|
| base::FilePath output_file_path = output_directory_path.Append(
|
| @@ -406,28 +304,60 @@
|
| return ExtractCurrentEntryToFilePath(output_file_path);
|
| }
|
|
|
| -bool ZipReader::ExtractCurrentEntryToFile(base::File* file) const {
|
| - DCHECK(zip_file_);
|
| -
|
| - // If this is a directory, there's nothing to extract to the file, so return
|
| - // false.
|
| +#if defined(OS_POSIX)
|
| +bool ZipReader::ExtractCurrentEntryToFd(const int fd) {
|
| + DCHECK(zip_file_);
|
| +
|
| + // If this is a directory, there's nothing to extract to the file descriptor,
|
| + // so return false.
|
| if (current_entry_info()->is_directory())
|
| return false;
|
|
|
| - FileWriterDelegate writer(file);
|
| - return ExtractCurrentEntry(&writer);
|
| -}
|
| -
|
| -bool ZipReader::ExtractCurrentEntryToString(size_t max_read_bytes,
|
| - std::string* output) const {
|
| + const int open_result = unzOpenCurrentFile(zip_file_);
|
| + if (open_result != UNZ_OK)
|
| + return false;
|
| +
|
| + bool success = true; // This becomes false when something bad happens.
|
| + while (true) {
|
| + char buf[internal::kZipBufSize];
|
| + const int num_bytes_read = unzReadCurrentFile(zip_file_, buf,
|
| + internal::kZipBufSize);
|
| + if (num_bytes_read == 0) {
|
| + // Reached the end of the file.
|
| + break;
|
| + } else if (num_bytes_read < 0) {
|
| + // If num_bytes_read < 0, then it's a specific UNZ_* error code.
|
| + success = false;
|
| + break;
|
| + } else if (num_bytes_read > 0) {
|
| + // Some data is read. Write it to the output file descriptor.
|
| + if (!base::WriteFileDescriptor(fd, buf, num_bytes_read)) {
|
| + success = false;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| + unzCloseCurrentFile(zip_file_);
|
| + return success;
|
| +}
|
| +#endif // defined(OS_POSIX)
|
| +
|
| +bool ZipReader::ExtractCurrentEntryToString(
|
| + size_t max_read_bytes,
|
| + std::string* output) const {
|
| DCHECK(output);
|
| DCHECK(zip_file_);
|
| - DCHECK_NE(0U, max_read_bytes);
|
| + DCHECK(max_read_bytes != 0);
|
|
|
| if (current_entry_info()->is_directory()) {
|
| output->clear();
|
| return true;
|
| }
|
| +
|
| + const int open_result = unzOpenCurrentFile(zip_file_);
|
| + if (open_result != UNZ_OK)
|
| + return false;
|
|
|
| // The original_size() is the best hint for the real size, so it saves
|
| // doing reallocations for the common case when the uncompressed size is
|
| @@ -438,11 +368,32 @@
|
| static_cast<int64>(max_read_bytes),
|
| current_entry_info()->original_size())));
|
|
|
| - StringWriterDelegate writer(max_read_bytes, &contents);
|
| - if (!ExtractCurrentEntry(&writer))
|
| - return false;
|
| - output->swap(contents);
|
| - return true;
|
| + bool success = true; // This becomes false when something bad happens.
|
| + char buf[internal::kZipBufSize];
|
| + while (true) {
|
| + const int num_bytes_read = unzReadCurrentFile(zip_file_, buf,
|
| + internal::kZipBufSize);
|
| + if (num_bytes_read == 0) {
|
| + // Reached the end of the file.
|
| + break;
|
| + } else if (num_bytes_read < 0) {
|
| + // If num_bytes_read < 0, then it's a specific UNZ_* error code.
|
| + success = false;
|
| + break;
|
| + } else if (num_bytes_read > 0) {
|
| + if (contents.size() + num_bytes_read > max_read_bytes) {
|
| + success = false;
|
| + break;
|
| + }
|
| + contents.append(buf, num_bytes_read);
|
| + }
|
| + }
|
| +
|
| + unzCloseCurrentFile(zip_file_);
|
| + if (success)
|
| + output->swap(contents);
|
| +
|
| + return success;
|
| }
|
|
|
| bool ZipReader::OpenInternal() {
|
| @@ -510,30 +461,5 @@
|
| }
|
| }
|
|
|
| -// FileWriterDelegate ----------------------------------------------------------
|
| -
|
| -FileWriterDelegate::FileWriterDelegate(base::File* file)
|
| - : file_(file),
|
| - file_length_(0) {
|
| -}
|
| -
|
| -FileWriterDelegate::~FileWriterDelegate() {
|
| -#if !defined(NDEBUG)
|
| - const bool success =
|
| -#endif
|
| - file_->SetLength(file_length_);
|
| - DPLOG_IF(ERROR, !success) << "Failed updating length of written file";
|
| -}
|
| -
|
| -bool FileWriterDelegate::PrepareOutput() {
|
| - return file_->Seek(base::File::FROM_BEGIN, 0) >= 0;
|
| -}
|
| -
|
| -bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) {
|
| - int bytes_written = file_->WriteAtCurrentPos(data, num_bytes);
|
| - if (bytes_written > 0)
|
| - file_length_ += bytes_written;
|
| - return bytes_written == num_bytes;
|
| -}
|
|
|
| } // namespace zip
|
|
|