11cb0ef41Sopenharmony_ci// Copyright 2011 The Chromium Authors 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "third_party/zlib/google/zip_internal.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <stddef.h> 81cb0ef41Sopenharmony_ci#include <string.h> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include <algorithm> 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "base/containers/fixed_flat_set.h" 131cb0ef41Sopenharmony_ci#include "base/files/file_path.h" 141cb0ef41Sopenharmony_ci#include "base/logging.h" 151cb0ef41Sopenharmony_ci#include "base/notreached.h" 161cb0ef41Sopenharmony_ci#include "base/strings/string_piece.h" 171cb0ef41Sopenharmony_ci#include "base/strings/string_util.h" 181cb0ef41Sopenharmony_ci#include "base/strings/utf_string_conversions.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci#if defined(USE_SYSTEM_MINIZIP) 211cb0ef41Sopenharmony_ci#include <minizip/ioapi.h> 221cb0ef41Sopenharmony_ci#include <minizip/unzip.h> 231cb0ef41Sopenharmony_ci#include <minizip/zip.h> 241cb0ef41Sopenharmony_ci#else 251cb0ef41Sopenharmony_ci#include "third_party/zlib/contrib/minizip/unzip.h" 261cb0ef41Sopenharmony_ci#include "third_party/zlib/contrib/minizip/zip.h" 271cb0ef41Sopenharmony_ci#if defined(OS_WIN) 281cb0ef41Sopenharmony_ci#include "third_party/zlib/contrib/minizip/iowin32.h" 291cb0ef41Sopenharmony_ci#elif defined(OS_POSIX) 301cb0ef41Sopenharmony_ci#include "third_party/zlib/contrib/minizip/ioapi.h" 311cb0ef41Sopenharmony_ci#endif // defined(OS_POSIX) 321cb0ef41Sopenharmony_ci#endif // defined(USE_SYSTEM_MINIZIP) 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cinamespace { 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci#if defined(OS_WIN) 371cb0ef41Sopenharmony_citypedef struct { 381cb0ef41Sopenharmony_ci HANDLE hf; 391cb0ef41Sopenharmony_ci int error; 401cb0ef41Sopenharmony_ci} WIN32FILE_IOWIN; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci// This function is derived from third_party/minizip/iowin32.c. 431cb0ef41Sopenharmony_ci// Its only difference is that it treats the filename as UTF-8 and 441cb0ef41Sopenharmony_ci// uses the Unicode version of CreateFile. 451cb0ef41Sopenharmony_civoid* ZipOpenFunc(void* opaque, const void* filename, int mode) { 461cb0ef41Sopenharmony_ci DWORD desired_access = 0, creation_disposition = 0; 471cb0ef41Sopenharmony_ci DWORD share_mode = 0, flags_and_attributes = 0; 481cb0ef41Sopenharmony_ci HANDLE file = 0; 491cb0ef41Sopenharmony_ci void* ret = NULL; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) { 521cb0ef41Sopenharmony_ci desired_access = GENERIC_READ; 531cb0ef41Sopenharmony_ci creation_disposition = OPEN_EXISTING; 541cb0ef41Sopenharmony_ci share_mode = FILE_SHARE_READ; 551cb0ef41Sopenharmony_ci } else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) { 561cb0ef41Sopenharmony_ci desired_access = GENERIC_WRITE | GENERIC_READ; 571cb0ef41Sopenharmony_ci creation_disposition = OPEN_EXISTING; 581cb0ef41Sopenharmony_ci } else if (mode & ZLIB_FILEFUNC_MODE_CREATE) { 591cb0ef41Sopenharmony_ci desired_access = GENERIC_WRITE | GENERIC_READ; 601cb0ef41Sopenharmony_ci creation_disposition = CREATE_ALWAYS; 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci if (filename != nullptr && desired_access != 0) { 641cb0ef41Sopenharmony_ci file = CreateFileW( 651cb0ef41Sopenharmony_ci base::UTF8ToWide(static_cast<const char*>(filename)).c_str(), 661cb0ef41Sopenharmony_ci desired_access, share_mode, nullptr, creation_disposition, 671cb0ef41Sopenharmony_ci flags_and_attributes, nullptr); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci if (file == INVALID_HANDLE_VALUE) 711cb0ef41Sopenharmony_ci file = NULL; 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci if (file != NULL) { 741cb0ef41Sopenharmony_ci WIN32FILE_IOWIN file_ret; 751cb0ef41Sopenharmony_ci file_ret.hf = file; 761cb0ef41Sopenharmony_ci file_ret.error = 0; 771cb0ef41Sopenharmony_ci ret = malloc(sizeof(WIN32FILE_IOWIN)); 781cb0ef41Sopenharmony_ci if (ret == NULL) 791cb0ef41Sopenharmony_ci CloseHandle(file); 801cb0ef41Sopenharmony_ci else 811cb0ef41Sopenharmony_ci *(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret; 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci return ret; 841cb0ef41Sopenharmony_ci} 851cb0ef41Sopenharmony_ci#endif 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci#if defined(OS_POSIX) || defined(OS_FUCHSIA) 881cb0ef41Sopenharmony_ci// Callback function for zlib that opens a file stream from a file descriptor. 891cb0ef41Sopenharmony_ci// Since we do not own the file descriptor, dup it so that we can fdopen/fclose 901cb0ef41Sopenharmony_ci// a file stream. 911cb0ef41Sopenharmony_civoid* FdOpenFileFunc(void* opaque, const void* filename, int mode) { 921cb0ef41Sopenharmony_ci FILE* file = NULL; 931cb0ef41Sopenharmony_ci const char* mode_fopen = NULL; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) 961cb0ef41Sopenharmony_ci mode_fopen = "rb"; 971cb0ef41Sopenharmony_ci else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 981cb0ef41Sopenharmony_ci mode_fopen = "r+b"; 991cb0ef41Sopenharmony_ci else if (mode & ZLIB_FILEFUNC_MODE_CREATE) 1001cb0ef41Sopenharmony_ci mode_fopen = "wb"; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci if ((filename != NULL) && (mode_fopen != NULL)) { 1031cb0ef41Sopenharmony_ci int fd = dup(*static_cast<int*>(opaque)); 1041cb0ef41Sopenharmony_ci if (fd != -1) 1051cb0ef41Sopenharmony_ci file = fdopen(fd, mode_fopen); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci return file; 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ciint FdCloseFileFunc(void* opaque, void* stream) { 1121cb0ef41Sopenharmony_ci fclose(static_cast<FILE*>(stream)); 1131cb0ef41Sopenharmony_ci free(opaque); // malloc'ed in FillFdOpenFileFunc() 1141cb0ef41Sopenharmony_ci return 0; 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci// Fills |pzlib_filecunc_def| appropriately to handle the zip file 1181cb0ef41Sopenharmony_ci// referred to by |fd|. 1191cb0ef41Sopenharmony_civoid FillFdOpenFileFunc(zlib_filefunc64_def* pzlib_filefunc_def, int fd) { 1201cb0ef41Sopenharmony_ci fill_fopen64_filefunc(pzlib_filefunc_def); 1211cb0ef41Sopenharmony_ci pzlib_filefunc_def->zopen64_file = FdOpenFileFunc; 1221cb0ef41Sopenharmony_ci pzlib_filefunc_def->zclose_file = FdCloseFileFunc; 1231cb0ef41Sopenharmony_ci int* ptr_fd = static_cast<int*>(malloc(sizeof(fd))); 1241cb0ef41Sopenharmony_ci *ptr_fd = fd; 1251cb0ef41Sopenharmony_ci pzlib_filefunc_def->opaque = ptr_fd; 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci#endif // defined(OS_POSIX) 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci#if defined(OS_WIN) 1301cb0ef41Sopenharmony_ci// Callback function for zlib that opens a file stream from a Windows handle. 1311cb0ef41Sopenharmony_ci// Does not take ownership of the handle. 1321cb0ef41Sopenharmony_civoid* HandleOpenFileFunc(void* opaque, const void* /*filename*/, int mode) { 1331cb0ef41Sopenharmony_ci WIN32FILE_IOWIN file_ret; 1341cb0ef41Sopenharmony_ci file_ret.hf = static_cast<HANDLE>(opaque); 1351cb0ef41Sopenharmony_ci file_ret.error = 0; 1361cb0ef41Sopenharmony_ci if (file_ret.hf == INVALID_HANDLE_VALUE) 1371cb0ef41Sopenharmony_ci return NULL; 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci void* ret = malloc(sizeof(WIN32FILE_IOWIN)); 1401cb0ef41Sopenharmony_ci if (ret != NULL) 1411cb0ef41Sopenharmony_ci *(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret; 1421cb0ef41Sopenharmony_ci return ret; 1431cb0ef41Sopenharmony_ci} 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ciint HandleCloseFileFunc(void* opaque, void* stream) { 1461cb0ef41Sopenharmony_ci free(stream); // malloc'ed in HandleOpenFileFunc() 1471cb0ef41Sopenharmony_ci return 0; 1481cb0ef41Sopenharmony_ci} 1491cb0ef41Sopenharmony_ci#endif 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci// A struct that contains data required for zlib functions to extract files from 1521cb0ef41Sopenharmony_ci// a zip archive stored in memory directly. The following I/O API functions 1531cb0ef41Sopenharmony_ci// expect their opaque parameters refer to this struct. 1541cb0ef41Sopenharmony_cistruct ZipBuffer { 1551cb0ef41Sopenharmony_ci const char* data; // weak 1561cb0ef41Sopenharmony_ci ZPOS64_T length; 1571cb0ef41Sopenharmony_ci ZPOS64_T offset; 1581cb0ef41Sopenharmony_ci}; 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci// Opens the specified file. When this function returns a non-NULL pointer, zlib 1611cb0ef41Sopenharmony_ci// uses this pointer as a stream parameter while compressing or uncompressing 1621cb0ef41Sopenharmony_ci// data. (Returning NULL represents an error.) This function initializes the 1631cb0ef41Sopenharmony_ci// given opaque parameter and returns it because this parameter stores all 1641cb0ef41Sopenharmony_ci// information needed for uncompressing data. (This function does not support 1651cb0ef41Sopenharmony_ci// writing compressed data and it returns NULL for this case.) 1661cb0ef41Sopenharmony_civoid* OpenZipBuffer(void* opaque, const void* /*filename*/, int mode) { 1671cb0ef41Sopenharmony_ci if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) != ZLIB_FILEFUNC_MODE_READ) { 1681cb0ef41Sopenharmony_ci NOTREACHED(); 1691cb0ef41Sopenharmony_ci return NULL; 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque); 1721cb0ef41Sopenharmony_ci if (!buffer || !buffer->data || !buffer->length) 1731cb0ef41Sopenharmony_ci return NULL; 1741cb0ef41Sopenharmony_ci buffer->offset = 0; 1751cb0ef41Sopenharmony_ci return opaque; 1761cb0ef41Sopenharmony_ci} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci// Reads compressed data from the specified stream. This function copies data 1791cb0ef41Sopenharmony_ci// refered by the opaque parameter and returns the size actually copied. 1801cb0ef41Sopenharmony_ciuLong ReadZipBuffer(void* opaque, void* /*stream*/, void* buf, uLong size) { 1811cb0ef41Sopenharmony_ci ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque); 1821cb0ef41Sopenharmony_ci DCHECK_LE(buffer->offset, buffer->length); 1831cb0ef41Sopenharmony_ci ZPOS64_T remaining_bytes = buffer->length - buffer->offset; 1841cb0ef41Sopenharmony_ci if (!buffer || !buffer->data || !remaining_bytes) 1851cb0ef41Sopenharmony_ci return 0; 1861cb0ef41Sopenharmony_ci if (size > remaining_bytes) 1871cb0ef41Sopenharmony_ci size = remaining_bytes; 1881cb0ef41Sopenharmony_ci memcpy(buf, &buffer->data[buffer->offset], size); 1891cb0ef41Sopenharmony_ci buffer->offset += size; 1901cb0ef41Sopenharmony_ci return size; 1911cb0ef41Sopenharmony_ci} 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci// Writes compressed data to the stream. This function always returns zero 1941cb0ef41Sopenharmony_ci// because this implementation is only for reading compressed data. 1951cb0ef41Sopenharmony_ciuLong WriteZipBuffer(void* /*opaque*/, 1961cb0ef41Sopenharmony_ci void* /*stream*/, 1971cb0ef41Sopenharmony_ci const void* /*buf*/, 1981cb0ef41Sopenharmony_ci uLong /*size*/) { 1991cb0ef41Sopenharmony_ci NOTREACHED(); 2001cb0ef41Sopenharmony_ci return 0; 2011cb0ef41Sopenharmony_ci} 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci// Returns the offset from the beginning of the data. 2041cb0ef41Sopenharmony_ciZPOS64_T GetOffsetOfZipBuffer(void* opaque, void* /*stream*/) { 2051cb0ef41Sopenharmony_ci ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque); 2061cb0ef41Sopenharmony_ci if (!buffer) 2071cb0ef41Sopenharmony_ci return -1; 2081cb0ef41Sopenharmony_ci return buffer->offset; 2091cb0ef41Sopenharmony_ci} 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci// Moves the current offset to the specified position. 2121cb0ef41Sopenharmony_cilong SeekZipBuffer(void* opaque, 2131cb0ef41Sopenharmony_ci void* /*stream*/, 2141cb0ef41Sopenharmony_ci ZPOS64_T offset, 2151cb0ef41Sopenharmony_ci int origin) { 2161cb0ef41Sopenharmony_ci ZipBuffer* buffer = static_cast<ZipBuffer*>(opaque); 2171cb0ef41Sopenharmony_ci if (!buffer) 2181cb0ef41Sopenharmony_ci return -1; 2191cb0ef41Sopenharmony_ci if (origin == ZLIB_FILEFUNC_SEEK_CUR) { 2201cb0ef41Sopenharmony_ci buffer->offset = std::min(buffer->offset + offset, buffer->length); 2211cb0ef41Sopenharmony_ci return 0; 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci if (origin == ZLIB_FILEFUNC_SEEK_END) { 2241cb0ef41Sopenharmony_ci buffer->offset = (buffer->length > offset) ? buffer->length - offset : 0; 2251cb0ef41Sopenharmony_ci return 0; 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci if (origin == ZLIB_FILEFUNC_SEEK_SET) { 2281cb0ef41Sopenharmony_ci buffer->offset = std::min(buffer->length, offset); 2291cb0ef41Sopenharmony_ci return 0; 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci NOTREACHED(); 2321cb0ef41Sopenharmony_ci return -1; 2331cb0ef41Sopenharmony_ci} 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci// Closes the input offset and deletes all resources used for compressing or 2361cb0ef41Sopenharmony_ci// uncompressing data. This function deletes the ZipBuffer object referred by 2371cb0ef41Sopenharmony_ci// the opaque parameter since zlib deletes the unzFile object and it does not 2381cb0ef41Sopenharmony_ci// use this object any longer. 2391cb0ef41Sopenharmony_ciint CloseZipBuffer(void* opaque, void* /*stream*/) { 2401cb0ef41Sopenharmony_ci if (opaque) 2411cb0ef41Sopenharmony_ci free(opaque); 2421cb0ef41Sopenharmony_ci return 0; 2431cb0ef41Sopenharmony_ci} 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci// Returns the last error happened when reading or writing data. This function 2461cb0ef41Sopenharmony_ci// always returns zero, which means there are not any errors. 2471cb0ef41Sopenharmony_ciint GetErrorOfZipBuffer(void* /*opaque*/, void* /*stream*/) { 2481cb0ef41Sopenharmony_ci return 0; 2491cb0ef41Sopenharmony_ci} 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci// Returns a zip_fileinfo struct with the time represented by |file_time|. 2521cb0ef41Sopenharmony_cizip_fileinfo TimeToZipFileInfo(const base::Time& file_time) { 2531cb0ef41Sopenharmony_ci base::Time::Exploded file_time_parts; 2541cb0ef41Sopenharmony_ci file_time.UTCExplode(&file_time_parts); 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci zip_fileinfo zip_info = {}; 2571cb0ef41Sopenharmony_ci if (file_time_parts.year >= 1980) { 2581cb0ef41Sopenharmony_ci // This if check works around the handling of the year value in 2591cb0ef41Sopenharmony_ci // contrib/minizip/zip.c in function zip64local_TmzDateToDosDate 2601cb0ef41Sopenharmony_ci // It assumes that dates below 1980 are in the double digit format. 2611cb0ef41Sopenharmony_ci // Hence the fail safe option is to leave the date unset. Some programs 2621cb0ef41Sopenharmony_ci // might show the unset date as 1980-0-0 which is invalid. 2631cb0ef41Sopenharmony_ci zip_info.tmz_date = { 2641cb0ef41Sopenharmony_ci .tm_sec = static_cast<uInt>(file_time_parts.second), 2651cb0ef41Sopenharmony_ci .tm_min = static_cast<uInt>(file_time_parts.minute), 2661cb0ef41Sopenharmony_ci .tm_hour = static_cast<uInt>(file_time_parts.hour), 2671cb0ef41Sopenharmony_ci .tm_mday = static_cast<uInt>(file_time_parts.day_of_month), 2681cb0ef41Sopenharmony_ci .tm_mon = static_cast<uInt>(file_time_parts.month - 1), 2691cb0ef41Sopenharmony_ci .tm_year = static_cast<uInt>(file_time_parts.year)}; 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci return zip_info; 2731cb0ef41Sopenharmony_ci} 2741cb0ef41Sopenharmony_ci} // namespace 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_cinamespace zip { 2771cb0ef41Sopenharmony_cinamespace internal { 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ciunzFile OpenForUnzipping(const std::string& file_name_utf8) { 2801cb0ef41Sopenharmony_ci zlib_filefunc64_def* zip_func_ptrs = nullptr; 2811cb0ef41Sopenharmony_ci#if defined(OS_WIN) 2821cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_funcs; 2831cb0ef41Sopenharmony_ci fill_win32_filefunc64(&zip_funcs); 2841cb0ef41Sopenharmony_ci zip_funcs.zopen64_file = ZipOpenFunc; 2851cb0ef41Sopenharmony_ci zip_func_ptrs = &zip_funcs; 2861cb0ef41Sopenharmony_ci#endif 2871cb0ef41Sopenharmony_ci return unzOpen2_64(file_name_utf8.c_str(), zip_func_ptrs); 2881cb0ef41Sopenharmony_ci} 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci#if defined(OS_POSIX) || defined(OS_FUCHSIA) 2911cb0ef41Sopenharmony_ciunzFile OpenFdForUnzipping(int zip_fd) { 2921cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_funcs; 2931cb0ef41Sopenharmony_ci FillFdOpenFileFunc(&zip_funcs, zip_fd); 2941cb0ef41Sopenharmony_ci // Passing dummy "fd" filename to zlib. 2951cb0ef41Sopenharmony_ci return unzOpen2_64("fd", &zip_funcs); 2961cb0ef41Sopenharmony_ci} 2971cb0ef41Sopenharmony_ci#endif 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci#if defined(OS_WIN) 3001cb0ef41Sopenharmony_ciunzFile OpenHandleForUnzipping(HANDLE zip_handle) { 3011cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_funcs; 3021cb0ef41Sopenharmony_ci fill_win32_filefunc64(&zip_funcs); 3031cb0ef41Sopenharmony_ci zip_funcs.zopen64_file = HandleOpenFileFunc; 3041cb0ef41Sopenharmony_ci zip_funcs.zclose_file = HandleCloseFileFunc; 3051cb0ef41Sopenharmony_ci zip_funcs.opaque = zip_handle; 3061cb0ef41Sopenharmony_ci return unzOpen2_64("fd", &zip_funcs); 3071cb0ef41Sopenharmony_ci} 3081cb0ef41Sopenharmony_ci#endif 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci// static 3111cb0ef41Sopenharmony_ciunzFile PrepareMemoryForUnzipping(const std::string& data) { 3121cb0ef41Sopenharmony_ci if (data.empty()) 3131cb0ef41Sopenharmony_ci return NULL; 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci ZipBuffer* buffer = static_cast<ZipBuffer*>(malloc(sizeof(ZipBuffer))); 3161cb0ef41Sopenharmony_ci if (!buffer) 3171cb0ef41Sopenharmony_ci return NULL; 3181cb0ef41Sopenharmony_ci buffer->data = data.data(); 3191cb0ef41Sopenharmony_ci buffer->length = data.length(); 3201cb0ef41Sopenharmony_ci buffer->offset = 0; 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_functions; 3231cb0ef41Sopenharmony_ci zip_functions.zopen64_file = OpenZipBuffer; 3241cb0ef41Sopenharmony_ci zip_functions.zread_file = ReadZipBuffer; 3251cb0ef41Sopenharmony_ci zip_functions.zwrite_file = WriteZipBuffer; 3261cb0ef41Sopenharmony_ci zip_functions.ztell64_file = GetOffsetOfZipBuffer; 3271cb0ef41Sopenharmony_ci zip_functions.zseek64_file = SeekZipBuffer; 3281cb0ef41Sopenharmony_ci zip_functions.zclose_file = CloseZipBuffer; 3291cb0ef41Sopenharmony_ci zip_functions.zerror_file = GetErrorOfZipBuffer; 3301cb0ef41Sopenharmony_ci zip_functions.opaque = buffer; 3311cb0ef41Sopenharmony_ci return unzOpen2_64(nullptr, &zip_functions); 3321cb0ef41Sopenharmony_ci} 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_cizipFile OpenForZipping(const std::string& file_name_utf8, int append_flag) { 3351cb0ef41Sopenharmony_ci zlib_filefunc64_def* zip_func_ptrs = nullptr; 3361cb0ef41Sopenharmony_ci#if defined(OS_WIN) 3371cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_funcs; 3381cb0ef41Sopenharmony_ci fill_win32_filefunc64(&zip_funcs); 3391cb0ef41Sopenharmony_ci zip_funcs.zopen64_file = ZipOpenFunc; 3401cb0ef41Sopenharmony_ci zip_func_ptrs = &zip_funcs; 3411cb0ef41Sopenharmony_ci#endif 3421cb0ef41Sopenharmony_ci return zipOpen2_64(file_name_utf8.c_str(), append_flag, nullptr, 3431cb0ef41Sopenharmony_ci zip_func_ptrs); 3441cb0ef41Sopenharmony_ci} 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci#if defined(OS_POSIX) || defined(OS_FUCHSIA) 3471cb0ef41Sopenharmony_cizipFile OpenFdForZipping(int zip_fd, int append_flag) { 3481cb0ef41Sopenharmony_ci zlib_filefunc64_def zip_funcs; 3491cb0ef41Sopenharmony_ci FillFdOpenFileFunc(&zip_funcs, zip_fd); 3501cb0ef41Sopenharmony_ci // Passing dummy "fd" filename to zlib. 3511cb0ef41Sopenharmony_ci return zipOpen2_64("fd", append_flag, nullptr, &zip_funcs); 3521cb0ef41Sopenharmony_ci} 3531cb0ef41Sopenharmony_ci#endif 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_cibool ZipOpenNewFileInZip(zipFile zip_file, 3561cb0ef41Sopenharmony_ci const std::string& str_path, 3571cb0ef41Sopenharmony_ci base::Time last_modified_time, 3581cb0ef41Sopenharmony_ci Compression compression) { 3591cb0ef41Sopenharmony_ci // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT 3601cb0ef41Sopenharmony_ci // Setting the Language encoding flag so the file is told to be in utf-8. 3611cb0ef41Sopenharmony_ci const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11; 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci const zip_fileinfo file_info = TimeToZipFileInfo(last_modified_time); 3641cb0ef41Sopenharmony_ci const int err = zipOpenNewFileInZip4_64( 3651cb0ef41Sopenharmony_ci /*file=*/zip_file, 3661cb0ef41Sopenharmony_ci /*filename=*/str_path.c_str(), 3671cb0ef41Sopenharmony_ci /*zip_fileinfo=*/&file_info, 3681cb0ef41Sopenharmony_ci /*extrafield_local=*/nullptr, 3691cb0ef41Sopenharmony_ci /*size_extrafield_local=*/0u, 3701cb0ef41Sopenharmony_ci /*extrafield_global=*/nullptr, 3711cb0ef41Sopenharmony_ci /*size_extrafield_global=*/0u, 3721cb0ef41Sopenharmony_ci /*comment=*/nullptr, 3731cb0ef41Sopenharmony_ci /*method=*/compression, 3741cb0ef41Sopenharmony_ci /*level=*/Z_DEFAULT_COMPRESSION, 3751cb0ef41Sopenharmony_ci /*raw=*/0, 3761cb0ef41Sopenharmony_ci /*windowBits=*/-MAX_WBITS, 3771cb0ef41Sopenharmony_ci /*memLevel=*/DEF_MEM_LEVEL, 3781cb0ef41Sopenharmony_ci /*strategy=*/Z_DEFAULT_STRATEGY, 3791cb0ef41Sopenharmony_ci /*password=*/nullptr, 3801cb0ef41Sopenharmony_ci /*crcForCrypting=*/0, 3811cb0ef41Sopenharmony_ci /*versionMadeBy=*/0, 3821cb0ef41Sopenharmony_ci /*flagBase=*/LANGUAGE_ENCODING_FLAG, 3831cb0ef41Sopenharmony_ci /*zip64=*/1); 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci if (err != ZIP_OK) { 3861cb0ef41Sopenharmony_ci DLOG(ERROR) << "Cannot open ZIP file entry '" << str_path 3871cb0ef41Sopenharmony_ci << "': zipOpenNewFileInZip4_64 returned " << err; 3881cb0ef41Sopenharmony_ci return false; 3891cb0ef41Sopenharmony_ci } 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci return true; 3921cb0ef41Sopenharmony_ci} 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ciCompression GetCompressionMethod(const base::FilePath& path) { 3951cb0ef41Sopenharmony_ci // Get the filename extension in lower case. 3961cb0ef41Sopenharmony_ci const base::FilePath::StringType ext = 3971cb0ef41Sopenharmony_ci base::ToLowerASCII(path.FinalExtension()); 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci if (ext.empty()) 4001cb0ef41Sopenharmony_ci return kDeflated; 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci using StringPiece = base::FilePath::StringPieceType; 4031cb0ef41Sopenharmony_ci 4041cb0ef41Sopenharmony_ci // Skip the leading dot. 4051cb0ef41Sopenharmony_ci StringPiece ext_without_dot = ext; 4061cb0ef41Sopenharmony_ci DCHECK_EQ(ext_without_dot.front(), FILE_PATH_LITERAL('.')); 4071cb0ef41Sopenharmony_ci ext_without_dot.remove_prefix(1); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci // Well known filename extensions of files that a likely to be already 4101cb0ef41Sopenharmony_ci // compressed. The extensions are in lower case without the leading dot. 4111cb0ef41Sopenharmony_ci static constexpr auto kExts = base::MakeFixedFlatSet<StringPiece>({ 4121cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("3g2"), // 4131cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("3gp"), // 4141cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("7z"), // 4151cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("7zip"), // 4161cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("aac"), // 4171cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("avi"), // 4181cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("bz"), // 4191cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("bz2"), // 4201cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("crx"), // 4211cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("gif"), // 4221cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("gz"), // 4231cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("jar"), // 4241cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("jpeg"), // 4251cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("jpg"), // 4261cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("lz"), // 4271cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("m2v"), // 4281cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("m4p"), // 4291cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("m4v"), // 4301cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mng"), // 4311cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mov"), // 4321cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mp2"), // 4331cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mp3"), // 4341cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mp4"), // 4351cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mpe"), // 4361cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mpeg"), // 4371cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mpg"), // 4381cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("mpv"), // 4391cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("ogg"), // 4401cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("ogv"), // 4411cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("png"), // 4421cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("qt"), // 4431cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("rar"), // 4441cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("taz"), // 4451cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tb2"), // 4461cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tbz"), // 4471cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tbz2"), // 4481cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tgz"), // 4491cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tlz"), // 4501cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tz"), // 4511cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("tz2"), // 4521cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("vob"), // 4531cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("webm"), // 4541cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("wma"), // 4551cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("wmv"), // 4561cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("xz"), // 4571cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("z"), // 4581cb0ef41Sopenharmony_ci FILE_PATH_LITERAL("zip"), // 4591cb0ef41Sopenharmony_ci }); 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci if (kExts.count(ext_without_dot)) { 4621cb0ef41Sopenharmony_ci return kStored; 4631cb0ef41Sopenharmony_ci } 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ci return kDeflated; 4661cb0ef41Sopenharmony_ci} 4671cb0ef41Sopenharmony_ci 4681cb0ef41Sopenharmony_ci} // namespace internal 4691cb0ef41Sopenharmony_ci} // namespace zip 470