Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: third_party/zlib/google/zip_internal.cc

Issue 2023703002: Beginning work on GN build (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Really add //build. Add dart_bootstrap rule. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/zlib/google/zip_internal.h ('k') | third_party/zlib/google/zip_reader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/zlib/google/zip_internal.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10
11 #include "base/files/file_util.h"
12 #include "base/logging.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h"
15 #include "build/build_config.h"
16
17 #if defined(USE_SYSTEM_MINIZIP)
18 #include <minizip/ioapi.h>
19 #include <minizip/unzip.h>
20 #include <minizip/zip.h>
21 #else
22 #include "third_party/zlib/contrib/minizip/unzip.h"
23 #include "third_party/zlib/contrib/minizip/zip.h"
24 #if defined(OS_WIN)
25 #include "third_party/zlib/contrib/minizip/iowin32.h"
26 #elif defined(OS_POSIX)
27 #include "third_party/zlib/contrib/minizip/ioapi.h"
28 #endif // defined(OS_POSIX)
29 #endif // defined(USE_SYSTEM_MINIZIP)
30
31 namespace {
32
33 #if defined(OS_WIN)
34 typedef struct {
35 HANDLE hf;
36 int error;
37 } WIN32FILE_IOWIN;
38
39 // This function is derived from third_party/minizip/iowin32.c.
40 // Its only difference is that it treats the char* as UTF8 and
41 // uses the Unicode version of CreateFile.
42 void* ZipOpenFunc(void *opaque, const char* filename, int mode) {
43 DWORD desired_access = 0, creation_disposition = 0;
44 DWORD share_mode = 0, flags_and_attributes = 0;
45 HANDLE file = 0;
46 void* ret = NULL;
47
48 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
49 desired_access = GENERIC_READ;
50 creation_disposition = OPEN_EXISTING;
51 share_mode = FILE_SHARE_READ;
52 } else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
53 desired_access = GENERIC_WRITE | GENERIC_READ;
54 creation_disposition = OPEN_EXISTING;
55 } else if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
56 desired_access = GENERIC_WRITE | GENERIC_READ;
57 creation_disposition = CREATE_ALWAYS;
58 }
59
60 base::string16 filename16 = base::UTF8ToUTF16(filename);
61 if ((filename != NULL) && (desired_access != 0)) {
62 file = CreateFile(filename16.c_str(), desired_access, share_mode,
63 NULL, creation_disposition, flags_and_attributes, NULL);
64 }
65
66 if (file == INVALID_HANDLE_VALUE)
67 file = NULL;
68
69 if (file != NULL) {
70 WIN32FILE_IOWIN file_ret;
71 file_ret.hf = file;
72 file_ret.error = 0;
73 ret = malloc(sizeof(WIN32FILE_IOWIN));
74 if (ret == NULL)
75 CloseHandle(file);
76 else
77 *(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
78 }
79 return ret;
80 }
81 #endif
82
83 #if defined(OS_POSIX)
84 // Callback function for zlib that opens a file stream from a file descriptor.
85 // Since we do not own the file descriptor, dup it so that we can fdopen/fclose
86 // a file stream.
87 void* FdOpenFileFunc(void* opaque, const char* filename, int mode) {
88 FILE* file = NULL;
89 const char* mode_fopen = NULL;
90
91 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
92 mode_fopen = "rb";
93 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
94 mode_fopen = "r+b";
95 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
96 mode_fopen = "wb";
97
98 if ((filename != NULL) && (mode_fopen != NULL)) {
99 int fd = dup(*static_cast<int*>(opaque));
100 if (fd != -1)
101 file = fdopen(fd, mode_fopen);
102 }
103
104 return file;
105 }
106
107 int FdCloseFileFunc(void* opaque, void* stream) {
108 fclose(static_cast<FILE*>(stream));
109 free(opaque); // malloc'ed in FillFdOpenFileFunc()
110 return 0;
111 }
112
113 // Fills |pzlib_filecunc_def| appropriately to handle the zip file
114 // referred to by |fd|.
115 void FillFdOpenFileFunc(zlib_filefunc_def* pzlib_filefunc_def, int fd) {
116 fill_fopen_filefunc(pzlib_filefunc_def);
117 pzlib_filefunc_def->zopen_file = FdOpenFileFunc;
118 pzlib_filefunc_def->zclose_file = FdCloseFileFunc;
119 int* ptr_fd = static_cast<int*>(malloc(sizeof(fd)));
120 *ptr_fd = fd;
121 pzlib_filefunc_def->opaque = ptr_fd;
122 }
123 #endif // defined(OS_POSIX)
124
125 #if defined(OS_WIN)
126 // Callback function for zlib that opens a file stream from a Windows handle.
127 // Does not take ownership of the handle.
128 void* HandleOpenFileFunc(void* opaque, const char* filename, int mode) {
129 WIN32FILE_IOWIN file_ret;
130 file_ret.hf = static_cast<HANDLE>(opaque);
131 file_ret.error = 0;
132 if (file_ret.hf == INVALID_HANDLE_VALUE)
133 return NULL;
134
135 void* ret = malloc(sizeof(WIN32FILE_IOWIN));
136 if (ret != NULL)
137 *(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
138 return ret;
139 }
140
141 int HandleCloseFileFunc(void* opaque, void* stream) {
142 free(stream); // malloc'ed in HandleOpenFileFunc()
143 return 0;
144 }
145 #endif
146
147 // A struct that contains data required for zlib functions to extract files from
148 // a zip archive stored in memory directly. The following I/O API functions
149 // expect their opaque parameters refer to this struct.
150 struct ZipBuffer {
151 const char* data; // weak
152 size_t length;
153 size_t offset;
154 };
155
156 // Opens the specified file. When this function returns a non-NULL pointer, zlib
157 // uses this pointer as a stream parameter while compressing or uncompressing
158 // data. (Returning NULL represents an error.) This function initializes the
159 // given opaque parameter and returns it because this parameter stores all
160 // information needed for uncompressing data. (This function does not support
161 // writing compressed data and it returns NULL for this case.)
162 void* OpenZipBuffer(void* opaque, const char* /*filename*/, int mode) {
163 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) != ZLIB_FILEFUNC_MODE_READ) {
164 NOTREACHED();
165 return NULL;
166 }
167 ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
168 if (!buffer || !buffer->data || !buffer->length)
169 return NULL;
170 buffer->offset = 0;
171 return opaque;
172 }
173
174 // Reads compressed data from the specified stream. This function copies data
175 // refered by the opaque parameter and returns the size actually copied.
176 uLong ReadZipBuffer(void* opaque, void* /*stream*/, void* buf, uLong size) {
177 ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
178 DCHECK_LE(buffer->offset, buffer->length);
179 size_t remaining_bytes = buffer->length - buffer->offset;
180 if (!buffer || !buffer->data || !remaining_bytes)
181 return 0;
182 size = std::min(size, static_cast<uLong>(remaining_bytes));
183 memcpy(buf, &buffer->data[buffer->offset], size);
184 buffer->offset += size;
185 return size;
186 }
187
188 // Writes compressed data to the stream. This function always returns zero
189 // because this implementation is only for reading compressed data.
190 uLong WriteZipBuffer(void* /*opaque*/,
191 void* /*stream*/,
192 const void* /*buf*/,
193 uLong /*size*/) {
194 NOTREACHED();
195 return 0;
196 }
197
198 // Returns the offset from the beginning of the data.
199 long GetOffsetOfZipBuffer(void* opaque, void* /*stream*/) {
200 ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
201 if (!buffer)
202 return -1;
203 return static_cast<long>(buffer->offset);
204 }
205
206 // Moves the current offset to the specified position.
207 long SeekZipBuffer(void* opaque, void* /*stream*/, uLong offset, int origin) {
208 ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque);
209 if (!buffer)
210 return -1;
211 if (origin == ZLIB_FILEFUNC_SEEK_CUR) {
212 buffer->offset = std::min(buffer->offset + static_cast<size_t>(offset),
213 buffer->length);
214 return 0;
215 }
216 if (origin == ZLIB_FILEFUNC_SEEK_END) {
217 buffer->offset = (buffer->length > offset) ? buffer->length - offset : 0;
218 return 0;
219 }
220 if (origin == ZLIB_FILEFUNC_SEEK_SET) {
221 buffer->offset = std::min(buffer->length, static_cast<size_t>(offset));
222 return 0;
223 }
224 NOTREACHED();
225 return -1;
226 }
227
228 // Closes the input offset and deletes all resources used for compressing or
229 // uncompressing data. This function deletes the ZipBuffer object referred by
230 // the opaque parameter since zlib deletes the unzFile object and it does not
231 // use this object any longer.
232 int CloseZipBuffer(void* opaque, void* /*stream*/) {
233 if (opaque)
234 free(opaque);
235 return 0;
236 }
237
238 // Returns the last error happened when reading or writing data. This function
239 // always returns zero, which means there are not any errors.
240 int GetErrorOfZipBuffer(void* /*opaque*/, void* /*stream*/) {
241 return 0;
242 }
243
244 // Returns a zip_fileinfo struct with the time represented by |file_time|.
245 zip_fileinfo TimeToZipFileInfo(const base::Time& file_time) {
246 base::Time::Exploded file_time_parts;
247 file_time.LocalExplode(&file_time_parts);
248
249 zip_fileinfo zip_info = {};
250 if (file_time_parts.year >= 1980) {
251 // This if check works around the handling of the year value in
252 // contrib/minizip/zip.c in function zip64local_TmzDateToDosDate
253 // It assumes that dates below 1980 are in the double digit format.
254 // Hence the fail safe option is to leave the date unset. Some programs
255 // might show the unset date as 1980-0-0 which is invalid.
256 zip_info.tmz_date.tm_year = file_time_parts.year;
257 zip_info.tmz_date.tm_mon = file_time_parts.month - 1;
258 zip_info.tmz_date.tm_mday = file_time_parts.day_of_month;
259 zip_info.tmz_date.tm_hour = file_time_parts.hour;
260 zip_info.tmz_date.tm_min = file_time_parts.minute;
261 zip_info.tmz_date.tm_sec = file_time_parts.second;
262 }
263
264 return zip_info;
265 }
266 } // namespace
267
268 namespace zip {
269 namespace internal {
270
271 unzFile OpenForUnzipping(const std::string& file_name_utf8) {
272 zlib_filefunc_def* zip_func_ptrs = NULL;
273 #if defined(OS_WIN)
274 zlib_filefunc_def zip_funcs;
275 fill_win32_filefunc(&zip_funcs);
276 zip_funcs.zopen_file = ZipOpenFunc;
277 zip_func_ptrs = &zip_funcs;
278 #endif
279 return unzOpen2(file_name_utf8.c_str(), zip_func_ptrs);
280 }
281
282 #if defined(OS_POSIX)
283 unzFile OpenFdForUnzipping(int zip_fd) {
284 zlib_filefunc_def zip_funcs;
285 FillFdOpenFileFunc(&zip_funcs, zip_fd);
286 // Passing dummy "fd" filename to zlib.
287 return unzOpen2("fd", &zip_funcs);
288 }
289 #endif
290
291 #if defined(OS_WIN)
292 unzFile OpenHandleForUnzipping(HANDLE zip_handle) {
293 zlib_filefunc_def zip_funcs;
294 fill_win32_filefunc(&zip_funcs);
295 zip_funcs.zopen_file = HandleOpenFileFunc;
296 zip_funcs.zclose_file = HandleCloseFileFunc;
297 zip_funcs.opaque = zip_handle;
298 return unzOpen2("fd", &zip_funcs);
299 }
300 #endif
301
302 // static
303 unzFile PrepareMemoryForUnzipping(const std::string& data) {
304 if (data.empty())
305 return NULL;
306
307 ZipBuffer* buffer = static_cast<ZipBuffer*>(malloc(sizeof(ZipBuffer)));
308 if (!buffer)
309 return NULL;
310 buffer->data = data.data();
311 buffer->length = data.length();
312 buffer->offset = 0;
313
314 zlib_filefunc_def zip_functions;
315 zip_functions.zopen_file = OpenZipBuffer;
316 zip_functions.zread_file = ReadZipBuffer;
317 zip_functions.zwrite_file = WriteZipBuffer;
318 zip_functions.ztell_file = GetOffsetOfZipBuffer;
319 zip_functions.zseek_file = SeekZipBuffer;
320 zip_functions.zclose_file = CloseZipBuffer;
321 zip_functions.zerror_file = GetErrorOfZipBuffer;
322 zip_functions.opaque = static_cast<void*>(buffer);
323 return unzOpen2(NULL, &zip_functions);
324 }
325
326 zipFile OpenForZipping(const std::string& file_name_utf8, int append_flag) {
327 zlib_filefunc_def* zip_func_ptrs = NULL;
328 #if defined(OS_WIN)
329 zlib_filefunc_def zip_funcs;
330 fill_win32_filefunc(&zip_funcs);
331 zip_funcs.zopen_file = ZipOpenFunc;
332 zip_func_ptrs = &zip_funcs;
333 #endif
334 return zipOpen2(file_name_utf8.c_str(),
335 append_flag,
336 NULL, // global comment
337 zip_func_ptrs);
338 }
339
340 #if defined(OS_POSIX)
341 zipFile OpenFdForZipping(int zip_fd, int append_flag) {
342 zlib_filefunc_def zip_funcs;
343 FillFdOpenFileFunc(&zip_funcs, zip_fd);
344 // Passing dummy "fd" filename to zlib.
345 return zipOpen2("fd", append_flag, NULL, &zip_funcs);
346 }
347 #endif
348
349 zip_fileinfo GetFileInfoForZipping(const base::FilePath& path) {
350 base::Time file_time;
351 base::File::Info file_info;
352 if (base::GetFileInfo(path, &file_info))
353 file_time = file_info.last_modified;
354 return TimeToZipFileInfo(file_time);
355 }
356
357 bool ZipOpenNewFileInZip(zipFile zip_file,
358 const std::string& str_path,
359 const zip_fileinfo* file_info) {
360 // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT
361 // Setting the Language encoding flag so the file is told to be in utf-8.
362 const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11;
363
364 if (ZIP_OK != zipOpenNewFileInZip4(
365 zip_file, // file
366 str_path.c_str(), // filename
367 file_info, // zipfi
368 NULL, // extrafield_local,
369 0u, // size_extrafield_local
370 NULL, // extrafield_global
371 0u, // size_extrafield_global
372 NULL, // comment
373 Z_DEFLATED, // method
374 Z_DEFAULT_COMPRESSION, // level
375 0, // raw
376 -MAX_WBITS, // windowBits
377 DEF_MEM_LEVEL, // memLevel
378 Z_DEFAULT_STRATEGY, // strategy
379 NULL, // password
380 0, // crcForCrypting
381 0, // versionMadeBy
382 LANGUAGE_ENCODING_FLAG)) { // flagBase
383 DLOG(ERROR) << "Could not open zip file entry " << str_path;
384 return false;
385 }
386 return true;
387 }
388
389 } // namespace internal
390 } // namespace zip
OLDNEW
« no previous file with comments | « third_party/zlib/google/zip_internal.h ('k') | third_party/zlib/google/zip_reader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698