1*4882a593SmuzhiyunFrom f78446b14aff46db2ef27d062a275b6a01fd68b1 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Kim Kulling <kim.kulling@googlemail.com> 3*4882a593SmuzhiyunDate: Tue, 19 Nov 2019 20:30:40 +0100 4*4882a593SmuzhiyunSubject: [PATCH] closes https://github.com/assimp/assimp/issues/2733: update 5*4882a593Smuzhiyun of zlip to fix gcc build for v9.2.0 32 bit 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun[Retrieved (and updated to remove .gitignore and appveyor.yml) from: 8*4882a593Smuzhiyunhttps://github.com/assimp/assimp/commit/f78446b14aff46db2ef27d062a275b6a01fd68b1] 9*4882a593SmuzhiyunSigned-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> 10*4882a593Smuzhiyun--- 11*4882a593Smuzhiyun contrib/zip/.gitignore | 2 + 12*4882a593Smuzhiyun contrib/zip/CMakeLists.txt | 83 +++++- 13*4882a593Smuzhiyun contrib/zip/README.md | 12 +- 14*4882a593Smuzhiyun contrib/zip/appveyor.yml | 2 +- 15*4882a593Smuzhiyun contrib/zip/src/miniz.h | 457 ++++++++++++++++++++++++++++---- 16*4882a593Smuzhiyun contrib/zip/src/zip.c | 62 +++-- 17*4882a593Smuzhiyun contrib/zip/src/zip.h | 457 ++++++++++++++++---------------- 18*4882a593Smuzhiyun contrib/zip/test/CMakeLists.txt | 27 +- 19*4882a593Smuzhiyun contrib/zip/test/test.c | 38 ++- 20*4882a593Smuzhiyun contrib/zip/test/test_miniz.c | 25 +- 21*4882a593Smuzhiyun 10 files changed, 821 insertions(+), 344 deletions(-) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyundiff --git a/contrib/zip/CMakeLists.txt b/contrib/zip/CMakeLists.txt 24*4882a593Smuzhiyunindex b46dbb1db0..77916d2e14 100644 25*4882a593Smuzhiyun--- a/contrib/zip/CMakeLists.txt 26*4882a593Smuzhiyun+++ b/contrib/zip/CMakeLists.txt 27*4882a593Smuzhiyun@@ -1,10 +1,14 @@ 28*4882a593Smuzhiyun-cmake_minimum_required(VERSION 2.8) 29*4882a593Smuzhiyun-project(zip) 30*4882a593Smuzhiyun-enable_language(C) 31*4882a593Smuzhiyun+cmake_minimum_required(VERSION 3.0) 32*4882a593Smuzhiyun+ 33*4882a593Smuzhiyun+project(zip 34*4882a593Smuzhiyun+ LANGUAGES C 35*4882a593Smuzhiyun+ VERSION "0.1.15") 36*4882a593Smuzhiyun set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun+option(CMAKE_DISABLE_TESTING "Disable test creation" OFF) 39*4882a593Smuzhiyun+ 40*4882a593Smuzhiyun if (MSVC) 41*4882a593Smuzhiyun- # Use secure functions by defaualt and suppress warnings about "deprecated" functions 42*4882a593Smuzhiyun+ # Use secure functions by default and suppress warnings about "deprecated" functions 43*4882a593Smuzhiyun set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") 44*4882a593Smuzhiyun set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") 45*4882a593Smuzhiyun set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1") 46*4882a593Smuzhiyun@@ -12,28 +16,80 @@ elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR 47*4882a593Smuzhiyun "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR 48*4882a593Smuzhiyun "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") 49*4882a593Smuzhiyun set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic") 50*4882a593Smuzhiyun+ if(ENABLE_COVERAGE) 51*4882a593Smuzhiyun+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") 52*4882a593Smuzhiyun+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") 53*4882a593Smuzhiyun+ endif() 54*4882a593Smuzhiyun endif (MSVC) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun # zip 57*4882a593Smuzhiyun set(SRC src/miniz.h src/zip.h src/zip.c) 58*4882a593Smuzhiyun add_library(${PROJECT_NAME} ${SRC}) 59*4882a593Smuzhiyun-target_include_directories(${PROJECT_NAME} INTERFACE src) 60*4882a593Smuzhiyun+target_include_directories(${PROJECT_NAME} PUBLIC 61*4882a593Smuzhiyun+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> 62*4882a593Smuzhiyun+ $<INSTALL_INTERFACE:include> 63*4882a593Smuzhiyun+) 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun # test 66*4882a593Smuzhiyun if (NOT CMAKE_DISABLE_TESTING) 67*4882a593Smuzhiyun enable_testing() 68*4882a593Smuzhiyun add_subdirectory(test) 69*4882a593Smuzhiyun find_package(Sanitizers) 70*4882a593Smuzhiyun- add_sanitizers(${PROJECT_NAME} test.exe) 71*4882a593Smuzhiyun- add_sanitizers(${PROJECT_NAME} test_miniz.exe) 72*4882a593Smuzhiyun+ add_sanitizers(${PROJECT_NAME} ${test_out} ${test_miniz_out}) 73*4882a593Smuzhiyun endif() 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun+#### 76*4882a593Smuzhiyun+# Installation (https://github.com/forexample/package-example) { 77*4882a593Smuzhiyun+ 78*4882a593Smuzhiyun+set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}") 79*4882a593Smuzhiyun+set(INCLUDE_INSTALL_DIR "include") 80*4882a593Smuzhiyun+ 81*4882a593Smuzhiyun+set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") 82*4882a593Smuzhiyun+ 83*4882a593Smuzhiyun+# Configuration 84*4882a593Smuzhiyun+set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake") 85*4882a593Smuzhiyun+set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake") 86*4882a593Smuzhiyun+set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") 87*4882a593Smuzhiyun+set(NAMESPACE "${PROJECT_NAME}::") 88*4882a593Smuzhiyun+ 89*4882a593Smuzhiyun+# Include module with fuction 'write_basic_package_version_file' 90*4882a593Smuzhiyun+include(CMakePackageConfigHelpers) 91*4882a593Smuzhiyun+ 92*4882a593Smuzhiyun+# Note: PROJECT_VERSION is used as a VERSION 93*4882a593Smuzhiyun+write_basic_package_version_file( 94*4882a593Smuzhiyun+ "${VERSION_CONFIG}" COMPATIBILITY SameMajorVersion 95*4882a593Smuzhiyun+) 96*4882a593Smuzhiyun+ 97*4882a593Smuzhiyun+# Use variables: 98*4882a593Smuzhiyun+# * TARGETS_EXPORT_NAME 99*4882a593Smuzhiyun+# * PROJECT_NAME 100*4882a593Smuzhiyun+configure_package_config_file( 101*4882a593Smuzhiyun+ "cmake/Config.cmake.in" 102*4882a593Smuzhiyun+ "${PROJECT_CONFIG}" 103*4882a593Smuzhiyun+ INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}" 104*4882a593Smuzhiyun+) 105*4882a593Smuzhiyun+ 106*4882a593Smuzhiyun+install( 107*4882a593Smuzhiyun+ FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}" 108*4882a593Smuzhiyun+ DESTINATION "${CONFIG_INSTALL_DIR}" 109*4882a593Smuzhiyun+) 110*4882a593Smuzhiyun+ 111*4882a593Smuzhiyun+install( 112*4882a593Smuzhiyun+ EXPORT "${TARGETS_EXPORT_NAME}" 113*4882a593Smuzhiyun+ NAMESPACE "${NAMESPACE}" 114*4882a593Smuzhiyun+ DESTINATION "${CONFIG_INSTALL_DIR}" 115*4882a593Smuzhiyun+) 116*4882a593Smuzhiyun+ 117*4882a593Smuzhiyun+# } 118*4882a593Smuzhiyun+ 119*4882a593Smuzhiyun install(TARGETS ${PROJECT_NAME} 120*4882a593Smuzhiyun+ EXPORT ${TARGETS_EXPORT_NAME} 121*4882a593Smuzhiyun RUNTIME DESTINATION bin 122*4882a593Smuzhiyun ARCHIVE DESTINATION lib 123*4882a593Smuzhiyun LIBRARY DESTINATION lib 124*4882a593Smuzhiyun- COMPONENT library) 125*4882a593Smuzhiyun-install(FILES ${PROJECT_SOURCE_DIR}/src/zip.h DESTINATION include) 126*4882a593Smuzhiyun+ INCLUDES DESTINATION ${INCLUDE_INSTALL_DIR} 127*4882a593Smuzhiyun+) 128*4882a593Smuzhiyun+install(FILES ${PROJECT_SOURCE_DIR}/src/zip.h DESTINATION ${INCLUDE_INSTALL_DIR}/zip) 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun # uninstall target (https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake) 131*4882a593Smuzhiyun if(NOT TARGET uninstall) 132*4882a593Smuzhiyun@@ -45,3 +101,12 @@ if(NOT TARGET uninstall) 133*4882a593Smuzhiyun add_custom_target(uninstall 134*4882a593Smuzhiyun COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake) 135*4882a593Smuzhiyun endif() 136*4882a593Smuzhiyun+ 137*4882a593Smuzhiyun+find_package(Doxygen) 138*4882a593Smuzhiyun+if(DOXYGEN_FOUND) 139*4882a593Smuzhiyun+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) 140*4882a593Smuzhiyun+ add_custom_target(doc 141*4882a593Smuzhiyun+ ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 142*4882a593Smuzhiyun+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 143*4882a593Smuzhiyun+ COMMENT "Generating API documentation with Doxygen" VERBATIM) 144*4882a593Smuzhiyun+endif() 145*4882a593Smuzhiyundiff --git a/contrib/zip/README.md b/contrib/zip/README.md 146*4882a593Smuzhiyunindex d5fb8cd203..14eb9a34c8 100644 147*4882a593Smuzhiyun--- a/contrib/zip/README.md 148*4882a593Smuzhiyun+++ b/contrib/zip/README.md 149*4882a593Smuzhiyun@@ -71,7 +71,7 @@ int arg = 2; 150*4882a593Smuzhiyun zip_extract("foo.zip", "/tmp", on_extract_entry, &arg); 151*4882a593Smuzhiyun ``` 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun-* Extract a zip entry into memory. 154*4882a593Smuzhiyun+* Extract a zip entry into memory. 155*4882a593Smuzhiyun ```c 156*4882a593Smuzhiyun void *buf = NULL; 157*4882a593Smuzhiyun size_t bufsize; 158*4882a593Smuzhiyun@@ -89,7 +89,7 @@ zip_close(zip); 159*4882a593Smuzhiyun free(buf); 160*4882a593Smuzhiyun ``` 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun-* Extract a zip entry into memory (no internal allocation). 163*4882a593Smuzhiyun+* Extract a zip entry into memory (no internal allocation). 164*4882a593Smuzhiyun ```c 165*4882a593Smuzhiyun unsigned char *buf; 166*4882a593Smuzhiyun size_t bufsize; 167*4882a593Smuzhiyun@@ -110,7 +110,7 @@ zip_close(zip); 168*4882a593Smuzhiyun free(buf); 169*4882a593Smuzhiyun ``` 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun-* Extract a zip entry into memory using callback. 172*4882a593Smuzhiyun+* Extract a zip entry into memory using callback. 173*4882a593Smuzhiyun ```c 174*4882a593Smuzhiyun struct buffer_t { 175*4882a593Smuzhiyun char *data; 176*4882a593Smuzhiyun@@ -144,7 +144,7 @@ free(buf.data); 177*4882a593Smuzhiyun ``` 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun-* Extract a zip entry into a file. 181*4882a593Smuzhiyun+* Extract a zip entry into a file. 182*4882a593Smuzhiyun ```c 183*4882a593Smuzhiyun struct zip_t *zip = zip_open("foo.zip", 0, 'r'); 184*4882a593Smuzhiyun { 185*4882a593Smuzhiyun@@ -157,7 +157,7 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r'); 186*4882a593Smuzhiyun zip_close(zip); 187*4882a593Smuzhiyun ``` 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun-* List of all zip entries 190*4882a593Smuzhiyun+* List of all zip entries 191*4882a593Smuzhiyun ```c 192*4882a593Smuzhiyun struct zip_t *zip = zip_open("foo.zip", 0, 'r'); 193*4882a593Smuzhiyun int i, n = zip_total_entries(zip); 194*4882a593Smuzhiyun@@ -174,7 +174,7 @@ for (i = 0; i < n; ++i) { 195*4882a593Smuzhiyun zip_close(zip); 196*4882a593Smuzhiyun ``` 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun-## Bindings 199*4882a593Smuzhiyun+# Bindings 200*4882a593Smuzhiyun Compile zip library as a dynamic library. 201*4882a593Smuzhiyun ```shell 202*4882a593Smuzhiyun $ mkdir build 203*4882a593Smuzhiyundiff --git a/contrib/zip/src/miniz.h b/contrib/zip/src/miniz.h 204*4882a593Smuzhiyunindex 2c27a94d8d..c4fcfb83e6 100644 205*4882a593Smuzhiyun--- a/contrib/zip/src/miniz.h 206*4882a593Smuzhiyun+++ b/contrib/zip/src/miniz.h 207*4882a593Smuzhiyun@@ -221,6 +221,7 @@ 208*4882a593Smuzhiyun #ifndef MINIZ_HEADER_INCLUDED 209*4882a593Smuzhiyun #define MINIZ_HEADER_INCLUDED 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun+#include <stdint.h> 212*4882a593Smuzhiyun #include <stdlib.h> 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun // Defines to completely disable specific portions of miniz.c: 215*4882a593Smuzhiyun@@ -284,7 +285,8 @@ 216*4882a593Smuzhiyun /* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */ 217*4882a593Smuzhiyun #if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES) 218*4882a593Smuzhiyun #if MINIZ_X86_OR_X64_CPU 219*4882a593Smuzhiyun-/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */ 220*4882a593Smuzhiyun+/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient 221*4882a593Smuzhiyun+ * integer loads and stores from unaligned addresses. */ 222*4882a593Smuzhiyun #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 223*4882a593Smuzhiyun #define MINIZ_UNALIGNED_USE_MEMCPY 224*4882a593Smuzhiyun #else 225*4882a593Smuzhiyun@@ -354,6 +356,44 @@ enum { 226*4882a593Smuzhiyun MZ_FIXED = 4 227*4882a593Smuzhiyun }; 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun+/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or 230*4882a593Smuzhiyun+ * modify this enum. */ 231*4882a593Smuzhiyun+typedef enum { 232*4882a593Smuzhiyun+ MZ_ZIP_NO_ERROR = 0, 233*4882a593Smuzhiyun+ MZ_ZIP_UNDEFINED_ERROR, 234*4882a593Smuzhiyun+ MZ_ZIP_TOO_MANY_FILES, 235*4882a593Smuzhiyun+ MZ_ZIP_FILE_TOO_LARGE, 236*4882a593Smuzhiyun+ MZ_ZIP_UNSUPPORTED_METHOD, 237*4882a593Smuzhiyun+ MZ_ZIP_UNSUPPORTED_ENCRYPTION, 238*4882a593Smuzhiyun+ MZ_ZIP_UNSUPPORTED_FEATURE, 239*4882a593Smuzhiyun+ MZ_ZIP_FAILED_FINDING_CENTRAL_DIR, 240*4882a593Smuzhiyun+ MZ_ZIP_NOT_AN_ARCHIVE, 241*4882a593Smuzhiyun+ MZ_ZIP_INVALID_HEADER_OR_CORRUPTED, 242*4882a593Smuzhiyun+ MZ_ZIP_UNSUPPORTED_MULTIDISK, 243*4882a593Smuzhiyun+ MZ_ZIP_DECOMPRESSION_FAILED, 244*4882a593Smuzhiyun+ MZ_ZIP_COMPRESSION_FAILED, 245*4882a593Smuzhiyun+ MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE, 246*4882a593Smuzhiyun+ MZ_ZIP_CRC_CHECK_FAILED, 247*4882a593Smuzhiyun+ MZ_ZIP_UNSUPPORTED_CDIR_SIZE, 248*4882a593Smuzhiyun+ MZ_ZIP_ALLOC_FAILED, 249*4882a593Smuzhiyun+ MZ_ZIP_FILE_OPEN_FAILED, 250*4882a593Smuzhiyun+ MZ_ZIP_FILE_CREATE_FAILED, 251*4882a593Smuzhiyun+ MZ_ZIP_FILE_WRITE_FAILED, 252*4882a593Smuzhiyun+ MZ_ZIP_FILE_READ_FAILED, 253*4882a593Smuzhiyun+ MZ_ZIP_FILE_CLOSE_FAILED, 254*4882a593Smuzhiyun+ MZ_ZIP_FILE_SEEK_FAILED, 255*4882a593Smuzhiyun+ MZ_ZIP_FILE_STAT_FAILED, 256*4882a593Smuzhiyun+ MZ_ZIP_INVALID_PARAMETER, 257*4882a593Smuzhiyun+ MZ_ZIP_INVALID_FILENAME, 258*4882a593Smuzhiyun+ MZ_ZIP_BUF_TOO_SMALL, 259*4882a593Smuzhiyun+ MZ_ZIP_INTERNAL_ERROR, 260*4882a593Smuzhiyun+ MZ_ZIP_FILE_NOT_FOUND, 261*4882a593Smuzhiyun+ MZ_ZIP_ARCHIVE_TOO_LARGE, 262*4882a593Smuzhiyun+ MZ_ZIP_VALIDATION_FAILED, 263*4882a593Smuzhiyun+ MZ_ZIP_WRITE_CALLBACK_FAILED, 264*4882a593Smuzhiyun+ MZ_ZIP_TOTAL_ERRORS 265*4882a593Smuzhiyun+} mz_zip_error; 266*4882a593Smuzhiyun+ 267*4882a593Smuzhiyun // Method 268*4882a593Smuzhiyun #define MZ_DEFLATED 8 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun@@ -696,6 +736,7 @@ typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, 271*4882a593Smuzhiyun void *pBuf, size_t n); 272*4882a593Smuzhiyun typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, 273*4882a593Smuzhiyun const void *pBuf, size_t n); 274*4882a593Smuzhiyun+typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque); 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun struct mz_zip_internal_state_tag; 277*4882a593Smuzhiyun typedef struct mz_zip_internal_state_tag mz_zip_internal_state; 278*4882a593Smuzhiyun@@ -707,13 +748,27 @@ typedef enum { 279*4882a593Smuzhiyun MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 280*4882a593Smuzhiyun } mz_zip_mode; 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun-typedef struct mz_zip_archive_tag { 283*4882a593Smuzhiyun+typedef enum { 284*4882a593Smuzhiyun+ MZ_ZIP_TYPE_INVALID = 0, 285*4882a593Smuzhiyun+ MZ_ZIP_TYPE_USER, 286*4882a593Smuzhiyun+ MZ_ZIP_TYPE_MEMORY, 287*4882a593Smuzhiyun+ MZ_ZIP_TYPE_HEAP, 288*4882a593Smuzhiyun+ MZ_ZIP_TYPE_FILE, 289*4882a593Smuzhiyun+ MZ_ZIP_TYPE_CFILE, 290*4882a593Smuzhiyun+ MZ_ZIP_TOTAL_TYPES 291*4882a593Smuzhiyun+} mz_zip_type; 292*4882a593Smuzhiyun+ 293*4882a593Smuzhiyun+typedef struct { 294*4882a593Smuzhiyun mz_uint64 m_archive_size; 295*4882a593Smuzhiyun mz_uint64 m_central_directory_file_ofs; 296*4882a593Smuzhiyun- mz_uint m_total_files; 297*4882a593Smuzhiyun+ 298*4882a593Smuzhiyun+ /* We only support up to UINT32_MAX files in zip64 mode. */ 299*4882a593Smuzhiyun+ mz_uint32 m_total_files; 300*4882a593Smuzhiyun mz_zip_mode m_zip_mode; 301*4882a593Smuzhiyun+ mz_zip_type m_zip_type; 302*4882a593Smuzhiyun+ mz_zip_error m_last_error; 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun- mz_uint m_file_offset_alignment; 305*4882a593Smuzhiyun+ mz_uint64 m_file_offset_alignment; 306*4882a593Smuzhiyun 307*4882a593Smuzhiyun mz_alloc_func m_pAlloc; 308*4882a593Smuzhiyun mz_free_func m_pFree; 309*4882a593Smuzhiyun@@ -722,6 +777,7 @@ typedef struct mz_zip_archive_tag { 310*4882a593Smuzhiyun 311*4882a593Smuzhiyun mz_file_read_func m_pRead; 312*4882a593Smuzhiyun mz_file_write_func m_pWrite; 313*4882a593Smuzhiyun+ mz_file_needs_keepalive m_pNeeds_keepalive; 314*4882a593Smuzhiyun void *m_pIO_opaque; 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun mz_zip_internal_state *m_pState; 317*4882a593Smuzhiyun@@ -1263,6 +1319,9 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, 318*4882a593Smuzhiyun int strategy); 319*4882a593Smuzhiyun #endif // #ifndef MINIZ_NO_ZLIB_APIS 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun+#define MZ_UINT16_MAX (0xFFFFU) 322*4882a593Smuzhiyun+#define MZ_UINT32_MAX (0xFFFFFFFFU) 323*4882a593Smuzhiyun+ 324*4882a593Smuzhiyun #ifdef __cplusplus 325*4882a593Smuzhiyun } 326*4882a593Smuzhiyun #endif 327*4882a593Smuzhiyun@@ -1311,6 +1370,11 @@ typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; 328*4882a593Smuzhiyun ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) 329*4882a593Smuzhiyun #endif 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun+#define MZ_READ_LE64(p) \ 332*4882a593Smuzhiyun+ (((mz_uint64)MZ_READ_LE32(p)) | \ 333*4882a593Smuzhiyun+ (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) \ 334*4882a593Smuzhiyun+ << 32U)) 335*4882a593Smuzhiyun+ 336*4882a593Smuzhiyun #ifdef _MSC_VER 337*4882a593Smuzhiyun #define MZ_FORCEINLINE __forceinline 338*4882a593Smuzhiyun #elif defined(__GNUC__) 339*4882a593Smuzhiyun@@ -4160,6 +4224,17 @@ enum { 340*4882a593Smuzhiyun MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, 341*4882a593Smuzhiyun MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, 342*4882a593Smuzhiyun MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, 343*4882a593Smuzhiyun+ 344*4882a593Smuzhiyun+ /* ZIP64 archive identifier and record sizes */ 345*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50, 346*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50, 347*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56, 348*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, 349*4882a593Smuzhiyun+ MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, 350*4882a593Smuzhiyun+ MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, 351*4882a593Smuzhiyun+ MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24, 352*4882a593Smuzhiyun+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16, 353*4882a593Smuzhiyun+ 354*4882a593Smuzhiyun // Central directory header record offsets 355*4882a593Smuzhiyun MZ_ZIP_CDH_SIG_OFS = 0, 356*4882a593Smuzhiyun MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, 357*4882a593Smuzhiyun@@ -4199,6 +4274,31 @@ enum { 358*4882a593Smuzhiyun MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, 359*4882a593Smuzhiyun MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, 360*4882a593Smuzhiyun MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, 361*4882a593Smuzhiyun+ 362*4882a593Smuzhiyun+ /* ZIP64 End of central directory locator offsets */ 363*4882a593Smuzhiyun+ MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */ 364*4882a593Smuzhiyun+ MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4, /* 4 bytes */ 365*4882a593Smuzhiyun+ MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8, /* 8 bytes */ 366*4882a593Smuzhiyun+ MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */ 367*4882a593Smuzhiyun+ 368*4882a593Smuzhiyun+ /* ZIP64 End of central directory header offsets */ 369*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */ 370*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4, /* 8 bytes */ 371*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12, /* 2 bytes */ 372*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14, /* 2 bytes */ 373*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16, /* 4 bytes */ 374*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20, /* 4 bytes */ 375*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */ 376*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32, /* 8 bytes */ 377*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */ 378*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */ 379*4882a593Smuzhiyun+ MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0, 380*4882a593Smuzhiyun+ MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10, 381*4882a593Smuzhiyun+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1, 382*4882a593Smuzhiyun+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32, 383*4882a593Smuzhiyun+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64, 384*4882a593Smuzhiyun+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192, 385*4882a593Smuzhiyun+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11 386*4882a593Smuzhiyun }; 387*4882a593Smuzhiyun 388*4882a593Smuzhiyun typedef struct { 389*4882a593Smuzhiyun@@ -4211,7 +4311,24 @@ struct mz_zip_internal_state_tag { 390*4882a593Smuzhiyun mz_zip_array m_central_dir; 391*4882a593Smuzhiyun mz_zip_array m_central_dir_offsets; 392*4882a593Smuzhiyun mz_zip_array m_sorted_central_dir_offsets; 393*4882a593Smuzhiyun+ 394*4882a593Smuzhiyun+ /* The flags passed in when the archive is initially opened. */ 395*4882a593Smuzhiyun+ uint32_t m_init_flags; 396*4882a593Smuzhiyun+ 397*4882a593Smuzhiyun+ /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. 398*4882a593Smuzhiyun+ */ 399*4882a593Smuzhiyun+ mz_bool m_zip64; 400*4882a593Smuzhiyun+ 401*4882a593Smuzhiyun+ /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 402*4882a593Smuzhiyun+ * will also be slammed to true too, even if we didn't find a zip64 end of 403*4882a593Smuzhiyun+ * central dir header, etc.) */ 404*4882a593Smuzhiyun+ mz_bool m_zip64_has_extended_info_fields; 405*4882a593Smuzhiyun+ 406*4882a593Smuzhiyun+ /* These fields are used by the file, FILE, memory, and memory/heap read/write 407*4882a593Smuzhiyun+ * helpers. */ 408*4882a593Smuzhiyun MZ_FILE *m_pFile; 409*4882a593Smuzhiyun+ mz_uint64 m_file_archive_start_ofs; 410*4882a593Smuzhiyun+ 411*4882a593Smuzhiyun void *m_pMem; 412*4882a593Smuzhiyun size_t m_mem_size; 413*4882a593Smuzhiyun size_t m_mem_capacity; 414*4882a593Smuzhiyun@@ -4363,6 +4480,13 @@ static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, 415*4882a593Smuzhiyun #endif /* #ifndef MINIZ_NO_STDIO */ 416*4882a593Smuzhiyun #endif /* #ifndef MINIZ_NO_TIME */ 417*4882a593Smuzhiyun 418*4882a593Smuzhiyun+static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, 419*4882a593Smuzhiyun+ mz_zip_error err_num) { 420*4882a593Smuzhiyun+ if (pZip) 421*4882a593Smuzhiyun+ pZip->m_last_error = err_num; 422*4882a593Smuzhiyun+ return MZ_FALSE; 423*4882a593Smuzhiyun+} 424*4882a593Smuzhiyun+ 425*4882a593Smuzhiyun static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, 426*4882a593Smuzhiyun mz_uint32 flags) { 427*4882a593Smuzhiyun (void)flags; 428*4882a593Smuzhiyun@@ -4480,127 +4604,346 @@ mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) { 429*4882a593Smuzhiyun } 430*4882a593Smuzhiyun } 431*4882a593Smuzhiyun 432*4882a593Smuzhiyun-static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, 433*4882a593Smuzhiyun- mz_uint32 flags) { 434*4882a593Smuzhiyun- mz_uint cdir_size, num_this_disk, cdir_disk_index; 435*4882a593Smuzhiyun- mz_uint64 cdir_ofs; 436*4882a593Smuzhiyun+static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, 437*4882a593Smuzhiyun+ mz_uint32 record_sig, 438*4882a593Smuzhiyun+ mz_uint32 record_size, 439*4882a593Smuzhiyun+ mz_int64 *pOfs) { 440*4882a593Smuzhiyun mz_int64 cur_file_ofs; 441*4882a593Smuzhiyun- const mz_uint8 *p; 442*4882a593Smuzhiyun mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; 443*4882a593Smuzhiyun mz_uint8 *pBuf = (mz_uint8 *)buf_u32; 444*4882a593Smuzhiyun- mz_bool sort_central_dir = 445*4882a593Smuzhiyun- ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); 446*4882a593Smuzhiyun- // Basic sanity checks - reject files which are too small, and check the first 447*4882a593Smuzhiyun- // 4 bytes of the file to make sure a local header is there. 448*4882a593Smuzhiyun- if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) 449*4882a593Smuzhiyun+ 450*4882a593Smuzhiyun+ /* Basic sanity checks - reject files which are too small */ 451*4882a593Smuzhiyun+ if (pZip->m_archive_size < record_size) 452*4882a593Smuzhiyun return MZ_FALSE; 453*4882a593Smuzhiyun- // Find the end of central directory record by scanning the file from the end 454*4882a593Smuzhiyun- // towards the beginning. 455*4882a593Smuzhiyun+ 456*4882a593Smuzhiyun+ /* Find the record by scanning the file from the end towards the beginning. */ 457*4882a593Smuzhiyun cur_file_ofs = 458*4882a593Smuzhiyun MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); 459*4882a593Smuzhiyun for (;;) { 460*4882a593Smuzhiyun int i, 461*4882a593Smuzhiyun n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); 462*4882a593Smuzhiyun+ 463*4882a593Smuzhiyun if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) 464*4882a593Smuzhiyun return MZ_FALSE; 465*4882a593Smuzhiyun- for (i = n - 4; i >= 0; --i) 466*4882a593Smuzhiyun- if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) 467*4882a593Smuzhiyun- break; 468*4882a593Smuzhiyun+ 469*4882a593Smuzhiyun+ for (i = n - 4; i >= 0; --i) { 470*4882a593Smuzhiyun+ mz_uint s = MZ_READ_LE32(pBuf + i); 471*4882a593Smuzhiyun+ if (s == record_sig) { 472*4882a593Smuzhiyun+ if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size) 473*4882a593Smuzhiyun+ break; 474*4882a593Smuzhiyun+ } 475*4882a593Smuzhiyun+ } 476*4882a593Smuzhiyun+ 477*4882a593Smuzhiyun if (i >= 0) { 478*4882a593Smuzhiyun cur_file_ofs += i; 479*4882a593Smuzhiyun break; 480*4882a593Smuzhiyun } 481*4882a593Smuzhiyun+ 482*4882a593Smuzhiyun+ /* Give up if we've searched the entire file, or we've gone back "too far" 483*4882a593Smuzhiyun+ * (~64kb) */ 484*4882a593Smuzhiyun if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= 485*4882a593Smuzhiyun- (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) 486*4882a593Smuzhiyun+ (MZ_UINT16_MAX + record_size))) 487*4882a593Smuzhiyun return MZ_FALSE; 488*4882a593Smuzhiyun+ 489*4882a593Smuzhiyun cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); 490*4882a593Smuzhiyun } 491*4882a593Smuzhiyun- // Read and verify the end of central directory record. 492*4882a593Smuzhiyun+ 493*4882a593Smuzhiyun+ *pOfs = cur_file_ofs; 494*4882a593Smuzhiyun+ return MZ_TRUE; 495*4882a593Smuzhiyun+} 496*4882a593Smuzhiyun+ 497*4882a593Smuzhiyun+static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, 498*4882a593Smuzhiyun+ mz_uint flags) { 499*4882a593Smuzhiyun+ mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, 500*4882a593Smuzhiyun+ cdir_disk_index = 0; 501*4882a593Smuzhiyun+ mz_uint64 cdir_ofs = 0; 502*4882a593Smuzhiyun+ mz_int64 cur_file_ofs = 0; 503*4882a593Smuzhiyun+ const mz_uint8 *p; 504*4882a593Smuzhiyun+ 505*4882a593Smuzhiyun+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; 506*4882a593Smuzhiyun+ mz_uint8 *pBuf = (mz_uint8 *)buf_u32; 507*4882a593Smuzhiyun+ mz_bool sort_central_dir = 508*4882a593Smuzhiyun+ ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); 509*4882a593Smuzhiyun+ mz_uint32 zip64_end_of_central_dir_locator_u32 510*4882a593Smuzhiyun+ [(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / 511*4882a593Smuzhiyun+ sizeof(mz_uint32)]; 512*4882a593Smuzhiyun+ mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32; 513*4882a593Smuzhiyun+ 514*4882a593Smuzhiyun+ mz_uint32 zip64_end_of_central_dir_header_u32 515*4882a593Smuzhiyun+ [(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / 516*4882a593Smuzhiyun+ sizeof(mz_uint32)]; 517*4882a593Smuzhiyun+ mz_uint8 *pZip64_end_of_central_dir = 518*4882a593Smuzhiyun+ (mz_uint8 *)zip64_end_of_central_dir_header_u32; 519*4882a593Smuzhiyun+ 520*4882a593Smuzhiyun+ mz_uint64 zip64_end_of_central_dir_ofs = 0; 521*4882a593Smuzhiyun+ 522*4882a593Smuzhiyun+ /* Basic sanity checks - reject files which are too small, and check the first 523*4882a593Smuzhiyun+ * 4 bytes of the file to make sure a local header is there. */ 524*4882a593Smuzhiyun+ if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) 525*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); 526*4882a593Smuzhiyun+ 527*4882a593Smuzhiyun+ if (!mz_zip_reader_locate_header_sig( 528*4882a593Smuzhiyun+ pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, 529*4882a593Smuzhiyun+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs)) 530*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR); 531*4882a593Smuzhiyun+ 532*4882a593Smuzhiyun+ /* Read and verify the end of central directory record. */ 533*4882a593Smuzhiyun if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, 534*4882a593Smuzhiyun MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != 535*4882a593Smuzhiyun MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) 536*4882a593Smuzhiyun- return MZ_FALSE; 537*4882a593Smuzhiyun- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != 538*4882a593Smuzhiyun- MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || 539*4882a593Smuzhiyun- ((pZip->m_total_files = 540*4882a593Smuzhiyun- MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != 541*4882a593Smuzhiyun- MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) 542*4882a593Smuzhiyun- return MZ_FALSE; 543*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); 544*4882a593Smuzhiyun+ 545*4882a593Smuzhiyun+ if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != 546*4882a593Smuzhiyun+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) 547*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); 548*4882a593Smuzhiyun+ 549*4882a593Smuzhiyun+ if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + 550*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) { 551*4882a593Smuzhiyun+ if (pZip->m_pRead(pZip->m_pIO_opaque, 552*4882a593Smuzhiyun+ cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, 553*4882a593Smuzhiyun+ pZip64_locator, 554*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == 555*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) { 556*4882a593Smuzhiyun+ if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == 557*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) { 558*4882a593Smuzhiyun+ zip64_end_of_central_dir_ofs = MZ_READ_LE64( 559*4882a593Smuzhiyun+ pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS); 560*4882a593Smuzhiyun+ if (zip64_end_of_central_dir_ofs > 561*4882a593Smuzhiyun+ (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) 562*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); 563*4882a593Smuzhiyun+ 564*4882a593Smuzhiyun+ if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, 565*4882a593Smuzhiyun+ pZip64_end_of_central_dir, 566*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == 567*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) { 568*4882a593Smuzhiyun+ if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == 569*4882a593Smuzhiyun+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) { 570*4882a593Smuzhiyun+ pZip->m_pState->m_zip64 = MZ_TRUE; 571*4882a593Smuzhiyun+ } 572*4882a593Smuzhiyun+ } 573*4882a593Smuzhiyun+ } 574*4882a593Smuzhiyun+ } 575*4882a593Smuzhiyun+ } 576*4882a593Smuzhiyun 577*4882a593Smuzhiyun+ pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS); 578*4882a593Smuzhiyun+ cdir_entries_on_this_disk = 579*4882a593Smuzhiyun+ MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); 580*4882a593Smuzhiyun num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); 581*4882a593Smuzhiyun cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); 582*4882a593Smuzhiyun+ cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS); 583*4882a593Smuzhiyun+ cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); 584*4882a593Smuzhiyun+ 585*4882a593Smuzhiyun+ if (pZip->m_pState->m_zip64) { 586*4882a593Smuzhiyun+ mz_uint32 zip64_total_num_of_disks = 587*4882a593Smuzhiyun+ MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS); 588*4882a593Smuzhiyun+ mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64( 589*4882a593Smuzhiyun+ pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS); 590*4882a593Smuzhiyun+ mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64( 591*4882a593Smuzhiyun+ pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); 592*4882a593Smuzhiyun+ mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64( 593*4882a593Smuzhiyun+ pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS); 594*4882a593Smuzhiyun+ mz_uint64 zip64_size_of_central_directory = 595*4882a593Smuzhiyun+ MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS); 596*4882a593Smuzhiyun+ 597*4882a593Smuzhiyun+ if (zip64_size_of_end_of_central_dir_record < 598*4882a593Smuzhiyun+ (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12)) 599*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 600*4882a593Smuzhiyun+ 601*4882a593Smuzhiyun+ if (zip64_total_num_of_disks != 1U) 602*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); 603*4882a593Smuzhiyun+ 604*4882a593Smuzhiyun+ /* Check for miniz's practical limits */ 605*4882a593Smuzhiyun+ if (zip64_cdir_total_entries > MZ_UINT32_MAX) 606*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); 607*4882a593Smuzhiyun+ 608*4882a593Smuzhiyun+ pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries; 609*4882a593Smuzhiyun+ 610*4882a593Smuzhiyun+ if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX) 611*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); 612*4882a593Smuzhiyun+ 613*4882a593Smuzhiyun+ cdir_entries_on_this_disk = 614*4882a593Smuzhiyun+ (mz_uint32)zip64_cdir_total_entries_on_this_disk; 615*4882a593Smuzhiyun+ 616*4882a593Smuzhiyun+ /* Check for miniz's current practical limits (sorry, this should be enough 617*4882a593Smuzhiyun+ * for millions of files) */ 618*4882a593Smuzhiyun+ if (zip64_size_of_central_directory > MZ_UINT32_MAX) 619*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); 620*4882a593Smuzhiyun+ 621*4882a593Smuzhiyun+ cdir_size = (mz_uint32)zip64_size_of_central_directory; 622*4882a593Smuzhiyun+ 623*4882a593Smuzhiyun+ num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + 624*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS); 625*4882a593Smuzhiyun+ 626*4882a593Smuzhiyun+ cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + 627*4882a593Smuzhiyun+ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS); 628*4882a593Smuzhiyun+ 629*4882a593Smuzhiyun+ cdir_ofs = 630*4882a593Smuzhiyun+ MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS); 631*4882a593Smuzhiyun+ } 632*4882a593Smuzhiyun+ 633*4882a593Smuzhiyun+ if (pZip->m_total_files != cdir_entries_on_this_disk) 634*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); 635*4882a593Smuzhiyun+ 636*4882a593Smuzhiyun if (((num_this_disk | cdir_disk_index) != 0) && 637*4882a593Smuzhiyun ((num_this_disk != 1) || (cdir_disk_index != 1))) 638*4882a593Smuzhiyun- return MZ_FALSE; 639*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); 640*4882a593Smuzhiyun 641*4882a593Smuzhiyun- if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < 642*4882a593Smuzhiyun- pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) 643*4882a593Smuzhiyun- return MZ_FALSE; 644*4882a593Smuzhiyun+ if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) 645*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 646*4882a593Smuzhiyun 647*4882a593Smuzhiyun- cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); 648*4882a593Smuzhiyun if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) 649*4882a593Smuzhiyun- return MZ_FALSE; 650*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 651*4882a593Smuzhiyun 652*4882a593Smuzhiyun pZip->m_central_directory_file_ofs = cdir_ofs; 653*4882a593Smuzhiyun 654*4882a593Smuzhiyun if (pZip->m_total_files) { 655*4882a593Smuzhiyun mz_uint i, n; 656*4882a593Smuzhiyun- 657*4882a593Smuzhiyun- // Read the entire central directory into a heap block, and allocate another 658*4882a593Smuzhiyun- // heap block to hold the unsorted central dir file record offsets, and 659*4882a593Smuzhiyun- // another to hold the sorted indices. 660*4882a593Smuzhiyun+ /* Read the entire central directory into a heap block, and allocate another 661*4882a593Smuzhiyun+ * heap block to hold the unsorted central dir file record offsets, and 662*4882a593Smuzhiyun+ * possibly another to hold the sorted indices. */ 663*4882a593Smuzhiyun if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, 664*4882a593Smuzhiyun MZ_FALSE)) || 665*4882a593Smuzhiyun (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, 666*4882a593Smuzhiyun pZip->m_total_files, MZ_FALSE))) 667*4882a593Smuzhiyun- return MZ_FALSE; 668*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); 669*4882a593Smuzhiyun 670*4882a593Smuzhiyun if (sort_central_dir) { 671*4882a593Smuzhiyun if (!mz_zip_array_resize(pZip, 672*4882a593Smuzhiyun &pZip->m_pState->m_sorted_central_dir_offsets, 673*4882a593Smuzhiyun pZip->m_total_files, MZ_FALSE)) 674*4882a593Smuzhiyun- return MZ_FALSE; 675*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); 676*4882a593Smuzhiyun } 677*4882a593Smuzhiyun 678*4882a593Smuzhiyun if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, 679*4882a593Smuzhiyun pZip->m_pState->m_central_dir.m_p, 680*4882a593Smuzhiyun cdir_size) != cdir_size) 681*4882a593Smuzhiyun- return MZ_FALSE; 682*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); 683*4882a593Smuzhiyun 684*4882a593Smuzhiyun- // Now create an index into the central directory file records, do some 685*4882a593Smuzhiyun- // basic sanity checking on each record, and check for zip64 entries (which 686*4882a593Smuzhiyun- // are not yet supported). 687*4882a593Smuzhiyun+ /* Now create an index into the central directory file records, do some 688*4882a593Smuzhiyun+ * basic sanity checking on each record */ 689*4882a593Smuzhiyun p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; 690*4882a593Smuzhiyun for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) { 691*4882a593Smuzhiyun- mz_uint total_header_size, comp_size, decomp_size, disk_index; 692*4882a593Smuzhiyun+ mz_uint total_header_size, disk_index, bit_flags, filename_size, 693*4882a593Smuzhiyun+ ext_data_size; 694*4882a593Smuzhiyun+ mz_uint64 comp_size, decomp_size, local_header_ofs; 695*4882a593Smuzhiyun+ 696*4882a593Smuzhiyun if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || 697*4882a593Smuzhiyun (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) 698*4882a593Smuzhiyun- return MZ_FALSE; 699*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 700*4882a593Smuzhiyun+ 701*4882a593Smuzhiyun MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, 702*4882a593Smuzhiyun i) = 703*4882a593Smuzhiyun (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); 704*4882a593Smuzhiyun+ 705*4882a593Smuzhiyun if (sort_central_dir) 706*4882a593Smuzhiyun MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, 707*4882a593Smuzhiyun mz_uint32, i) = i; 708*4882a593Smuzhiyun+ 709*4882a593Smuzhiyun comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); 710*4882a593Smuzhiyun decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); 711*4882a593Smuzhiyun- if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && 712*4882a593Smuzhiyun- (decomp_size != comp_size)) || 713*4882a593Smuzhiyun- (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || 714*4882a593Smuzhiyun- (comp_size == 0xFFFFFFFF)) 715*4882a593Smuzhiyun- return MZ_FALSE; 716*4882a593Smuzhiyun+ local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); 717*4882a593Smuzhiyun+ filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); 718*4882a593Smuzhiyun+ ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); 719*4882a593Smuzhiyun+ 720*4882a593Smuzhiyun+ if ((!pZip->m_pState->m_zip64_has_extended_info_fields) && 721*4882a593Smuzhiyun+ (ext_data_size) && 722*4882a593Smuzhiyun+ (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == 723*4882a593Smuzhiyun+ MZ_UINT32_MAX)) { 724*4882a593Smuzhiyun+ /* Attempt to find zip64 extended information field in the entry's extra 725*4882a593Smuzhiyun+ * data */ 726*4882a593Smuzhiyun+ mz_uint32 extra_size_remaining = ext_data_size; 727*4882a593Smuzhiyun+ 728*4882a593Smuzhiyun+ if (extra_size_remaining) { 729*4882a593Smuzhiyun+ const mz_uint8 *pExtra_data; 730*4882a593Smuzhiyun+ void *buf = NULL; 731*4882a593Smuzhiyun+ 732*4882a593Smuzhiyun+ if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > 733*4882a593Smuzhiyun+ n) { 734*4882a593Smuzhiyun+ buf = MZ_MALLOC(ext_data_size); 735*4882a593Smuzhiyun+ if (buf == NULL) 736*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); 737*4882a593Smuzhiyun+ 738*4882a593Smuzhiyun+ if (pZip->m_pRead(pZip->m_pIO_opaque, 739*4882a593Smuzhiyun+ cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + 740*4882a593Smuzhiyun+ filename_size, 741*4882a593Smuzhiyun+ buf, ext_data_size) != ext_data_size) { 742*4882a593Smuzhiyun+ MZ_FREE(buf); 743*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); 744*4882a593Smuzhiyun+ } 745*4882a593Smuzhiyun+ 746*4882a593Smuzhiyun+ pExtra_data = (mz_uint8 *)buf; 747*4882a593Smuzhiyun+ } else { 748*4882a593Smuzhiyun+ pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; 749*4882a593Smuzhiyun+ } 750*4882a593Smuzhiyun+ 751*4882a593Smuzhiyun+ do { 752*4882a593Smuzhiyun+ mz_uint32 field_id; 753*4882a593Smuzhiyun+ mz_uint32 field_data_size; 754*4882a593Smuzhiyun+ 755*4882a593Smuzhiyun+ if (extra_size_remaining < (sizeof(mz_uint16) * 2)) { 756*4882a593Smuzhiyun+ MZ_FREE(buf); 757*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 758*4882a593Smuzhiyun+ } 759*4882a593Smuzhiyun+ 760*4882a593Smuzhiyun+ field_id = MZ_READ_LE16(pExtra_data); 761*4882a593Smuzhiyun+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); 762*4882a593Smuzhiyun+ 763*4882a593Smuzhiyun+ if ((field_data_size + sizeof(mz_uint16) * 2) > 764*4882a593Smuzhiyun+ extra_size_remaining) { 765*4882a593Smuzhiyun+ MZ_FREE(buf); 766*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 767*4882a593Smuzhiyun+ } 768*4882a593Smuzhiyun+ 769*4882a593Smuzhiyun+ if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { 770*4882a593Smuzhiyun+ /* Ok, the archive didn't have any zip64 headers but it uses a 771*4882a593Smuzhiyun+ * zip64 extended information field so mark it as zip64 anyway 772*4882a593Smuzhiyun+ * (this can occur with infozip's zip util when it reads 773*4882a593Smuzhiyun+ * compresses files from stdin). */ 774*4882a593Smuzhiyun+ pZip->m_pState->m_zip64 = MZ_TRUE; 775*4882a593Smuzhiyun+ pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE; 776*4882a593Smuzhiyun+ break; 777*4882a593Smuzhiyun+ } 778*4882a593Smuzhiyun+ 779*4882a593Smuzhiyun+ pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; 780*4882a593Smuzhiyun+ extra_size_remaining = 781*4882a593Smuzhiyun+ extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; 782*4882a593Smuzhiyun+ } while (extra_size_remaining); 783*4882a593Smuzhiyun+ 784*4882a593Smuzhiyun+ MZ_FREE(buf); 785*4882a593Smuzhiyun+ } 786*4882a593Smuzhiyun+ } 787*4882a593Smuzhiyun+ 788*4882a593Smuzhiyun+ /* I've seen archives that aren't marked as zip64 that uses zip64 ext 789*4882a593Smuzhiyun+ * data, argh */ 790*4882a593Smuzhiyun+ if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) { 791*4882a593Smuzhiyun+ if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && 792*4882a593Smuzhiyun+ (decomp_size != comp_size)) || 793*4882a593Smuzhiyun+ (decomp_size && !comp_size)) 794*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 795*4882a593Smuzhiyun+ } 796*4882a593Smuzhiyun+ 797*4882a593Smuzhiyun disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); 798*4882a593Smuzhiyun- if ((disk_index != num_this_disk) && (disk_index != 1)) 799*4882a593Smuzhiyun- return MZ_FALSE; 800*4882a593Smuzhiyun- if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + 801*4882a593Smuzhiyun- MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) 802*4882a593Smuzhiyun- return MZ_FALSE; 803*4882a593Smuzhiyun+ if ((disk_index == MZ_UINT16_MAX) || 804*4882a593Smuzhiyun+ ((disk_index != num_this_disk) && (disk_index != 1))) 805*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); 806*4882a593Smuzhiyun+ 807*4882a593Smuzhiyun+ if (comp_size != MZ_UINT32_MAX) { 808*4882a593Smuzhiyun+ if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + 809*4882a593Smuzhiyun+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) 810*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 811*4882a593Smuzhiyun+ } 812*4882a593Smuzhiyun+ 813*4882a593Smuzhiyun+ bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); 814*4882a593Smuzhiyun+ if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED) 815*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); 816*4882a593Smuzhiyun+ 817*4882a593Smuzhiyun if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + 818*4882a593Smuzhiyun MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + 819*4882a593Smuzhiyun MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + 820*4882a593Smuzhiyun MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > 821*4882a593Smuzhiyun n) 822*4882a593Smuzhiyun- return MZ_FALSE; 823*4882a593Smuzhiyun+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); 824*4882a593Smuzhiyun+ 825*4882a593Smuzhiyun n -= total_header_size; 826*4882a593Smuzhiyun p += total_header_size; 827*4882a593Smuzhiyun } 828*4882a593Smuzhiyundiff --git a/contrib/zip/src/zip.c b/contrib/zip/src/zip.c 829*4882a593Smuzhiyunindex ff3a8fe1e6..1abcfd8fd1 100644 830*4882a593Smuzhiyun--- a/contrib/zip/src/zip.c 831*4882a593Smuzhiyun+++ b/contrib/zip/src/zip.c 832*4882a593Smuzhiyun@@ -24,7 +24,6 @@ 833*4882a593Smuzhiyun ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \ 834*4882a593Smuzhiyun (P)[1] == ':') 835*4882a593Smuzhiyun #define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE(P) ? 2 : 0) 836*4882a593Smuzhiyun-#define ISSLASH(C) ((C) == '/' || (C) == '\\') 837*4882a593Smuzhiyun 838*4882a593Smuzhiyun #else 839*4882a593Smuzhiyun 840*4882a593Smuzhiyun@@ -48,7 +47,7 @@ int symlink(const char *target, const char *linkpath); // needed on Linux 841*4882a593Smuzhiyun #endif 842*4882a593Smuzhiyun 843*4882a593Smuzhiyun #ifndef ISSLASH 844*4882a593Smuzhiyun-#define ISSLASH(C) ((C) == '/') 845*4882a593Smuzhiyun+#define ISSLASH(C) ((C) == '/' || (C) == '\\') 846*4882a593Smuzhiyun #endif 847*4882a593Smuzhiyun 848*4882a593Smuzhiyun #define CLEANUP(ptr) \ 849*4882a593Smuzhiyun@@ -78,26 +77,34 @@ static const char *base_name(const char *name) { 850*4882a593Smuzhiyun return base; 851*4882a593Smuzhiyun } 852*4882a593Smuzhiyun 853*4882a593Smuzhiyun-static int mkpath(const char *path) { 854*4882a593Smuzhiyun- char const *p; 855*4882a593Smuzhiyun+static int mkpath(char *path) { 856*4882a593Smuzhiyun+ char *p; 857*4882a593Smuzhiyun char npath[MAX_PATH + 1]; 858*4882a593Smuzhiyun int len = 0; 859*4882a593Smuzhiyun int has_device = HAS_DEVICE(path); 860*4882a593Smuzhiyun 861*4882a593Smuzhiyun memset(npath, 0, MAX_PATH + 1); 862*4882a593Smuzhiyun- 863*4882a593Smuzhiyun-#ifdef _WIN32 864*4882a593Smuzhiyun- // only on windows fix the path 865*4882a593Smuzhiyun- npath[0] = path[0]; 866*4882a593Smuzhiyun- npath[1] = path[1]; 867*4882a593Smuzhiyun- len = 2; 868*4882a593Smuzhiyun-#endif // _WIN32 869*4882a593Smuzhiyun- 870*4882a593Smuzhiyun+ if (has_device) { 871*4882a593Smuzhiyun+ // only on windows 872*4882a593Smuzhiyun+ npath[0] = path[0]; 873*4882a593Smuzhiyun+ npath[1] = path[1]; 874*4882a593Smuzhiyun+ len = 2; 875*4882a593Smuzhiyun+ } 876*4882a593Smuzhiyun for (p = path + len; *p && len < MAX_PATH; p++) { 877*4882a593Smuzhiyun if (ISSLASH(*p) && ((!has_device && len > 0) || (has_device && len > 2))) { 878*4882a593Smuzhiyun- if (MKDIR(npath) == -1) 879*4882a593Smuzhiyun- if (errno != EEXIST) 880*4882a593Smuzhiyun+#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ 881*4882a593Smuzhiyun+ defined(__MINGW32__) 882*4882a593Smuzhiyun+#else 883*4882a593Smuzhiyun+ if ('\\' == *p) { 884*4882a593Smuzhiyun+ *p = '/'; 885*4882a593Smuzhiyun+ } 886*4882a593Smuzhiyun+#endif 887*4882a593Smuzhiyun+ 888*4882a593Smuzhiyun+ if (MKDIR(npath) == -1) { 889*4882a593Smuzhiyun+ if (errno != EEXIST) { 890*4882a593Smuzhiyun return -1; 891*4882a593Smuzhiyun+ } 892*4882a593Smuzhiyun+ } 893*4882a593Smuzhiyun } 894*4882a593Smuzhiyun npath[len++] = *p; 895*4882a593Smuzhiyun } 896*4882a593Smuzhiyun@@ -279,7 +286,14 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { 897*4882a593Smuzhiyun zip->entry.header_offset = zip->archive.m_archive_size; 898*4882a593Smuzhiyun memset(zip->entry.header, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE * sizeof(mz_uint8)); 899*4882a593Smuzhiyun zip->entry.method = 0; 900*4882a593Smuzhiyun+ 901*4882a593Smuzhiyun+ // UNIX or APPLE 902*4882a593Smuzhiyun+#if MZ_PLATFORM == 3 || MZ_PLATFORM == 19 903*4882a593Smuzhiyun+ // regular file with rw-r--r-- persmissions 904*4882a593Smuzhiyun+ zip->entry.external_attr = (mz_uint32)(0100644) << 16; 905*4882a593Smuzhiyun+#else 906*4882a593Smuzhiyun zip->entry.external_attr = 0; 907*4882a593Smuzhiyun+#endif 908*4882a593Smuzhiyun 909*4882a593Smuzhiyun num_alignment_padding_bytes = 910*4882a593Smuzhiyun mz_zip_writer_compute_padding_needed_for_file_alignment(pzip); 911*4882a593Smuzhiyun@@ -660,7 +674,7 @@ ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize) { 912*4882a593Smuzhiyun } 913*4882a593Smuzhiyun 914*4882a593Smuzhiyun if (!mz_zip_reader_extract_to_mem_no_alloc(pzip, (mz_uint)zip->entry.index, 915*4882a593Smuzhiyun- buf, bufsize, 0, NULL, 0)) { 916*4882a593Smuzhiyun+ buf, bufsize, 0, NULL, 0)) { 917*4882a593Smuzhiyun return -1; 918*4882a593Smuzhiyun } 919*4882a593Smuzhiyun 920*4882a593Smuzhiyun@@ -670,10 +684,7 @@ ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize) { 921*4882a593Smuzhiyun int zip_entry_fread(struct zip_t *zip, const char *filename) { 922*4882a593Smuzhiyun mz_zip_archive *pzip = NULL; 923*4882a593Smuzhiyun mz_uint idx; 924*4882a593Smuzhiyun-#if defined(_MSC_VER) 925*4882a593Smuzhiyun-#else 926*4882a593Smuzhiyun mz_uint32 xattr = 0; 927*4882a593Smuzhiyun-#endif 928*4882a593Smuzhiyun mz_zip_archive_file_stat info; 929*4882a593Smuzhiyun 930*4882a593Smuzhiyun if (!zip) { 931*4882a593Smuzhiyun@@ -875,12 +886,19 @@ int zip_extract(const char *zipname, const char *dir, 932*4882a593Smuzhiyun goto out; 933*4882a593Smuzhiyun } 934*4882a593Smuzhiyun 935*4882a593Smuzhiyun- if ((((info.m_version_made_by >> 8) == 3) || ((info.m_version_made_by >> 8) == 19)) // if zip is produced on Unix or macOS (3 and 19 from section 4.4.2.2 of zip standard) 936*4882a593Smuzhiyun- && info.m_external_attr & (0x20 << 24)) { // and has sym link attribute (0x80 is file, 0x40 is directory) 937*4882a593Smuzhiyun+ if ((((info.m_version_made_by >> 8) == 3) || 938*4882a593Smuzhiyun+ ((info.m_version_made_by >> 8) == 939*4882a593Smuzhiyun+ 19)) // if zip is produced on Unix or macOS (3 and 19 from 940*4882a593Smuzhiyun+ // section 4.4.2.2 of zip standard) 941*4882a593Smuzhiyun+ && info.m_external_attr & 942*4882a593Smuzhiyun+ (0x20 << 24)) { // and has sym link attribute (0x80 is file, 0x40 943*4882a593Smuzhiyun+ // is directory) 944*4882a593Smuzhiyun #if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ 945*4882a593Smuzhiyun defined(__MINGW32__) 946*4882a593Smuzhiyun-#else 947*4882a593Smuzhiyun- if (info.m_uncomp_size > MAX_PATH || !mz_zip_reader_extract_to_mem_no_alloc(&zip_archive, i, symlink_to, MAX_PATH, 0, NULL, 0)) { 948*4882a593Smuzhiyun+#else 949*4882a593Smuzhiyun+ if (info.m_uncomp_size > MAX_PATH || 950*4882a593Smuzhiyun+ !mz_zip_reader_extract_to_mem_no_alloc(&zip_archive, i, symlink_to, 951*4882a593Smuzhiyun+ MAX_PATH, 0, NULL, 0)) { 952*4882a593Smuzhiyun goto out; 953*4882a593Smuzhiyun } 954*4882a593Smuzhiyun symlink_to[info.m_uncomp_size] = '\0'; 955*4882a593Smuzhiyundiff --git a/contrib/zip/src/zip.h b/contrib/zip/src/zip.h 956*4882a593Smuzhiyunindex 5f39df50ad..a48d64d6de 100644 957*4882a593Smuzhiyun--- a/contrib/zip/src/zip.h 958*4882a593Smuzhiyun+++ b/contrib/zip/src/zip.h 959*4882a593Smuzhiyun@@ -20,241 +20,240 @@ extern "C" { 960*4882a593Smuzhiyun #endif 961*4882a593Smuzhiyun 962*4882a593Smuzhiyun #if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \ 963*4882a593Smuzhiyun- !defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(__ssize_t_defined) 964*4882a593Smuzhiyun-#define _SSIZE_T 965*4882a593Smuzhiyun+ !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \ 966*4882a593Smuzhiyun+ !defined(_SSIZE_T) && !defined(_SSIZE_T_) 967*4882a593Smuzhiyun+ 968*4882a593Smuzhiyun // 64-bit Windows is the only mainstream platform 969*4882a593Smuzhiyun // where sizeof(long) != sizeof(void*) 970*4882a593Smuzhiyun #ifdef _WIN64 971*4882a593Smuzhiyun-typedef long long ssize_t; /* byte count or error */ 972*4882a593Smuzhiyun+typedef long long ssize_t; /* byte count or error */ 973*4882a593Smuzhiyun #else 974*4882a593Smuzhiyun-typedef long ssize_t; /* byte count or error */ 975*4882a593Smuzhiyun+typedef long ssize_t; /* byte count or error */ 976*4882a593Smuzhiyun #endif 977*4882a593Smuzhiyun+ 978*4882a593Smuzhiyun+#define _SSIZE_T_DEFINED 979*4882a593Smuzhiyun+#define _SSIZE_T_DEFINED_ 980*4882a593Smuzhiyun+#define __DEFINED_ssize_t 981*4882a593Smuzhiyun+#define __ssize_t_defined 982*4882a593Smuzhiyun+#define _SSIZE_T 983*4882a593Smuzhiyun+#define _SSIZE_T_ 984*4882a593Smuzhiyun+ 985*4882a593Smuzhiyun #endif 986*4882a593Smuzhiyun 987*4882a593Smuzhiyun #ifndef MAX_PATH 988*4882a593Smuzhiyun #define MAX_PATH 32767 /* # chars in a path name including NULL */ 989*4882a593Smuzhiyun #endif 990*4882a593Smuzhiyun 991*4882a593Smuzhiyun+/** 992*4882a593Smuzhiyun+ * @mainpage 993*4882a593Smuzhiyun+ * 994*4882a593Smuzhiyun+ * Documenation for @ref zip. 995*4882a593Smuzhiyun+ */ 996*4882a593Smuzhiyun+ 997*4882a593Smuzhiyun+/** 998*4882a593Smuzhiyun+ * @addtogroup zip 999*4882a593Smuzhiyun+ * @{ 1000*4882a593Smuzhiyun+ */ 1001*4882a593Smuzhiyun+ 1002*4882a593Smuzhiyun+/** 1003*4882a593Smuzhiyun+ * Default zip compression level. 1004*4882a593Smuzhiyun+ */ 1005*4882a593Smuzhiyun+ 1006*4882a593Smuzhiyun #define ZIP_DEFAULT_COMPRESSION_LEVEL 6 1007*4882a593Smuzhiyun 1008*4882a593Smuzhiyun-/* 1009*4882a593Smuzhiyun- This data structure is used throughout the library to represent zip archive 1010*4882a593Smuzhiyun- - forward declaration. 1011*4882a593Smuzhiyun-*/ 1012*4882a593Smuzhiyun+/** 1013*4882a593Smuzhiyun+ * @struct zip_t 1014*4882a593Smuzhiyun+ * 1015*4882a593Smuzhiyun+ * This data structure is used throughout the library to represent zip archive - 1016*4882a593Smuzhiyun+ * forward declaration. 1017*4882a593Smuzhiyun+ */ 1018*4882a593Smuzhiyun struct zip_t; 1019*4882a593Smuzhiyun 1020*4882a593Smuzhiyun-/* 1021*4882a593Smuzhiyun- Opens zip archive with compression level using the given mode. 1022*4882a593Smuzhiyun- 1023*4882a593Smuzhiyun- Args: 1024*4882a593Smuzhiyun- zipname: zip archive file name. 1025*4882a593Smuzhiyun- level: compression level (0-9 are the standard zlib-style levels). 1026*4882a593Smuzhiyun- mode: file access mode. 1027*4882a593Smuzhiyun- 'r': opens a file for reading/extracting (the file must exists). 1028*4882a593Smuzhiyun- 'w': creates an empty file for writing. 1029*4882a593Smuzhiyun- 'a': appends to an existing archive. 1030*4882a593Smuzhiyun- 1031*4882a593Smuzhiyun- Returns: 1032*4882a593Smuzhiyun- The zip archive handler or NULL on error 1033*4882a593Smuzhiyun-*/ 1034*4882a593Smuzhiyun+/** 1035*4882a593Smuzhiyun+ * Opens zip archive with compression level using the given mode. 1036*4882a593Smuzhiyun+ * 1037*4882a593Smuzhiyun+ * @param zipname zip archive file name. 1038*4882a593Smuzhiyun+ * @param level compression level (0-9 are the standard zlib-style levels). 1039*4882a593Smuzhiyun+ * @param mode file access mode. 1040*4882a593Smuzhiyun+ * - 'r': opens a file for reading/extracting (the file must exists). 1041*4882a593Smuzhiyun+ * - 'w': creates an empty file for writing. 1042*4882a593Smuzhiyun+ * - 'a': appends to an existing archive. 1043*4882a593Smuzhiyun+ * 1044*4882a593Smuzhiyun+ * @return the zip archive handler or NULL on error 1045*4882a593Smuzhiyun+ */ 1046*4882a593Smuzhiyun extern struct zip_t *zip_open(const char *zipname, int level, char mode); 1047*4882a593Smuzhiyun 1048*4882a593Smuzhiyun-/* 1049*4882a593Smuzhiyun- Closes the zip archive, releases resources - always finalize. 1050*4882a593Smuzhiyun- 1051*4882a593Smuzhiyun- Args: 1052*4882a593Smuzhiyun- zip: zip archive handler. 1053*4882a593Smuzhiyun-*/ 1054*4882a593Smuzhiyun+/** 1055*4882a593Smuzhiyun+ * Closes the zip archive, releases resources - always finalize. 1056*4882a593Smuzhiyun+ * 1057*4882a593Smuzhiyun+ * @param zip zip archive handler. 1058*4882a593Smuzhiyun+ */ 1059*4882a593Smuzhiyun extern void zip_close(struct zip_t *zip); 1060*4882a593Smuzhiyun 1061*4882a593Smuzhiyun-/* 1062*4882a593Smuzhiyun- Opens an entry by name in the zip archive. 1063*4882a593Smuzhiyun- For zip archive opened in 'w' or 'a' mode the function will append 1064*4882a593Smuzhiyun- a new entry. In readonly mode the function tries to locate the entry 1065*4882a593Smuzhiyun- in global dictionary. 1066*4882a593Smuzhiyun- 1067*4882a593Smuzhiyun- Args: 1068*4882a593Smuzhiyun- zip: zip archive handler. 1069*4882a593Smuzhiyun- entryname: an entry name in local dictionary. 1070*4882a593Smuzhiyun- 1071*4882a593Smuzhiyun- Returns: 1072*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1073*4882a593Smuzhiyun-*/ 1074*4882a593Smuzhiyun+/** 1075*4882a593Smuzhiyun+ * Opens an entry by name in the zip archive. 1076*4882a593Smuzhiyun+ * 1077*4882a593Smuzhiyun+ * For zip archive opened in 'w' or 'a' mode the function will append 1078*4882a593Smuzhiyun+ * a new entry. In readonly mode the function tries to locate the entry 1079*4882a593Smuzhiyun+ * in global dictionary. 1080*4882a593Smuzhiyun+ * 1081*4882a593Smuzhiyun+ * @param zip zip archive handler. 1082*4882a593Smuzhiyun+ * @param entryname an entry name in local dictionary. 1083*4882a593Smuzhiyun+ * 1084*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1085*4882a593Smuzhiyun+ */ 1086*4882a593Smuzhiyun extern int zip_entry_open(struct zip_t *zip, const char *entryname); 1087*4882a593Smuzhiyun 1088*4882a593Smuzhiyun-/* 1089*4882a593Smuzhiyun- Opens a new entry by index in the zip archive. 1090*4882a593Smuzhiyun- This function is only valid if zip archive was opened in 'r' (readonly) mode. 1091*4882a593Smuzhiyun- 1092*4882a593Smuzhiyun- Args: 1093*4882a593Smuzhiyun- zip: zip archive handler. 1094*4882a593Smuzhiyun- index: index in local dictionary. 1095*4882a593Smuzhiyun- 1096*4882a593Smuzhiyun- Returns: 1097*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1098*4882a593Smuzhiyun-*/ 1099*4882a593Smuzhiyun+/** 1100*4882a593Smuzhiyun+ * Opens a new entry by index in the zip archive. 1101*4882a593Smuzhiyun+ * 1102*4882a593Smuzhiyun+ * This function is only valid if zip archive was opened in 'r' (readonly) mode. 1103*4882a593Smuzhiyun+ * 1104*4882a593Smuzhiyun+ * @param zip zip archive handler. 1105*4882a593Smuzhiyun+ * @param index index in local dictionary. 1106*4882a593Smuzhiyun+ * 1107*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1108*4882a593Smuzhiyun+ */ 1109*4882a593Smuzhiyun extern int zip_entry_openbyindex(struct zip_t *zip, int index); 1110*4882a593Smuzhiyun 1111*4882a593Smuzhiyun-/* 1112*4882a593Smuzhiyun- Closes a zip entry, flushes buffer and releases resources. 1113*4882a593Smuzhiyun- 1114*4882a593Smuzhiyun- Args: 1115*4882a593Smuzhiyun- zip: zip archive handler. 1116*4882a593Smuzhiyun- 1117*4882a593Smuzhiyun- Returns: 1118*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1119*4882a593Smuzhiyun-*/ 1120*4882a593Smuzhiyun+/** 1121*4882a593Smuzhiyun+ * Closes a zip entry, flushes buffer and releases resources. 1122*4882a593Smuzhiyun+ * 1123*4882a593Smuzhiyun+ * @param zip zip archive handler. 1124*4882a593Smuzhiyun+ * 1125*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1126*4882a593Smuzhiyun+ */ 1127*4882a593Smuzhiyun extern int zip_entry_close(struct zip_t *zip); 1128*4882a593Smuzhiyun 1129*4882a593Smuzhiyun-/* 1130*4882a593Smuzhiyun- Returns a local name of the current zip entry. 1131*4882a593Smuzhiyun- The main difference between user's entry name and local entry name 1132*4882a593Smuzhiyun- is optional relative path. 1133*4882a593Smuzhiyun- Following .ZIP File Format Specification - the path stored MUST not contain 1134*4882a593Smuzhiyun- a drive or device letter, or a leading slash. 1135*4882a593Smuzhiyun- All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' 1136*4882a593Smuzhiyun- for compatibility with Amiga and UNIX file systems etc. 1137*4882a593Smuzhiyun- 1138*4882a593Smuzhiyun- Args: 1139*4882a593Smuzhiyun- zip: zip archive handler. 1140*4882a593Smuzhiyun- 1141*4882a593Smuzhiyun- Returns: 1142*4882a593Smuzhiyun- The pointer to the current zip entry name, or NULL on error. 1143*4882a593Smuzhiyun-*/ 1144*4882a593Smuzhiyun+/** 1145*4882a593Smuzhiyun+ * Returns a local name of the current zip entry. 1146*4882a593Smuzhiyun+ * 1147*4882a593Smuzhiyun+ * The main difference between user's entry name and local entry name 1148*4882a593Smuzhiyun+ * is optional relative path. 1149*4882a593Smuzhiyun+ * Following .ZIP File Format Specification - the path stored MUST not contain 1150*4882a593Smuzhiyun+ * a drive or device letter, or a leading slash. 1151*4882a593Smuzhiyun+ * All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' 1152*4882a593Smuzhiyun+ * for compatibility with Amiga and UNIX file systems etc. 1153*4882a593Smuzhiyun+ * 1154*4882a593Smuzhiyun+ * @param zip: zip archive handler. 1155*4882a593Smuzhiyun+ * 1156*4882a593Smuzhiyun+ * @return the pointer to the current zip entry name, or NULL on error. 1157*4882a593Smuzhiyun+ */ 1158*4882a593Smuzhiyun extern const char *zip_entry_name(struct zip_t *zip); 1159*4882a593Smuzhiyun 1160*4882a593Smuzhiyun-/* 1161*4882a593Smuzhiyun- Returns an index of the current zip entry. 1162*4882a593Smuzhiyun- 1163*4882a593Smuzhiyun- Args: 1164*4882a593Smuzhiyun- zip: zip archive handler. 1165*4882a593Smuzhiyun- 1166*4882a593Smuzhiyun- Returns: 1167*4882a593Smuzhiyun- The index on success, negative number (< 0) on error. 1168*4882a593Smuzhiyun-*/ 1169*4882a593Smuzhiyun+/** 1170*4882a593Smuzhiyun+ * Returns an index of the current zip entry. 1171*4882a593Smuzhiyun+ * 1172*4882a593Smuzhiyun+ * @param zip zip archive handler. 1173*4882a593Smuzhiyun+ * 1174*4882a593Smuzhiyun+ * @return the index on success, negative number (< 0) on error. 1175*4882a593Smuzhiyun+ */ 1176*4882a593Smuzhiyun extern int zip_entry_index(struct zip_t *zip); 1177*4882a593Smuzhiyun 1178*4882a593Smuzhiyun-/* 1179*4882a593Smuzhiyun- Determines if the current zip entry is a directory entry. 1180*4882a593Smuzhiyun- 1181*4882a593Smuzhiyun- Args: 1182*4882a593Smuzhiyun- zip: zip archive handler. 1183*4882a593Smuzhiyun- 1184*4882a593Smuzhiyun- Returns: 1185*4882a593Smuzhiyun- The return code - 1 (true), 0 (false), negative number (< 0) on error. 1186*4882a593Smuzhiyun-*/ 1187*4882a593Smuzhiyun+/** 1188*4882a593Smuzhiyun+ * Determines if the current zip entry is a directory entry. 1189*4882a593Smuzhiyun+ * 1190*4882a593Smuzhiyun+ * @param zip zip archive handler. 1191*4882a593Smuzhiyun+ * 1192*4882a593Smuzhiyun+ * @return the return code - 1 (true), 0 (false), negative number (< 0) on 1193*4882a593Smuzhiyun+ * error. 1194*4882a593Smuzhiyun+ */ 1195*4882a593Smuzhiyun extern int zip_entry_isdir(struct zip_t *zip); 1196*4882a593Smuzhiyun 1197*4882a593Smuzhiyun-/* 1198*4882a593Smuzhiyun- Returns an uncompressed size of the current zip entry. 1199*4882a593Smuzhiyun- 1200*4882a593Smuzhiyun- Args: 1201*4882a593Smuzhiyun- zip: zip archive handler. 1202*4882a593Smuzhiyun- 1203*4882a593Smuzhiyun- Returns: 1204*4882a593Smuzhiyun- The uncompressed size in bytes. 1205*4882a593Smuzhiyun-*/ 1206*4882a593Smuzhiyun+/** 1207*4882a593Smuzhiyun+ * Returns an uncompressed size of the current zip entry. 1208*4882a593Smuzhiyun+ * 1209*4882a593Smuzhiyun+ * @param zip zip archive handler. 1210*4882a593Smuzhiyun+ * 1211*4882a593Smuzhiyun+ * @return the uncompressed size in bytes. 1212*4882a593Smuzhiyun+ */ 1213*4882a593Smuzhiyun extern unsigned long long zip_entry_size(struct zip_t *zip); 1214*4882a593Smuzhiyun 1215*4882a593Smuzhiyun-/* 1216*4882a593Smuzhiyun- Returns CRC-32 checksum of the current zip entry. 1217*4882a593Smuzhiyun- 1218*4882a593Smuzhiyun- Args: 1219*4882a593Smuzhiyun- zip: zip archive handler. 1220*4882a593Smuzhiyun- 1221*4882a593Smuzhiyun- Returns: 1222*4882a593Smuzhiyun- The CRC-32 checksum. 1223*4882a593Smuzhiyun-*/ 1224*4882a593Smuzhiyun+/** 1225*4882a593Smuzhiyun+ * Returns CRC-32 checksum of the current zip entry. 1226*4882a593Smuzhiyun+ * 1227*4882a593Smuzhiyun+ * @param zip zip archive handler. 1228*4882a593Smuzhiyun+ * 1229*4882a593Smuzhiyun+ * @return the CRC-32 checksum. 1230*4882a593Smuzhiyun+ */ 1231*4882a593Smuzhiyun extern unsigned int zip_entry_crc32(struct zip_t *zip); 1232*4882a593Smuzhiyun 1233*4882a593Smuzhiyun-/* 1234*4882a593Smuzhiyun- Compresses an input buffer for the current zip entry. 1235*4882a593Smuzhiyun- 1236*4882a593Smuzhiyun- Args: 1237*4882a593Smuzhiyun- zip: zip archive handler. 1238*4882a593Smuzhiyun- buf: input buffer. 1239*4882a593Smuzhiyun- bufsize: input buffer size (in bytes). 1240*4882a593Smuzhiyun- 1241*4882a593Smuzhiyun- Returns: 1242*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1243*4882a593Smuzhiyun-*/ 1244*4882a593Smuzhiyun+/** 1245*4882a593Smuzhiyun+ * Compresses an input buffer for the current zip entry. 1246*4882a593Smuzhiyun+ * 1247*4882a593Smuzhiyun+ * @param zip zip archive handler. 1248*4882a593Smuzhiyun+ * @param buf input buffer. 1249*4882a593Smuzhiyun+ * @param bufsize input buffer size (in bytes). 1250*4882a593Smuzhiyun+ * 1251*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1252*4882a593Smuzhiyun+ */ 1253*4882a593Smuzhiyun extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize); 1254*4882a593Smuzhiyun 1255*4882a593Smuzhiyun-/* 1256*4882a593Smuzhiyun- Compresses a file for the current zip entry. 1257*4882a593Smuzhiyun- 1258*4882a593Smuzhiyun- Args: 1259*4882a593Smuzhiyun- zip: zip archive handler. 1260*4882a593Smuzhiyun- filename: input file. 1261*4882a593Smuzhiyun- 1262*4882a593Smuzhiyun- Returns: 1263*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1264*4882a593Smuzhiyun-*/ 1265*4882a593Smuzhiyun+/** 1266*4882a593Smuzhiyun+ * Compresses a file for the current zip entry. 1267*4882a593Smuzhiyun+ * 1268*4882a593Smuzhiyun+ * @param zip zip archive handler. 1269*4882a593Smuzhiyun+ * @param filename input file. 1270*4882a593Smuzhiyun+ * 1271*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1272*4882a593Smuzhiyun+ */ 1273*4882a593Smuzhiyun extern int zip_entry_fwrite(struct zip_t *zip, const char *filename); 1274*4882a593Smuzhiyun 1275*4882a593Smuzhiyun-/* 1276*4882a593Smuzhiyun- Extracts the current zip entry into output buffer. 1277*4882a593Smuzhiyun- The function allocates sufficient memory for a output buffer. 1278*4882a593Smuzhiyun- 1279*4882a593Smuzhiyun- Args: 1280*4882a593Smuzhiyun- zip: zip archive handler. 1281*4882a593Smuzhiyun- buf: output buffer. 1282*4882a593Smuzhiyun- bufsize: output buffer size (in bytes). 1283*4882a593Smuzhiyun- 1284*4882a593Smuzhiyun- Note: 1285*4882a593Smuzhiyun- - remember to release memory allocated for a output buffer. 1286*4882a593Smuzhiyun- - for large entries, please take a look at zip_entry_extract function. 1287*4882a593Smuzhiyun- 1288*4882a593Smuzhiyun- Returns: 1289*4882a593Smuzhiyun- The return code - the number of bytes actually read on success. 1290*4882a593Smuzhiyun- Otherwise a -1 on error. 1291*4882a593Smuzhiyun-*/ 1292*4882a593Smuzhiyun+/** 1293*4882a593Smuzhiyun+ * Extracts the current zip entry into output buffer. 1294*4882a593Smuzhiyun+ * 1295*4882a593Smuzhiyun+ * The function allocates sufficient memory for a output buffer. 1296*4882a593Smuzhiyun+ * 1297*4882a593Smuzhiyun+ * @param zip zip archive handler. 1298*4882a593Smuzhiyun+ * @param buf output buffer. 1299*4882a593Smuzhiyun+ * @param bufsize output buffer size (in bytes). 1300*4882a593Smuzhiyun+ * 1301*4882a593Smuzhiyun+ * @note remember to release memory allocated for a output buffer. 1302*4882a593Smuzhiyun+ * for large entries, please take a look at zip_entry_extract function. 1303*4882a593Smuzhiyun+ * 1304*4882a593Smuzhiyun+ * @return the return code - the number of bytes actually read on success. 1305*4882a593Smuzhiyun+ * Otherwise a -1 on error. 1306*4882a593Smuzhiyun+ */ 1307*4882a593Smuzhiyun extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize); 1308*4882a593Smuzhiyun 1309*4882a593Smuzhiyun-/* 1310*4882a593Smuzhiyun- Extracts the current zip entry into a memory buffer using no memory 1311*4882a593Smuzhiyun- allocation. 1312*4882a593Smuzhiyun- 1313*4882a593Smuzhiyun- Args: 1314*4882a593Smuzhiyun- zip: zip archive handler. 1315*4882a593Smuzhiyun- buf: preallocated output buffer. 1316*4882a593Smuzhiyun- bufsize: output buffer size (in bytes). 1317*4882a593Smuzhiyun- 1318*4882a593Smuzhiyun- Note: 1319*4882a593Smuzhiyun- - ensure supplied output buffer is large enough. 1320*4882a593Smuzhiyun- - zip_entry_size function (returns uncompressed size for the current entry) 1321*4882a593Smuzhiyun- can be handy to estimate how big buffer is needed. 1322*4882a593Smuzhiyun- - for large entries, please take a look at zip_entry_extract function. 1323*4882a593Smuzhiyun- 1324*4882a593Smuzhiyun- Returns: 1325*4882a593Smuzhiyun- The return code - the number of bytes actually read on success. 1326*4882a593Smuzhiyun- Otherwise a -1 on error (e.g. bufsize is not large enough). 1327*4882a593Smuzhiyun-*/ 1328*4882a593Smuzhiyun-extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize); 1329*4882a593Smuzhiyun- 1330*4882a593Smuzhiyun-/* 1331*4882a593Smuzhiyun- Extracts the current zip entry into output file. 1332*4882a593Smuzhiyun- 1333*4882a593Smuzhiyun- Args: 1334*4882a593Smuzhiyun- zip: zip archive handler. 1335*4882a593Smuzhiyun- filename: output file. 1336*4882a593Smuzhiyun- 1337*4882a593Smuzhiyun- Returns: 1338*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1339*4882a593Smuzhiyun-*/ 1340*4882a593Smuzhiyun+/** 1341*4882a593Smuzhiyun+ * Extracts the current zip entry into a memory buffer using no memory 1342*4882a593Smuzhiyun+ * allocation. 1343*4882a593Smuzhiyun+ * 1344*4882a593Smuzhiyun+ * @param zip zip archive handler. 1345*4882a593Smuzhiyun+ * @param buf preallocated output buffer. 1346*4882a593Smuzhiyun+ * @param bufsize output buffer size (in bytes). 1347*4882a593Smuzhiyun+ * 1348*4882a593Smuzhiyun+ * @note ensure supplied output buffer is large enough. 1349*4882a593Smuzhiyun+ * zip_entry_size function (returns uncompressed size for the current 1350*4882a593Smuzhiyun+ * entry) can be handy to estimate how big buffer is needed. for large 1351*4882a593Smuzhiyun+ * entries, please take a look at zip_entry_extract function. 1352*4882a593Smuzhiyun+ * 1353*4882a593Smuzhiyun+ * @return the return code - the number of bytes actually read on success. 1354*4882a593Smuzhiyun+ * Otherwise a -1 on error (e.g. bufsize is not large enough). 1355*4882a593Smuzhiyun+ */ 1356*4882a593Smuzhiyun+extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, 1357*4882a593Smuzhiyun+ size_t bufsize); 1358*4882a593Smuzhiyun+ 1359*4882a593Smuzhiyun+/** 1360*4882a593Smuzhiyun+ * Extracts the current zip entry into output file. 1361*4882a593Smuzhiyun+ * 1362*4882a593Smuzhiyun+ * @param zip zip archive handler. 1363*4882a593Smuzhiyun+ * @param filename output file. 1364*4882a593Smuzhiyun+ * 1365*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1366*4882a593Smuzhiyun+ */ 1367*4882a593Smuzhiyun extern int zip_entry_fread(struct zip_t *zip, const char *filename); 1368*4882a593Smuzhiyun 1369*4882a593Smuzhiyun-/* 1370*4882a593Smuzhiyun- Extracts the current zip entry using a callback function (on_extract). 1371*4882a593Smuzhiyun- 1372*4882a593Smuzhiyun- Args: 1373*4882a593Smuzhiyun- zip: zip archive handler. 1374*4882a593Smuzhiyun- on_extract: callback function. 1375*4882a593Smuzhiyun- arg: opaque pointer (optional argument, 1376*4882a593Smuzhiyun- which you can pass to the on_extract callback) 1377*4882a593Smuzhiyun- 1378*4882a593Smuzhiyun- Returns: 1379*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1380*4882a593Smuzhiyun+/** 1381*4882a593Smuzhiyun+ * Extracts the current zip entry using a callback function (on_extract). 1382*4882a593Smuzhiyun+ * 1383*4882a593Smuzhiyun+ * @param zip zip archive handler. 1384*4882a593Smuzhiyun+ * @param on_extract callback function. 1385*4882a593Smuzhiyun+ * @param arg opaque pointer (optional argument, which you can pass to the 1386*4882a593Smuzhiyun+ * on_extract callback) 1387*4882a593Smuzhiyun+ * 1388*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1389*4882a593Smuzhiyun */ 1390*4882a593Smuzhiyun extern int 1391*4882a593Smuzhiyun zip_entry_extract(struct zip_t *zip, 1392*4882a593Smuzhiyun@@ -262,53 +261,49 @@ zip_entry_extract(struct zip_t *zip, 1393*4882a593Smuzhiyun const void *data, size_t size), 1394*4882a593Smuzhiyun void *arg); 1395*4882a593Smuzhiyun 1396*4882a593Smuzhiyun-/* 1397*4882a593Smuzhiyun- Returns the number of all entries (files and directories) in the zip archive. 1398*4882a593Smuzhiyun- 1399*4882a593Smuzhiyun- Args: 1400*4882a593Smuzhiyun- zip: zip archive handler. 1401*4882a593Smuzhiyun- 1402*4882a593Smuzhiyun- Returns: 1403*4882a593Smuzhiyun- The return code - the number of entries on success, 1404*4882a593Smuzhiyun- negative number (< 0) on error. 1405*4882a593Smuzhiyun-*/ 1406*4882a593Smuzhiyun+/** 1407*4882a593Smuzhiyun+ * Returns the number of all entries (files and directories) in the zip archive. 1408*4882a593Smuzhiyun+ * 1409*4882a593Smuzhiyun+ * @param zip zip archive handler. 1410*4882a593Smuzhiyun+ * 1411*4882a593Smuzhiyun+ * @return the return code - the number of entries on success, negative number 1412*4882a593Smuzhiyun+ * (< 0) on error. 1413*4882a593Smuzhiyun+ */ 1414*4882a593Smuzhiyun extern int zip_total_entries(struct zip_t *zip); 1415*4882a593Smuzhiyun 1416*4882a593Smuzhiyun-/* 1417*4882a593Smuzhiyun- Creates a new archive and puts files into a single zip archive. 1418*4882a593Smuzhiyun- 1419*4882a593Smuzhiyun- Args: 1420*4882a593Smuzhiyun- zipname: zip archive file. 1421*4882a593Smuzhiyun- filenames: input files. 1422*4882a593Smuzhiyun- len: number of input files. 1423*4882a593Smuzhiyun- 1424*4882a593Smuzhiyun- Returns: 1425*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1426*4882a593Smuzhiyun-*/ 1427*4882a593Smuzhiyun+/** 1428*4882a593Smuzhiyun+ * Creates a new archive and puts files into a single zip archive. 1429*4882a593Smuzhiyun+ * 1430*4882a593Smuzhiyun+ * @param zipname zip archive file. 1431*4882a593Smuzhiyun+ * @param filenames input files. 1432*4882a593Smuzhiyun+ * @param len: number of input files. 1433*4882a593Smuzhiyun+ * 1434*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1435*4882a593Smuzhiyun+ */ 1436*4882a593Smuzhiyun extern int zip_create(const char *zipname, const char *filenames[], size_t len); 1437*4882a593Smuzhiyun 1438*4882a593Smuzhiyun-/* 1439*4882a593Smuzhiyun- Extracts a zip archive file into directory. 1440*4882a593Smuzhiyun- 1441*4882a593Smuzhiyun- If on_extract_entry is not NULL, the callback will be called after 1442*4882a593Smuzhiyun- successfully extracted each zip entry. 1443*4882a593Smuzhiyun- Returning a negative value from the callback will cause abort and return an 1444*4882a593Smuzhiyun- error. The last argument (void *arg) is optional, which you can use to pass 1445*4882a593Smuzhiyun- data to the on_extract_entry callback. 1446*4882a593Smuzhiyun- 1447*4882a593Smuzhiyun- Args: 1448*4882a593Smuzhiyun- zipname: zip archive file. 1449*4882a593Smuzhiyun- dir: output directory. 1450*4882a593Smuzhiyun- on_extract_entry: on extract callback. 1451*4882a593Smuzhiyun- arg: opaque pointer. 1452*4882a593Smuzhiyun- 1453*4882a593Smuzhiyun- Returns: 1454*4882a593Smuzhiyun- The return code - 0 on success, negative number (< 0) on error. 1455*4882a593Smuzhiyun-*/ 1456*4882a593Smuzhiyun+/** 1457*4882a593Smuzhiyun+ * Extracts a zip archive file into directory. 1458*4882a593Smuzhiyun+ * 1459*4882a593Smuzhiyun+ * If on_extract_entry is not NULL, the callback will be called after 1460*4882a593Smuzhiyun+ * successfully extracted each zip entry. 1461*4882a593Smuzhiyun+ * Returning a negative value from the callback will cause abort and return an 1462*4882a593Smuzhiyun+ * error. The last argument (void *arg) is optional, which you can use to pass 1463*4882a593Smuzhiyun+ * data to the on_extract_entry callback. 1464*4882a593Smuzhiyun+ * 1465*4882a593Smuzhiyun+ * @param zipname zip archive file. 1466*4882a593Smuzhiyun+ * @param dir output directory. 1467*4882a593Smuzhiyun+ * @param on_extract_entry on extract callback. 1468*4882a593Smuzhiyun+ * @param arg opaque pointer. 1469*4882a593Smuzhiyun+ * 1470*4882a593Smuzhiyun+ * @return the return code - 0 on success, negative number (< 0) on error. 1471*4882a593Smuzhiyun+ */ 1472*4882a593Smuzhiyun extern int zip_extract(const char *zipname, const char *dir, 1473*4882a593Smuzhiyun int (*on_extract_entry)(const char *filename, void *arg), 1474*4882a593Smuzhiyun void *arg); 1475*4882a593Smuzhiyun 1476*4882a593Smuzhiyun+/** @} */ 1477*4882a593Smuzhiyun+ 1478*4882a593Smuzhiyun #ifdef __cplusplus 1479*4882a593Smuzhiyun } 1480*4882a593Smuzhiyun #endif 1481*4882a593Smuzhiyundiff --git a/contrib/zip/test/CMakeLists.txt b/contrib/zip/test/CMakeLists.txt 1482*4882a593Smuzhiyunindex 9b2a8db106..cc060b00fe 100644 1483*4882a593Smuzhiyun--- a/contrib/zip/test/CMakeLists.txt 1484*4882a593Smuzhiyun+++ b/contrib/zip/test/CMakeLists.txt 1485*4882a593Smuzhiyun@@ -1,19 +1,16 @@ 1486*4882a593Smuzhiyun cmake_minimum_required(VERSION 2.8) 1487*4882a593Smuzhiyun 1488*4882a593Smuzhiyun-if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") 1489*4882a593Smuzhiyun- if(ENABLE_COVERAGE) 1490*4882a593Smuzhiyun- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g ") 1491*4882a593Smuzhiyun- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") 1492*4882a593Smuzhiyun- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs") 1493*4882a593Smuzhiyun- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage") 1494*4882a593Smuzhiyun- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") 1495*4882a593Smuzhiyun- endif() 1496*4882a593Smuzhiyun-endif () 1497*4882a593Smuzhiyun- 1498*4882a593Smuzhiyun # test 1499*4882a593Smuzhiyun-include_directories(../src) 1500*4882a593Smuzhiyun-add_executable(test.exe test.c ../src/zip.c) 1501*4882a593Smuzhiyun-add_executable(test_miniz.exe test_miniz.c) 1502*4882a593Smuzhiyun+set(test_out test.out) 1503*4882a593Smuzhiyun+set(test_miniz_out test_miniz.out) 1504*4882a593Smuzhiyun+ 1505*4882a593Smuzhiyun+add_executable(${test_out} test.c) 1506*4882a593Smuzhiyun+target_link_libraries(${test_out} zip) 1507*4882a593Smuzhiyun+add_executable(${test_miniz_out} test_miniz.c) 1508*4882a593Smuzhiyun+target_link_libraries(${test_miniz_out} zip) 1509*4882a593Smuzhiyun+ 1510*4882a593Smuzhiyun+add_test(NAME ${test_out} COMMAND ${test_out}) 1511*4882a593Smuzhiyun+add_test(NAME ${test_miniz_out} COMMAND ${test_miniz_out}) 1512*4882a593Smuzhiyun 1513*4882a593Smuzhiyun-add_test(NAME test COMMAND test.exe) 1514*4882a593Smuzhiyun-add_test(NAME test_miniz COMMAND test_miniz.exe) 1515*4882a593Smuzhiyun+set(test_out ${test_out} PARENT_SCOPE) 1516*4882a593Smuzhiyun+set(test_miniz_out ${test_miniz_out} PARENT_SCOPE) 1517*4882a593Smuzhiyundiff --git a/contrib/zip/test/test.c b/contrib/zip/test/test.c 1518*4882a593Smuzhiyunindex 454430533a..a9b2ddab1e 100644 1519*4882a593Smuzhiyun--- a/contrib/zip/test/test.c 1520*4882a593Smuzhiyun+++ b/contrib/zip/test/test.c 1521*4882a593Smuzhiyun@@ -29,6 +29,8 @@ 1522*4882a593Smuzhiyun #define XFILE "7.txt\0" 1523*4882a593Smuzhiyun #define XMODE 0100777 1524*4882a593Smuzhiyun 1525*4882a593Smuzhiyun+#define UNIXMODE 0100644 1526*4882a593Smuzhiyun+ 1527*4882a593Smuzhiyun #define UNUSED(x) (void)x 1528*4882a593Smuzhiyun 1529*4882a593Smuzhiyun static int total_entries = 0; 1530*4882a593Smuzhiyun@@ -102,7 +104,8 @@ static void test_read(void) { 1531*4882a593Smuzhiyun assert(0 == zip_entry_close(zip)); 1532*4882a593Smuzhiyun free(buf); 1533*4882a593Smuzhiyun buf = NULL; 1534*4882a593Smuzhiyun- 1535*4882a593Smuzhiyun+ bufsize = 0; 1536*4882a593Smuzhiyun+ 1537*4882a593Smuzhiyun assert(0 == zip_entry_open(zip, "test/test-2.txt")); 1538*4882a593Smuzhiyun assert(strlen(TESTDATA2) == zip_entry_size(zip)); 1539*4882a593Smuzhiyun assert(CRC32DATA2 == zip_entry_crc32(zip)); 1540*4882a593Smuzhiyun@@ -131,7 +134,8 @@ static void test_read(void) { 1541*4882a593Smuzhiyun assert(0 == zip_entry_close(zip)); 1542*4882a593Smuzhiyun free(buf); 1543*4882a593Smuzhiyun buf = NULL; 1544*4882a593Smuzhiyun- 1545*4882a593Smuzhiyun+ bufsize = 0; 1546*4882a593Smuzhiyun+ 1547*4882a593Smuzhiyun buftmp = strlen(TESTDATA1); 1548*4882a593Smuzhiyun buf = calloc(buftmp, sizeof(char)); 1549*4882a593Smuzhiyun assert(0 == zip_entry_open(zip, "test/test-1.txt")); 1550*4882a593Smuzhiyun@@ -433,6 +437,35 @@ static void test_mtime(void) { 1551*4882a593Smuzhiyun remove(ZIPNAME); 1552*4882a593Smuzhiyun } 1553*4882a593Smuzhiyun 1554*4882a593Smuzhiyun+static void test_unix_permissions(void) { 1555*4882a593Smuzhiyun+#if defined(_WIN64) || defined(_WIN32) || defined(__WIN32__) 1556*4882a593Smuzhiyun+#else 1557*4882a593Smuzhiyun+ // UNIX or APPLE 1558*4882a593Smuzhiyun+ struct MZ_FILE_STAT_STRUCT file_stats; 1559*4882a593Smuzhiyun+ 1560*4882a593Smuzhiyun+ remove(ZIPNAME); 1561*4882a593Smuzhiyun+ 1562*4882a593Smuzhiyun+ struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); 1563*4882a593Smuzhiyun+ assert(zip != NULL); 1564*4882a593Smuzhiyun+ 1565*4882a593Smuzhiyun+ assert(0 == zip_entry_open(zip, RFILE)); 1566*4882a593Smuzhiyun+ assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1))); 1567*4882a593Smuzhiyun+ assert(0 == zip_entry_close(zip)); 1568*4882a593Smuzhiyun+ 1569*4882a593Smuzhiyun+ zip_close(zip); 1570*4882a593Smuzhiyun+ 1571*4882a593Smuzhiyun+ remove(RFILE); 1572*4882a593Smuzhiyun+ 1573*4882a593Smuzhiyun+ assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL)); 1574*4882a593Smuzhiyun+ 1575*4882a593Smuzhiyun+ assert(0 == MZ_FILE_STAT(RFILE, &file_stats)); 1576*4882a593Smuzhiyun+ assert(UNIXMODE == file_stats.st_mode); 1577*4882a593Smuzhiyun+ 1578*4882a593Smuzhiyun+ remove(RFILE); 1579*4882a593Smuzhiyun+ remove(ZIPNAME); 1580*4882a593Smuzhiyun+#endif 1581*4882a593Smuzhiyun+} 1582*4882a593Smuzhiyun+ 1583*4882a593Smuzhiyun int main(int argc, char *argv[]) { 1584*4882a593Smuzhiyun UNUSED(argc); 1585*4882a593Smuzhiyun UNUSED(argv); 1586*4882a593Smuzhiyun@@ -453,6 +486,7 @@ int main(int argc, char *argv[]) { 1587*4882a593Smuzhiyun test_write_permissions(); 1588*4882a593Smuzhiyun test_exe_permissions(); 1589*4882a593Smuzhiyun test_mtime(); 1590*4882a593Smuzhiyun+ test_unix_permissions(); 1591*4882a593Smuzhiyun 1592*4882a593Smuzhiyun remove(ZIPNAME); 1593*4882a593Smuzhiyun return 0; 1594*4882a593Smuzhiyundiff --git a/contrib/zip/test/test_miniz.c b/contrib/zip/test/test_miniz.c 1595*4882a593Smuzhiyunindex ebc0564dc3..babcaecdb6 100644 1596*4882a593Smuzhiyun--- a/contrib/zip/test/test_miniz.c 1597*4882a593Smuzhiyun+++ b/contrib/zip/test/test_miniz.c 1598*4882a593Smuzhiyun@@ -23,16 +23,39 @@ int main(int argc, char *argv[]) { 1599*4882a593Smuzhiyun uint step = 0; 1600*4882a593Smuzhiyun int cmp_status; 1601*4882a593Smuzhiyun uLong src_len = (uLong)strlen(s_pStr); 1602*4882a593Smuzhiyun- uLong cmp_len = compressBound(src_len); 1603*4882a593Smuzhiyun uLong uncomp_len = src_len; 1604*4882a593Smuzhiyun+ uLong cmp_len; 1605*4882a593Smuzhiyun uint8 *pCmp, *pUncomp; 1606*4882a593Smuzhiyun+ size_t sz; 1607*4882a593Smuzhiyun uint total_succeeded = 0; 1608*4882a593Smuzhiyun (void)argc, (void)argv; 1609*4882a593Smuzhiyun 1610*4882a593Smuzhiyun printf("miniz.c version: %s\n", MZ_VERSION); 1611*4882a593Smuzhiyun 1612*4882a593Smuzhiyun do { 1613*4882a593Smuzhiyun+ pCmp = (uint8 *)tdefl_compress_mem_to_heap(s_pStr, src_len, &cmp_len, 0); 1614*4882a593Smuzhiyun+ if (!pCmp) { 1615*4882a593Smuzhiyun+ printf("tdefl_compress_mem_to_heap failed\n"); 1616*4882a593Smuzhiyun+ return EXIT_FAILURE; 1617*4882a593Smuzhiyun+ } 1618*4882a593Smuzhiyun+ if (src_len <= cmp_len) { 1619*4882a593Smuzhiyun+ printf("tdefl_compress_mem_to_heap failed: from %u to %u bytes\n", 1620*4882a593Smuzhiyun+ (mz_uint32)uncomp_len, (mz_uint32)cmp_len); 1621*4882a593Smuzhiyun+ free(pCmp); 1622*4882a593Smuzhiyun+ return EXIT_FAILURE; 1623*4882a593Smuzhiyun+ } 1624*4882a593Smuzhiyun+ 1625*4882a593Smuzhiyun+ sz = tdefl_compress_mem_to_mem(pCmp, cmp_len, s_pStr, src_len, 0); 1626*4882a593Smuzhiyun+ if (sz != cmp_len) { 1627*4882a593Smuzhiyun+ printf("tdefl_compress_mem_to_mem failed: expected %u, got %u\n", 1628*4882a593Smuzhiyun+ (mz_uint32)cmp_len, (mz_uint32)sz); 1629*4882a593Smuzhiyun+ free(pCmp); 1630*4882a593Smuzhiyun+ return EXIT_FAILURE; 1631*4882a593Smuzhiyun+ } 1632*4882a593Smuzhiyun+ 1633*4882a593Smuzhiyun // Allocate buffers to hold compressed and uncompressed data. 1634*4882a593Smuzhiyun+ free(pCmp); 1635*4882a593Smuzhiyun+ cmp_len = compressBound(src_len); 1636*4882a593Smuzhiyun pCmp = (mz_uint8 *)malloc((size_t)cmp_len); 1637*4882a593Smuzhiyun pUncomp = (mz_uint8 *)malloc((size_t)src_len); 1638*4882a593Smuzhiyun if ((!pCmp) || (!pUncomp)) { 1639