Skip to content

Commit

Permalink
Avoid fdreopen if possible
Browse files Browse the repository at this point in the history
Avoid using fdropen in mz_zip_add_mem_to_archive_file_in_place or
if new flag MZ_ZIP_FLAG_READ_ALLOW_WRITING is set.

This improves performance, but also fdreopen is broken on Android
(some kind of race).
  • Loading branch information
uroni committed Oct 16, 2024
1 parent 1ff82be commit 11e7c39
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
9 changes: 5 additions & 4 deletions miniz_zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

pFile = MZ_FOPEN(pFilename, "rb");
pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ? "r+b" : "rb");
if (!pFile)
return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);

Expand Down Expand Up @@ -3024,7 +3024,8 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
if (pZip->m_pIO_opaque != pZip)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
!(flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING) )
{
if (!pFilename)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
Expand Down Expand Up @@ -4568,14 +4569,14 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
else
{
/* Append to an existing archive. */
if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY | MZ_ZIP_FLAG_READ_ALLOW_WRITING, 0, 0))
{
if (pErr)
*pErr = zip_archive.m_last_error;
return MZ_FALSE;
}

if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags))
if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_READ_ALLOW_WRITING))
{
if (pErr)
*pErr = zip_archive.m_last_error;
Expand Down
3 changes: 2 additions & 1 deletion miniz_zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ extern "C"
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
/*After adding a compressed file, seek back
to local file header and set the correct sizes*/
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000,
MZ_ZIP_FLAG_READ_ALLOW_WRITING = 0x40000
} mz_zip_flags;

typedef enum
Expand Down
26 changes: 26 additions & 0 deletions tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ TEST_CASE("Zip writer tests")
REQUIRE(content_view.size() == 3);

free(content);

mz_zip_reader_end(&zip_archive);
}

SECTION("Test repeated file addition to zip")
{
mz_zip_archive zip_archive = {};
auto b = mz_zip_writer_init_file(&zip_archive, "test2.zip", 0);
REQUIRE(b);

b = mz_zip_writer_finalize_archive(&zip_archive);
REQUIRE(b);

b = mz_zip_writer_end(&zip_archive);
REQUIRE(b);

for (int i = 0; i < 50; i++)
{
const char *str = "hello world";
b = mz_zip_add_mem_to_archive_file_in_place(
std::string("test2.zip").c_str(), ("file1.txt" + std::to_string(i)).c_str(),
str, (mz_uint16)strlen(str),
NULL, 0,
MZ_BEST_COMPRESSION);
REQUIRE(b);
}
}
}

Expand Down

0 comments on commit 11e7c39

Please sign in to comment.