#include "third_party/zlib/google/zip_internal.h"
#include <stddef.h>
#include <string.h>
#include <algorithm>
#include <string_view>
#include "base/containers/fixed_flat_set.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#if defined(USE_SYSTEM_MINIZIP)
#include <minizip/ioapi.h>
#include <minizip/unzip.h>
#include <minizip/zip.h>
#else
#include "third_party/zlib/contrib/minizip/unzip.h"
#include "third_party/zlib/contrib/minizip/zip.h"
#if defined(OS_WIN)
#include "third_party/zlib/contrib/minizip/iowin32.h"
#elif defined(OS_POSIX)
#include "third_party/zlib/contrib/minizip/ioapi.h"
#endif
#endif
namespace {
#if defined(OS_WIN)
typedef struct {
HANDLE hf;
int error;
} WIN32FILE_IOWIN;
void* ZipOpenFunc(void* opaque, const void* filename, int mode) {
DWORD desired_access = 0, creation_disposition = 0;
DWORD share_mode = 0, flags_and_attributes = 0;
HANDLE file = 0;
void* ret = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
desired_access = GENERIC_READ;
creation_disposition = OPEN_EXISTING;
share_mode = FILE_SHARE_READ;
} else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
desired_access = GENERIC_WRITE | GENERIC_READ;
creation_disposition = OPEN_EXISTING;
} else if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
desired_access = GENERIC_WRITE | GENERIC_READ;
creation_disposition = CREATE_ALWAYS;
}
if (filename != nullptr && desired_access != 0) {
file = CreateFileW(
base::UTF8ToWide(static_cast<const char*>(filename)).c_str(),
desired_access, share_mode, nullptr, creation_disposition,
flags_and_attributes, nullptr);
}
if (file == INVALID_HANDLE_VALUE)
file = NULL;
if (file != NULL) {
WIN32FILE_IOWIN file_ret;
file_ret.hf = file;
file_ret.error = 0;
ret = malloc(sizeof(WIN32FILE_IOWIN));
if (ret == NULL)
CloseHandle(file);
else
*(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
}
return ret;
}
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
void* FdOpenFileFunc(void* opaque, const void* filename, int mode) { … }
int FdCloseFileFunc(void* opaque, void* stream) { … }
void FillFdOpenFileFunc(zlib_filefunc64_def* pzlib_filefunc_def, int fd) { … }
#endif
#if defined(OS_WIN)
void* HandleOpenFileFunc(void* opaque, const void* , int mode) {
WIN32FILE_IOWIN file_ret;
file_ret.hf = static_cast<HANDLE>(opaque);
file_ret.error = 0;
if (file_ret.hf == INVALID_HANDLE_VALUE)
return NULL;
void* ret = malloc(sizeof(WIN32FILE_IOWIN));
if (ret != NULL)
*(static_cast<WIN32FILE_IOWIN*>(ret)) = file_ret;
return ret;
}
int HandleCloseFileFunc(void* opaque, void* stream) {
free(stream);
return 0;
}
#endif
struct ZipBuffer { … };
void* OpenZipBuffer(void* opaque, const void* , int mode) { … }
uLong ReadZipBuffer(void* opaque, void* , void* buf, uLong size) { … }
uLong WriteZipBuffer(void* ,
void* ,
const void* ,
uLong ) { … }
ZPOS64_T GetOffsetOfZipBuffer(void* opaque, void* ) { … }
long SeekZipBuffer(void* opaque,
void* ,
ZPOS64_T offset,
int origin) { … }
int CloseZipBuffer(void* opaque, void* ) { … }
int GetErrorOfZipBuffer(void* , void* ) { … }
zip_fileinfo TimeToZipFileInfo(const base::Time& file_time) { … }
}
namespace zip {
namespace internal {
unzFile OpenForUnzipping(const std::string& file_name_utf8) { … }
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
unzFile OpenFdForUnzipping(int zip_fd) { … }
#endif
#if defined(OS_WIN)
unzFile OpenHandleForUnzipping(HANDLE zip_handle) {
zlib_filefunc64_def zip_funcs;
fill_win32_filefunc64(&zip_funcs);
zip_funcs.zopen64_file = HandleOpenFileFunc;
zip_funcs.zclose_file = HandleCloseFileFunc;
zip_funcs.opaque = zip_handle;
return unzOpen2_64("fd", &zip_funcs);
}
#endif
unzFile PrepareMemoryForUnzipping(const std::string& data) { … }
zipFile OpenForZipping(const std::string& file_name_utf8, int append_flag) { … }
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
zipFile OpenFdForZipping(int zip_fd, int append_flag) { … }
#endif
bool ZipOpenNewFileInZip(zipFile zip_file,
const std::string& str_path,
base::Time last_modified_time,
Compression compression) { … }
Compression GetCompressionMethod(const base::FilePath& path) { … }
}
}