xref: /aosp_15_r20/external/zlib/google/zip.cc (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1*86ee64e7SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*86ee64e7SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*86ee64e7SAndroid Build Coastguard Worker // found in the LICENSE file.
4*86ee64e7SAndroid Build Coastguard Worker 
5*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip.h"
6*86ee64e7SAndroid Build Coastguard Worker 
7*86ee64e7SAndroid Build Coastguard Worker #include <string>
8*86ee64e7SAndroid Build Coastguard Worker #include <vector>
9*86ee64e7SAndroid Build Coastguard Worker 
10*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file.h"
11*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file_enumerator.h"
12*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file_util.h"
13*86ee64e7SAndroid Build Coastguard Worker #include "base/functional/bind.h"
14*86ee64e7SAndroid Build Coastguard Worker #include "base/logging.h"
15*86ee64e7SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
16*86ee64e7SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
17*86ee64e7SAndroid Build Coastguard Worker #include "build/build_config.h"
18*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/redact.h"
19*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip_internal.h"
20*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip_reader.h"
21*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip_writer.h"
22*86ee64e7SAndroid Build Coastguard Worker 
23*86ee64e7SAndroid Build Coastguard Worker namespace zip {
24*86ee64e7SAndroid Build Coastguard Worker namespace {
25*86ee64e7SAndroid Build Coastguard Worker 
IsHiddenFile(const base::FilePath & file_path)26*86ee64e7SAndroid Build Coastguard Worker bool IsHiddenFile(const base::FilePath& file_path) {
27*86ee64e7SAndroid Build Coastguard Worker   return file_path.BaseName().value()[0] == '.';
28*86ee64e7SAndroid Build Coastguard Worker }
29*86ee64e7SAndroid Build Coastguard Worker 
30*86ee64e7SAndroid Build Coastguard Worker // Creates a directory at |extract_dir|/|entry_path|, including any parents.
CreateDirectory(const base::FilePath & extract_dir,const base::FilePath & entry_path)31*86ee64e7SAndroid Build Coastguard Worker bool CreateDirectory(const base::FilePath& extract_dir,
32*86ee64e7SAndroid Build Coastguard Worker                      const base::FilePath& entry_path) {
33*86ee64e7SAndroid Build Coastguard Worker   const base::FilePath dir = extract_dir.Append(entry_path);
34*86ee64e7SAndroid Build Coastguard Worker   const bool ok = base::CreateDirectory(dir);
35*86ee64e7SAndroid Build Coastguard Worker   PLOG_IF(ERROR, !ok) << "Cannot create directory " << Redact(dir);
36*86ee64e7SAndroid Build Coastguard Worker   return ok;
37*86ee64e7SAndroid Build Coastguard Worker }
38*86ee64e7SAndroid Build Coastguard Worker 
39*86ee64e7SAndroid Build Coastguard Worker // Creates a WriterDelegate that can write a file at |extract_dir|/|entry_path|.
CreateFilePathWriterDelegate(const base::FilePath & extract_dir,const base::FilePath & entry_path)40*86ee64e7SAndroid Build Coastguard Worker std::unique_ptr<WriterDelegate> CreateFilePathWriterDelegate(
41*86ee64e7SAndroid Build Coastguard Worker     const base::FilePath& extract_dir,
42*86ee64e7SAndroid Build Coastguard Worker     const base::FilePath& entry_path) {
43*86ee64e7SAndroid Build Coastguard Worker   return std::make_unique<FilePathWriterDelegate>(
44*86ee64e7SAndroid Build Coastguard Worker       extract_dir.Append(entry_path));
45*86ee64e7SAndroid Build Coastguard Worker }
46*86ee64e7SAndroid Build Coastguard Worker 
47*86ee64e7SAndroid Build Coastguard Worker class DirectFileAccessor : public FileAccessor {
48*86ee64e7SAndroid Build Coastguard Worker  public:
DirectFileAccessor(base::FilePath src_dir)49*86ee64e7SAndroid Build Coastguard Worker   explicit DirectFileAccessor(base::FilePath src_dir)
50*86ee64e7SAndroid Build Coastguard Worker       : src_dir_(std::move(src_dir)) {}
51*86ee64e7SAndroid Build Coastguard Worker 
52*86ee64e7SAndroid Build Coastguard Worker   ~DirectFileAccessor() override = default;
53*86ee64e7SAndroid Build Coastguard Worker 
Open(const Paths paths,std::vector<base::File> * const files)54*86ee64e7SAndroid Build Coastguard Worker   bool Open(const Paths paths, std::vector<base::File>* const files) override {
55*86ee64e7SAndroid Build Coastguard Worker     DCHECK(files);
56*86ee64e7SAndroid Build Coastguard Worker     files->reserve(files->size() + paths.size());
57*86ee64e7SAndroid Build Coastguard Worker 
58*86ee64e7SAndroid Build Coastguard Worker     for (const base::FilePath& path : paths) {
59*86ee64e7SAndroid Build Coastguard Worker       DCHECK(!path.IsAbsolute());
60*86ee64e7SAndroid Build Coastguard Worker       const base::FilePath absolute_path = src_dir_.Append(path);
61*86ee64e7SAndroid Build Coastguard Worker       if (base::DirectoryExists(absolute_path)) {
62*86ee64e7SAndroid Build Coastguard Worker         files->emplace_back();
63*86ee64e7SAndroid Build Coastguard Worker         LOG(ERROR) << "Cannot open " << Redact(path) << ": It is a directory";
64*86ee64e7SAndroid Build Coastguard Worker       } else {
65*86ee64e7SAndroid Build Coastguard Worker         const base::File& file = files->emplace_back(
66*86ee64e7SAndroid Build Coastguard Worker             absolute_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
67*86ee64e7SAndroid Build Coastguard Worker         LOG_IF(ERROR, !file.IsValid())
68*86ee64e7SAndroid Build Coastguard Worker             << "Cannot open " << Redact(path) << ": "
69*86ee64e7SAndroid Build Coastguard Worker             << base::File::ErrorToString(file.error_details());
70*86ee64e7SAndroid Build Coastguard Worker       }
71*86ee64e7SAndroid Build Coastguard Worker     }
72*86ee64e7SAndroid Build Coastguard Worker 
73*86ee64e7SAndroid Build Coastguard Worker     return true;
74*86ee64e7SAndroid Build Coastguard Worker   }
75*86ee64e7SAndroid Build Coastguard Worker 
List(const base::FilePath & path,std::vector<base::FilePath> * const files,std::vector<base::FilePath> * const subdirs)76*86ee64e7SAndroid Build Coastguard Worker   bool List(const base::FilePath& path,
77*86ee64e7SAndroid Build Coastguard Worker             std::vector<base::FilePath>* const files,
78*86ee64e7SAndroid Build Coastguard Worker             std::vector<base::FilePath>* const subdirs) override {
79*86ee64e7SAndroid Build Coastguard Worker     DCHECK(!path.IsAbsolute());
80*86ee64e7SAndroid Build Coastguard Worker     DCHECK(files);
81*86ee64e7SAndroid Build Coastguard Worker     DCHECK(subdirs);
82*86ee64e7SAndroid Build Coastguard Worker 
83*86ee64e7SAndroid Build Coastguard Worker     base::FileEnumerator file_enumerator(
84*86ee64e7SAndroid Build Coastguard Worker         src_dir_.Append(path), false /* recursive */,
85*86ee64e7SAndroid Build Coastguard Worker         base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
86*86ee64e7SAndroid Build Coastguard Worker 
87*86ee64e7SAndroid Build Coastguard Worker     while (!file_enumerator.Next().empty()) {
88*86ee64e7SAndroid Build Coastguard Worker       const base::FileEnumerator::FileInfo info = file_enumerator.GetInfo();
89*86ee64e7SAndroid Build Coastguard Worker       (info.IsDirectory() ? subdirs : files)
90*86ee64e7SAndroid Build Coastguard Worker           ->push_back(path.Append(info.GetName()));
91*86ee64e7SAndroid Build Coastguard Worker     }
92*86ee64e7SAndroid Build Coastguard Worker 
93*86ee64e7SAndroid Build Coastguard Worker     return true;
94*86ee64e7SAndroid Build Coastguard Worker   }
95*86ee64e7SAndroid Build Coastguard Worker 
GetInfo(const base::FilePath & path,Info * const info)96*86ee64e7SAndroid Build Coastguard Worker   bool GetInfo(const base::FilePath& path, Info* const info) override {
97*86ee64e7SAndroid Build Coastguard Worker     DCHECK(!path.IsAbsolute());
98*86ee64e7SAndroid Build Coastguard Worker     DCHECK(info);
99*86ee64e7SAndroid Build Coastguard Worker 
100*86ee64e7SAndroid Build Coastguard Worker     base::File::Info file_info;
101*86ee64e7SAndroid Build Coastguard Worker     if (!base::GetFileInfo(src_dir_.Append(path), &file_info)) {
102*86ee64e7SAndroid Build Coastguard Worker       PLOG(ERROR) << "Cannot get info of " << Redact(path);
103*86ee64e7SAndroid Build Coastguard Worker       return false;
104*86ee64e7SAndroid Build Coastguard Worker     }
105*86ee64e7SAndroid Build Coastguard Worker 
106*86ee64e7SAndroid Build Coastguard Worker     info->is_directory = file_info.is_directory;
107*86ee64e7SAndroid Build Coastguard Worker     info->last_modified = file_info.last_modified;
108*86ee64e7SAndroid Build Coastguard Worker 
109*86ee64e7SAndroid Build Coastguard Worker     return true;
110*86ee64e7SAndroid Build Coastguard Worker   }
111*86ee64e7SAndroid Build Coastguard Worker 
112*86ee64e7SAndroid Build Coastguard Worker  private:
113*86ee64e7SAndroid Build Coastguard Worker   const base::FilePath src_dir_;
114*86ee64e7SAndroid Build Coastguard Worker };
115*86ee64e7SAndroid Build Coastguard Worker 
116*86ee64e7SAndroid Build Coastguard Worker }  // namespace
117*86ee64e7SAndroid Build Coastguard Worker 
operator <<(std::ostream & out,const Progress & progress)118*86ee64e7SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const Progress& progress) {
119*86ee64e7SAndroid Build Coastguard Worker   return out << progress.bytes << " bytes, " << progress.files << " files, "
120*86ee64e7SAndroid Build Coastguard Worker              << progress.directories << " dirs, " << progress.errors
121*86ee64e7SAndroid Build Coastguard Worker              << " errors";
122*86ee64e7SAndroid Build Coastguard Worker }
123*86ee64e7SAndroid Build Coastguard Worker 
Zip(const ZipParams & params)124*86ee64e7SAndroid Build Coastguard Worker bool Zip(const ZipParams& params) {
125*86ee64e7SAndroid Build Coastguard Worker   DirectFileAccessor default_accessor(params.src_dir);
126*86ee64e7SAndroid Build Coastguard Worker   FileAccessor* const file_accessor = params.file_accessor ?: &default_accessor;
127*86ee64e7SAndroid Build Coastguard Worker 
128*86ee64e7SAndroid Build Coastguard Worker   std::unique_ptr<internal::ZipWriter> zip_writer;
129*86ee64e7SAndroid Build Coastguard Worker 
130*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
131*86ee64e7SAndroid Build Coastguard Worker   if (params.dest_fd != base::kInvalidPlatformFile) {
132*86ee64e7SAndroid Build Coastguard Worker     DCHECK(params.dest_file.empty());
133*86ee64e7SAndroid Build Coastguard Worker     zip_writer =
134*86ee64e7SAndroid Build Coastguard Worker         internal::ZipWriter::CreateWithFd(params.dest_fd, file_accessor);
135*86ee64e7SAndroid Build Coastguard Worker     if (!zip_writer)
136*86ee64e7SAndroid Build Coastguard Worker       return false;
137*86ee64e7SAndroid Build Coastguard Worker   }
138*86ee64e7SAndroid Build Coastguard Worker #endif
139*86ee64e7SAndroid Build Coastguard Worker 
140*86ee64e7SAndroid Build Coastguard Worker   if (!zip_writer) {
141*86ee64e7SAndroid Build Coastguard Worker     zip_writer = internal::ZipWriter::Create(params.dest_file, file_accessor);
142*86ee64e7SAndroid Build Coastguard Worker     if (!zip_writer)
143*86ee64e7SAndroid Build Coastguard Worker       return false;
144*86ee64e7SAndroid Build Coastguard Worker   }
145*86ee64e7SAndroid Build Coastguard Worker 
146*86ee64e7SAndroid Build Coastguard Worker   zip_writer->SetProgressCallback(params.progress_callback,
147*86ee64e7SAndroid Build Coastguard Worker                                   params.progress_period);
148*86ee64e7SAndroid Build Coastguard Worker   zip_writer->SetRecursive(params.recursive);
149*86ee64e7SAndroid Build Coastguard Worker   zip_writer->ContinueOnError(params.continue_on_error);
150*86ee64e7SAndroid Build Coastguard Worker 
151*86ee64e7SAndroid Build Coastguard Worker   if (!params.include_hidden_files || params.filter_callback)
152*86ee64e7SAndroid Build Coastguard Worker     zip_writer->SetFilterCallback(base::BindRepeating(
153*86ee64e7SAndroid Build Coastguard Worker         [](const ZipParams* const params, const base::FilePath& path) -> bool {
154*86ee64e7SAndroid Build Coastguard Worker           return (params->include_hidden_files || !IsHiddenFile(path)) &&
155*86ee64e7SAndroid Build Coastguard Worker                  (!params->filter_callback ||
156*86ee64e7SAndroid Build Coastguard Worker                   params->filter_callback.Run(params->src_dir.Append(path)));
157*86ee64e7SAndroid Build Coastguard Worker         },
158*86ee64e7SAndroid Build Coastguard Worker         &params));
159*86ee64e7SAndroid Build Coastguard Worker 
160*86ee64e7SAndroid Build Coastguard Worker   if (params.src_files.empty()) {
161*86ee64e7SAndroid Build Coastguard Worker     // No source items are specified. Zip the entire source directory.
162*86ee64e7SAndroid Build Coastguard Worker     zip_writer->SetRecursive(true);
163*86ee64e7SAndroid Build Coastguard Worker     if (!zip_writer->AddDirectoryContents(base::FilePath()))
164*86ee64e7SAndroid Build Coastguard Worker       return false;
165*86ee64e7SAndroid Build Coastguard Worker   } else {
166*86ee64e7SAndroid Build Coastguard Worker     // Only zip the specified source items.
167*86ee64e7SAndroid Build Coastguard Worker     if (!zip_writer->AddMixedEntries(params.src_files))
168*86ee64e7SAndroid Build Coastguard Worker       return false;
169*86ee64e7SAndroid Build Coastguard Worker   }
170*86ee64e7SAndroid Build Coastguard Worker 
171*86ee64e7SAndroid Build Coastguard Worker   return zip_writer->Close();
172*86ee64e7SAndroid Build Coastguard Worker }
173*86ee64e7SAndroid Build Coastguard Worker 
Unzip(const base::FilePath & src_file,const base::FilePath & dest_dir,UnzipOptions options)174*86ee64e7SAndroid Build Coastguard Worker bool Unzip(const base::FilePath& src_file,
175*86ee64e7SAndroid Build Coastguard Worker            const base::FilePath& dest_dir,
176*86ee64e7SAndroid Build Coastguard Worker            UnzipOptions options) {
177*86ee64e7SAndroid Build Coastguard Worker   base::File file(src_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
178*86ee64e7SAndroid Build Coastguard Worker   if (!file.IsValid()) {
179*86ee64e7SAndroid Build Coastguard Worker     PLOG(ERROR) << "Cannot open " << Redact(src_file) << ": "
180*86ee64e7SAndroid Build Coastguard Worker                 << base::File::ErrorToString(file.error_details());
181*86ee64e7SAndroid Build Coastguard Worker     return false;
182*86ee64e7SAndroid Build Coastguard Worker   }
183*86ee64e7SAndroid Build Coastguard Worker 
184*86ee64e7SAndroid Build Coastguard Worker   DLOG_IF(WARNING, !base::IsDirectoryEmpty(dest_dir))
185*86ee64e7SAndroid Build Coastguard Worker       << "ZIP extraction directory is not empty: " << dest_dir;
186*86ee64e7SAndroid Build Coastguard Worker 
187*86ee64e7SAndroid Build Coastguard Worker   return Unzip(file.GetPlatformFile(),
188*86ee64e7SAndroid Build Coastguard Worker                base::BindRepeating(&CreateFilePathWriterDelegate, dest_dir),
189*86ee64e7SAndroid Build Coastguard Worker                base::BindRepeating(&CreateDirectory, dest_dir),
190*86ee64e7SAndroid Build Coastguard Worker                std::move(options));
191*86ee64e7SAndroid Build Coastguard Worker }
192*86ee64e7SAndroid Build Coastguard Worker 
Unzip(const base::PlatformFile & src_file,WriterFactory writer_factory,DirectoryCreator directory_creator,UnzipOptions options)193*86ee64e7SAndroid Build Coastguard Worker bool Unzip(const base::PlatformFile& src_file,
194*86ee64e7SAndroid Build Coastguard Worker            WriterFactory writer_factory,
195*86ee64e7SAndroid Build Coastguard Worker            DirectoryCreator directory_creator,
196*86ee64e7SAndroid Build Coastguard Worker            UnzipOptions options) {
197*86ee64e7SAndroid Build Coastguard Worker   ZipReader reader;
198*86ee64e7SAndroid Build Coastguard Worker   reader.SetEncoding(std::move(options.encoding));
199*86ee64e7SAndroid Build Coastguard Worker   reader.SetPassword(std::move(options.password));
200*86ee64e7SAndroid Build Coastguard Worker 
201*86ee64e7SAndroid Build Coastguard Worker   if (!reader.OpenFromPlatformFile(src_file)) {
202*86ee64e7SAndroid Build Coastguard Worker     LOG(ERROR) << "Cannot open ZIP from file handle " << src_file;
203*86ee64e7SAndroid Build Coastguard Worker     return false;
204*86ee64e7SAndroid Build Coastguard Worker   }
205*86ee64e7SAndroid Build Coastguard Worker 
206*86ee64e7SAndroid Build Coastguard Worker   while (const ZipReader::Entry* const entry = reader.Next()) {
207*86ee64e7SAndroid Build Coastguard Worker     if (entry->is_unsafe) {
208*86ee64e7SAndroid Build Coastguard Worker       LOG(ERROR) << "Found unsafe entry " << Redact(entry->path) << " in ZIP";
209*86ee64e7SAndroid Build Coastguard Worker       if (!options.continue_on_error)
210*86ee64e7SAndroid Build Coastguard Worker         return false;
211*86ee64e7SAndroid Build Coastguard Worker       continue;
212*86ee64e7SAndroid Build Coastguard Worker     }
213*86ee64e7SAndroid Build Coastguard Worker 
214*86ee64e7SAndroid Build Coastguard Worker     if (options.filter && !options.filter.Run(entry->path)) {
215*86ee64e7SAndroid Build Coastguard Worker       VLOG(1) << "Skipped ZIP entry " << Redact(entry->path);
216*86ee64e7SAndroid Build Coastguard Worker       continue;
217*86ee64e7SAndroid Build Coastguard Worker     }
218*86ee64e7SAndroid Build Coastguard Worker 
219*86ee64e7SAndroid Build Coastguard Worker     if (entry->is_directory) {
220*86ee64e7SAndroid Build Coastguard Worker       // It's a directory.
221*86ee64e7SAndroid Build Coastguard Worker       if (!directory_creator.Run(entry->path)) {
222*86ee64e7SAndroid Build Coastguard Worker         LOG(ERROR) << "Cannot create directory " << Redact(entry->path);
223*86ee64e7SAndroid Build Coastguard Worker         if (!options.continue_on_error)
224*86ee64e7SAndroid Build Coastguard Worker           return false;
225*86ee64e7SAndroid Build Coastguard Worker       }
226*86ee64e7SAndroid Build Coastguard Worker 
227*86ee64e7SAndroid Build Coastguard Worker       continue;
228*86ee64e7SAndroid Build Coastguard Worker     }
229*86ee64e7SAndroid Build Coastguard Worker 
230*86ee64e7SAndroid Build Coastguard Worker     // It's a file.
231*86ee64e7SAndroid Build Coastguard Worker     std::unique_ptr<WriterDelegate> writer = writer_factory.Run(entry->path);
232*86ee64e7SAndroid Build Coastguard Worker     if (!writer ||
233*86ee64e7SAndroid Build Coastguard Worker         (options.progress ? !reader.ExtractCurrentEntryWithListener(
234*86ee64e7SAndroid Build Coastguard Worker                                 writer.get(), options.progress)
235*86ee64e7SAndroid Build Coastguard Worker                           : !reader.ExtractCurrentEntry(writer.get()))) {
236*86ee64e7SAndroid Build Coastguard Worker       LOG(ERROR) << "Cannot extract file " << Redact(entry->path)
237*86ee64e7SAndroid Build Coastguard Worker                  << " from ZIP";
238*86ee64e7SAndroid Build Coastguard Worker       if (!options.continue_on_error)
239*86ee64e7SAndroid Build Coastguard Worker         return false;
240*86ee64e7SAndroid Build Coastguard Worker     }
241*86ee64e7SAndroid Build Coastguard Worker   }
242*86ee64e7SAndroid Build Coastguard Worker 
243*86ee64e7SAndroid Build Coastguard Worker   return reader.ok();
244*86ee64e7SAndroid Build Coastguard Worker }
245*86ee64e7SAndroid Build Coastguard Worker 
ZipWithFilterCallback(const base::FilePath & src_dir,const base::FilePath & dest_file,FilterCallback filter)246*86ee64e7SAndroid Build Coastguard Worker bool ZipWithFilterCallback(const base::FilePath& src_dir,
247*86ee64e7SAndroid Build Coastguard Worker                            const base::FilePath& dest_file,
248*86ee64e7SAndroid Build Coastguard Worker                            FilterCallback filter) {
249*86ee64e7SAndroid Build Coastguard Worker   DCHECK(base::DirectoryExists(src_dir));
250*86ee64e7SAndroid Build Coastguard Worker   return Zip({.src_dir = src_dir,
251*86ee64e7SAndroid Build Coastguard Worker               .dest_file = dest_file,
252*86ee64e7SAndroid Build Coastguard Worker               .filter_callback = std::move(filter)});
253*86ee64e7SAndroid Build Coastguard Worker }
254*86ee64e7SAndroid Build Coastguard Worker 
Zip(const base::FilePath & src_dir,const base::FilePath & dest_file,bool include_hidden_files)255*86ee64e7SAndroid Build Coastguard Worker bool Zip(const base::FilePath& src_dir,
256*86ee64e7SAndroid Build Coastguard Worker          const base::FilePath& dest_file,
257*86ee64e7SAndroid Build Coastguard Worker          bool include_hidden_files) {
258*86ee64e7SAndroid Build Coastguard Worker   return Zip({.src_dir = src_dir,
259*86ee64e7SAndroid Build Coastguard Worker               .dest_file = dest_file,
260*86ee64e7SAndroid Build Coastguard Worker               .include_hidden_files = include_hidden_files});
261*86ee64e7SAndroid Build Coastguard Worker }
262*86ee64e7SAndroid Build Coastguard Worker 
263*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
ZipFiles(const base::FilePath & src_dir,Paths src_relative_paths,int dest_fd)264*86ee64e7SAndroid Build Coastguard Worker bool ZipFiles(const base::FilePath& src_dir,
265*86ee64e7SAndroid Build Coastguard Worker               Paths src_relative_paths,
266*86ee64e7SAndroid Build Coastguard Worker               int dest_fd) {
267*86ee64e7SAndroid Build Coastguard Worker   DCHECK(base::DirectoryExists(src_dir));
268*86ee64e7SAndroid Build Coastguard Worker   return Zip({.src_dir = src_dir,
269*86ee64e7SAndroid Build Coastguard Worker               .dest_fd = dest_fd,
270*86ee64e7SAndroid Build Coastguard Worker               .src_files = src_relative_paths});
271*86ee64e7SAndroid Build Coastguard Worker }
272*86ee64e7SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
273*86ee64e7SAndroid Build Coastguard Worker 
274*86ee64e7SAndroid Build Coastguard Worker }  // namespace zip
275