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 |