From a5939261949ef0721ff80c4b663e9850e20d550d Mon Sep 17 00:00:00 2001 From: appledragon Date: Thu, 23 Dec 2021 23:46:47 +0800 Subject: [PATCH] for support shareable file open on windows (#220) Support shareable file open on windows Co-authored-by: visla-dragon --- CMakeLists.txt | 5 +++++ src/miniz.h | 22 +++++++++++++++++----- src/zip.c | 4 +++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd58556..b41678d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,10 @@ option(CMAKE_ENABLE_SANITIZERS "Enable zip sanitizers" OFF) option(ZIP_STATIC_PIC "Build static zip with PIC" ON) option(ZIP_BUILD_DOCS "Generate API documentation with Doxygen" OFF) +if(ZIP_ENABLE_SHARABLE_FILE_OPEN) + add_definitions(-DZIP_ENABLE_SHARABLE_FILE_OPEN) +endif() + # zip set(SRC src/miniz.h src/zip.h src/zip.c) @@ -50,6 +54,7 @@ if (MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1") + elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") diff --git a/src/miniz.h b/src/miniz.h index e80c8db..ab29b11 100644 --- a/src/miniz.h +++ b/src/miniz.h @@ -4833,8 +4833,11 @@ static FILE *mz_fopen(const char *pFilename, const char *pMode) { wchar_t *wFilename = str2wstr(pFilename); wchar_t *wMode = str2wstr(pMode); +#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + pFile = _wfopen(wFilename, wMode); +#else _wfopen_s(&pFile, wFilename, wMode); - +#endif free(wFilename); free(wMode); @@ -4848,14 +4851,20 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { wchar_t *wPath = str2wstr(pPath); wchar_t *wMode = str2wstr(pMode); +#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + pFile = _wfreopen(wPath, wMode, pStream); +#else res = _wfreopen_s(&pFile, wPath, wMode, pStream); +#endif free(wPath); free(wMode); +#ifndef ZIP_ENABLE_SHARABLE_FILE_OPEN if (res) { return NULL; } +#endif return pFile; } @@ -8215,8 +8224,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2( mz_uint user_extra_data_central_len) { mz_uint16 method = 0, dos_time = 0, dos_date = 0; mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; - mz_uint64 local_dir_header_ofs = pZip->m_archive_size, - cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; + mz_uint64 local_dir_header_ofs = 0, + cur_archive_file_ofs = 0, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; tdefl_compressor *pComp = NULL; @@ -8248,6 +8257,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2( return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); pState = pZip->m_pState; + local_dir_header_ofs = pZip->m_archive_size; + cur_archive_file_ofs = pZip->m_archive_size; if (pState->m_zip64) { if (pZip->m_total_files == MZ_UINT32_MAX) @@ -8524,7 +8535,7 @@ mz_bool mz_zip_writer_add_read_buf_callback( : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; mz_uint16 method = 0, dos_time = 0, dos_date = 0; - mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, + mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = 0, uncomp_size = 0, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; @@ -8548,7 +8559,8 @@ mz_bool mz_zip_writer_add_read_buf_callback( return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); pState = pZip->m_pState; - + cur_archive_file_ofs = pZip->m_archive_size; + if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX)) { /* Source file is too large for non-zip64 */ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ diff --git a/src/zip.c b/src/zip.c index 612bc12..82e77c9 100644 --- a/src/zip.c +++ b/src/zip.c @@ -878,12 +878,14 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { mz_uint16 dos_time, dos_date; mz_uint32 extra_size = 0; mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_uint64 local_dir_header_ofs = zip->archive.m_archive_size; + mz_uint64 local_dir_header_ofs = 0; if (!zip) { return ZIP_ENOINIT; } + local_dir_header_ofs = zip->archive.m_archive_size; + if (!entryname) { return ZIP_EINVENTNAME; }