OR-Tools  9.6
zipfile.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // Interface for mapping the contents of a zipfile.
15 // You open a zip file archive by using the OpenZipArchive() method, which
16 // returns a shared_ptr to a ZipArchive object that maps its contents into the
17 // "/zip/" namespace. During the duration of the existence of the ZipArchive
18 // object, paths under it are available for File operations.
19 //
20 // Only a single ZipArchive will be opened for any unique path; all of the
21 // returned shared_ptrs will point to the same underlying ZipArchive object.
22 // The contents of the ZipArchive will remain mapped into the /zip/ namespace
23 // until the last shared_ptr is destroyed and its underlying object is
24 // released.
25 //
26 // To map the contents of zip file "/foo/bar.zip", use the following:
27 // {
28 // std::shared_ptr<zipfile::ZipArchive> zip_archive(
29 // zipfile::OpenZipArchive("/foo/bar.zip"));
30 // if (zip_archive == nullptr) {
31 // // Handle error
32 // }
33 //
34 // // Do interesting things with paths under "/zip/foo/bar.zip/..."
35 // }
36 //
37 // Paths in the zip file are available until the last shared_ptr to the
38 // ZipArchive object is released.
39 //
40 // You can use this pattern to read files from a Zip archive:
41 // {
42 // std::shared_ptr<zipfile::ZipArchive> zip_archive(
43 // zipfile::OpenZipArchive(filename));
44 // if (zip_archive == nullptr) {
45 // // Do not continue execution of the example code.
46 // }
47 // vector<string> files;
48 // absl::Status status = file::Match(file::JoinPath("/zip", filename, "*"),
49 // &files, file::Defaults());
50 // if (!status.ok()) {
51 // // Do not continue execution.
52 // }
53 // for (const string& fn : files) {
54 // File* f;
55 // absl::Status status = file::Open(fn, "r", &f, file::Defaults());
56 // if (!status.ok()) {
57 // // Handle error: abort, return, or continue.
58 // }
59 // DoStuffWithFile(f);
60 // status = f->Close();
61 // if (!status.ok()) {
62 // // Handle error: abort, return, or continue.
63 // }
64 // }
65 // }
66 
67 #ifndef OR_TOOLS_BASE_ZIPFILE_H_
68 #define OR_TOOLS_BASE_ZIPFILE_H_
69 
70 #include <memory>
71 #include <optional>
72 #include <string>
73 
74 #include "absl/strings/string_view.h"
75 
76 namespace zipfile {
77 
78 // Performance hint: Specify what order you expect to visit the data
79 // in the file.
80 enum class AccessPattern {
81  // Keep whatever is default for your system (typically same as NORMAL).
82  ACCESS_NONE = 0,
83  // Moderate prefetching as the file gets accessed.
84  ACCESS_NORMAL = 1,
85  // No prefetching to be done, use this for random access.
86  ACCESS_RANDOM = 2,
87  // Aggressive prefetching on reads.
89 };
90 
91 class ZipArchive;
92 
93 // An options struct to be provided when opening a zip archive:
94 //
95 // `access_pattern`, possible values:
96 // NORMAL: Will use a small InputBuffer to cache small files, raw access to
97 // big files.
98 // RANDOM: Do not do any caching at all.
99 // SEQUENTIAL: Always use a (big) InputBuffer to cache read access.
100 // SEQUENTIAL mode
101 //
102 // `zip_bomb_max_ratio`, if greater than zero, indicates the maximum
103 // compression ratio to allow on any file in the zip archive. This can be used
104 // to reject files containing decompression bombs. A value of 0 disables zip
105 // bomb checking.
106 //
107 // `zip_bomb_max_size`, if greater than zero, indicates the maximum
108 // decompressed file size that is allowed on any file in the zip archive. This
109 // is an additional layer of protection against zip bombs in addition to the
110 // zip_bomb_max_ratio
113  std::optional<size_t> zip_bomb_max_ratio = std::nullopt;
114  std::optional<size_t> zip_bomb_max_size = std::nullopt;
115 };
116 
117 // Open and return a ZipArchive. This maps the files in PATH into the /zip/
118 // namespace, and they will exist there until the ZipArchive is destroyed.
119 // If the archive is already opened, or opening it fails for some reason,
120 // nullptr will be returned.
121 //
122 // The path given to OpenZipArchive must be absolute.
123 // The ZipArchive can only be used for reading zipfile contents. To modify
124 // zip file contents, use ZipFileWriter from file/zipfile/zipfilewriter.h.
125 //
126 // The value of the returned shared_ptr may be nullptr if there is an
127 // error opening the archive. This may be caused by corruption, errors
128 // finding or opening the file, or any other problem which prevents the archive
129 // from being read.
130 //
131 // Note: Writing to an open ZipArchive will fail in strange and mysterious
132 // ways. You have been warned.
133 // The input options argument provides controls over zip bombs as well as
134 // access pattern controls
135 std::shared_ptr<ZipArchive> OpenZipArchive(absl::string_view path,
136  const ZipFileOptions& options);
137 
138 inline std::shared_ptr<ZipArchive> OpenZipArchive(absl::string_view path) {
139  ZipFileOptions options;
140  return OpenZipArchive(path, options);
141 }
142 
143 // A zip archive, which may contain files that can be read through the /zip
144 // filename prefix.
145 //
146 // Do not instantiate this class directly. Use the OpenZipArchive factory
147 // methods instead.
148 class ZipArchive {
149  public:
150  ZipArchive(absl::string_view path, const ZipFileOptions& options);
151 
152  ZipArchive(const ZipArchive&) = delete;
153  ZipArchive& operator=(const ZipArchive&) = delete;
154 
155  // Returns the filename at which this archive was first opened. Since all
156  // equivalent zip archive paths share the same archive, this name will not
157  // necessarily match the name at which the archive was opened. For example,
158  // we provide no guarantees about whether the filename will begin with "/zip",
159  // since the "/zip" prefix is optional for opening zip archives.
160  const std::string& filename() const { return filename_; }
161 
162  ~ZipArchive();
163 
164  private:
165  std::string filename_;
166  ZipFileOptions options_;
167 };
168 
169 }; // namespace zipfile
170 
171 #endif // OR_TOOLS_BASE_ZIPFILE_H_
ZipArchive & operator=(const ZipArchive &)=delete
ZipArchive(absl::string_view path, const ZipFileOptions &options)
Definition: zipfile.cc:39
const std::string & filename() const
Definition: zipfile.h:160
ZipArchive(const ZipArchive &)=delete
AccessPattern
Definition: zipfile.h:80
std::shared_ptr< ZipArchive > OpenZipArchive(absl::string_view path, const ZipFileOptions &options)
Definition: zipfile.cc:32
std::optional< size_t > zip_bomb_max_size
Definition: zipfile.h:114
std::optional< size_t > zip_bomb_max_ratio
Definition: zipfile.h:113
AccessPattern access_pattern
Definition: zipfile.h:112