Skip to content

Commit

Permalink
[zip] Handle big (4+GB) files with ZIP64
Browse files Browse the repository at this point in the history
Use the minizip API with the zip64 flag that allows to store big (4+GB)
files in a ZIP.

BUG=chromium:1207737, chromium:912236
TEST=browser_tests --gtest_filter="ZipFileCreatorTest*" --gtest_also_run_disabled_tests

Change-Id: I525a47e8d7bc18e95ba726b4516330c5b881cefc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3016489
Reviewed-by: Noel Gordon <noel@chromium.org>
Commit-Queue: François Degros <fdegros@chromium.org>
Cr-Commit-Position: refs/heads/master@{#907368}
  • Loading branch information
fdegros authored and Chromium LUCI CQ committed Jul 31, 2021
1 parent dd911d1 commit b0f5fc8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 31 deletions.
Expand Up @@ -139,10 +139,9 @@ IN_PROC_BROWSER_TEST_F(ZipFileCreatorTest, SomeFilesZip) {
}

IN_PROC_BROWSER_TEST_F(ZipFileCreatorTest, DISABLED_BigFile) {
// Prepare big file.
// TODO(crbug.com/1207737) Increase size to 5'000'000'000.
// Prepare big file (ie bigger than 4GB).
const base::FilePath kFile("big");
const int64_t kSize = 4'000'000'000;
const int64_t kSize = 5'000'000'000;

{
const base::ScopedAllowBlockingForTesting allow_io;
Expand Down
59 changes: 32 additions & 27 deletions third_party/zlib/google/zip_internal.cc
Expand Up @@ -38,7 +38,7 @@ typedef struct {
// This function is derived from third_party/minizip/iowin32.c.
// Its only difference is that it treats the char* as UTF8 and
// uses the Unicode version of CreateFile.
void* ZipOpenFunc(void *opaque, const char* filename, int mode) {
void* ZipOpenFunc(void* opaque, const char* filename, int mode) {
DWORD desired_access = 0, creation_disposition = 0;
DWORD share_mode = 0, flags_and_attributes = 0;
HANDLE file = 0;
Expand Down Expand Up @@ -105,7 +105,7 @@ void* FdOpenFileFunc(void* opaque, const char* filename, int mode) {

int FdCloseFileFunc(void* opaque, void* stream) {
fclose(static_cast<FILE*>(stream));
free(opaque); // malloc'ed in FillFdOpenFileFunc()
free(opaque); // malloc'ed in FillFdOpenFileFunc()
return 0;
}

Expand Down Expand Up @@ -138,7 +138,7 @@ void* HandleOpenFileFunc(void* opaque, const char* filename, int mode) {
}

int HandleCloseFileFunc(void* opaque, void* stream) {
free(stream); // malloc'ed in HandleOpenFileFunc()
free(stream); // malloc'ed in HandleOpenFileFunc()
return 0;
}
#endif
Expand Down Expand Up @@ -208,8 +208,8 @@ long SeekZipBuffer(void* opaque, void* /*stream*/, uLong offset, int origin) {
if (!buffer)
return -1;
if (origin == ZLIB_FILEFUNC_SEEK_CUR) {
buffer->offset = std::min(buffer->offset + static_cast<size_t>(offset),
buffer->length);
buffer->offset =
std::min(buffer->offset + static_cast<size_t>(offset), buffer->length);
return 0;
}
if (origin == ZLIB_FILEFUNC_SEEK_END) {
Expand Down Expand Up @@ -330,8 +330,7 @@ zipFile OpenForZipping(const std::string& file_name_utf8, int append_flag) {
zip_funcs.zopen_file = ZipOpenFunc;
zip_func_ptrs = &zip_funcs;
#endif
return zipOpen2(file_name_utf8.c_str(),
append_flag,
return zipOpen2(file_name_utf8.c_str(), append_flag,
NULL, // global comment
zip_func_ptrs);
}
Expand All @@ -352,28 +351,34 @@ bool ZipOpenNewFileInZip(zipFile zip_file,
// Setting the Language encoding flag so the file is told to be in utf-8.
const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11;

zip_fileinfo file_info = TimeToZipFileInfo(last_modified_time);
if (ZIP_OK != zipOpenNewFileInZip4(zip_file, // file
str_path.c_str(), // filename
&file_info, // zip_fileinfo
NULL, // extrafield_local,
0u, // size_extrafield_local
NULL, // extrafield_global
0u, // size_extrafield_global
NULL, // comment
Z_DEFLATED, // method
Z_DEFAULT_COMPRESSION, // level
0, // raw
-MAX_WBITS, // windowBits
DEF_MEM_LEVEL, // memLevel
Z_DEFAULT_STRATEGY, // strategy
NULL, // password
0, // crcForCrypting
0, // versionMadeBy
LANGUAGE_ENCODING_FLAG)) { // flagBase
DLOG(ERROR) << "Could not open zip file entry " << str_path;
const zip_fileinfo file_info = TimeToZipFileInfo(last_modified_time);
const int err = zipOpenNewFileInZip4_64(
/*file=*/zip_file,
/*filename=*/str_path.c_str(),
/*zip_fileinfo=*/&file_info,
/*extrafield_local=*/nullptr,
/*size_extrafield_local=*/0u,
/*extrafield_global=*/nullptr,
/*size_extrafield_global=*/0u,
/*comment=*/nullptr,
/*method=*/Z_DEFLATED,
/*level=*/Z_DEFAULT_COMPRESSION,
/*raw=*/0,
/*windowBits=*/-MAX_WBITS,
/*memLevel=*/DEF_MEM_LEVEL,
/*strategy=*/Z_DEFAULT_STRATEGY,
/*password=*/nullptr,
/*crcForCrypting=*/0,
/*versionMadeBy=*/0,
/*flagBase=*/LANGUAGE_ENCODING_FLAG,
/*zip64=*/1);

if (err != ZIP_OK) {
DLOG(ERROR) << "Cannot open ZIP file entry '" << str_path
<< "': zipOpenNewFileInZip4_64 returned " << err;
return false;
}

return true;
}

Expand Down
2 changes: 1 addition & 1 deletion third_party/zlib/google/zip_internal.h
Expand Up @@ -60,7 +60,7 @@ zipFile OpenForZipping(const std::string& file_name_utf8, int append_flag);
zipFile OpenFdForZipping(int zip_fd, int append_flag);
#endif

// Wrapper around zipOpenNewFileInZip4 which passes most common options.
// Adds a file (or directory) entry to the ZIP archive.
bool ZipOpenNewFileInZip(zipFile zip_file,
const std::string& str_path,
base::Time last_modified_time);
Expand Down

0 comments on commit b0f5fc8

Please sign in to comment.