diff --git a/thirdparty/zip/miniz.h b/thirdparty/zip/miniz.h index 48694d230b9178..d01c435d19fa31 100644 --- a/thirdparty/zip/miniz.h +++ b/thirdparty/zip/miniz.h @@ -1,5 +1,7 @@ +#ifndef MINIZ_EXPORT #define MINIZ_EXPORT -/* miniz.c 2.2.0 - public domain deflate/inflate, zlib-subset, ZIP +#endif +/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing See "unlicense" statement at the end of this file. Rich Geldreich , last updated Oct. 13, 2013 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: @@ -140,7 +142,7 @@ /* Defines to completely disable specific portions of miniz.c: If all macros here are defined the only functionality remaining will be - CRC-32, adler-32, tinfl, and tdefl. */ + CRC-32 and adler-32. */ /* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on * stdio for file I/O. */ @@ -154,6 +156,12 @@ */ /*#define MINIZ_NO_TIME */ +/* Define MINIZ_NO_DEFLATE_APIS to disable all compression API's. */ +/*#define MINIZ_NO_DEFLATE_APIS */ + +/* Define MINIZ_NO_INFLATE_APIS to disable all decompression API's. */ +/*#define MINIZ_NO_INFLATE_APIS */ + /* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */ /*#define MINIZ_NO_ARCHIVE_APIS */ @@ -177,6 +185,14 @@ */ /*#define MINIZ_NO_MALLOC */ +#ifdef MINIZ_NO_INFLATE_APIS +#define MINIZ_NO_ARCHIVE_APIS +#endif + +#ifdef MINIZ_NO_DEFLATE_APIS +#define MINIZ_NO_ARCHIVE_WRITING_APIS +#endif + #if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) /* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc * on Linux */ @@ -198,19 +214,41 @@ #define MINIZ_X86_OR_X64_CPU 0 #endif -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +/* Set MINIZ_LITTLE_ENDIAN only if not set */ +#if !defined(MINIZ_LITTLE_ENDIAN) +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) + +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */ #define MINIZ_LITTLE_ENDIAN 1 #else #define MINIZ_LITTLE_ENDIAN 0 #endif +#else + +#if MINIZ_X86_OR_X64_CPU +#define MINIZ_LITTLE_ENDIAN 1 +#else +#define MINIZ_LITTLE_ENDIAN 0 +#endif + +#endif +#endif + +/* Using unaligned loads and stores causes errors when using UBSan */ +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 +#endif +#endif + /* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */ #if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES) #if MINIZ_X86_OR_X64_CPU /* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient * integer loads and stores from unaligned addresses. */ -#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 #define MINIZ_UNALIGNED_USE_MEMCPY #else #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 @@ -287,9 +325,9 @@ enum { MZ_DEFAULT_COMPRESSION = -1 }; -#define MZ_VERSION "10.2.0" -#define MZ_VERNUM 0xA100 -#define MZ_VER_MAJOR 10 +#define MZ_VERSION "11.0.2" +#define MZ_VERNUM 0xB002 +#define MZ_VER_MAJOR 11 #define MZ_VER_MINOR 2 #define MZ_VER_REVISION 0 #define MZ_VER_SUBREVISION 0 @@ -355,6 +393,8 @@ typedef mz_stream *mz_streamp; /* Returns the version string of miniz.c. */ MINIZ_EXPORT const char *mz_version(void); +#ifndef MINIZ_NO_DEFLATE_APIS + /* mz_deflateInit() initializes a compressor with default options: */ /* Parameters: */ /* pStream must point to an initialized mz_stream struct. */ @@ -428,6 +468,10 @@ MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, * data that could be generated by calling mz_compress(). */ MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len); +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS + /* Initializes a decompressor. */ MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream); @@ -482,6 +526,7 @@ MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len); +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ /* Returns a string description of the specified error code, or NULL if the * error code is invalid. */ @@ -535,6 +580,8 @@ typedef void *const voidpc; #define free_func mz_free_func #define internal_state mz_internal_state #define z_stream mz_stream + +#ifndef MINIZ_NO_DEFLATE_APIS #define deflateInit mz_deflateInit #define deflateInit2 mz_deflateInit2 #define deflateReset mz_deflateReset @@ -544,6 +591,9 @@ typedef void *const voidpc; #define compress mz_compress #define compress2 mz_compress2 #define compressBound mz_compressBound +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS #define inflateInit mz_inflateInit #define inflateInit2 mz_inflateInit2 #define inflateReset mz_inflateReset @@ -551,6 +601,8 @@ typedef void *const voidpc; #define inflateEnd mz_inflateEnd #define uncompress mz_uncompress #define uncompress2 mz_uncompress2 +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + #define crc32 mz_crc32 #define adler32 mz_adler32 #define MAX_WBITS 15 @@ -608,7 +660,8 @@ typedef int mz_bool; #ifdef MINIZ_NO_TIME typedef struct mz_dummy_time_t_tag { - int m_dummy; + mz_uint32 m_dummy1; + mz_uint32 m_dummy2; } mz_dummy_time_t; #define MZ_TIME_T mz_dummy_time_t #else @@ -630,6 +683,8 @@ typedef struct mz_dummy_time_t_tag { #define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) +#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj)) +#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj)) #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) @@ -676,6 +731,8 @@ extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, #endif #pragma once +#ifndef MINIZ_NO_DEFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -921,10 +978,14 @@ MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp); #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ #pragma once /* ------------------- Low-level Decompression API Definitions */ +#ifndef MINIZ_NO_INFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -1085,12 +1146,6 @@ enum { TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS }; -typedef struct { - mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; - mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], - m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; -} tinfl_huff_table; - #if MINIZ_HAS_64BIT_REGISTERS #define TINFL_USE_64BIT_BITBUF 1 #else @@ -1111,7 +1166,13 @@ struct tinfl_decompressor_tag { m_table_sizes[TINFL_MAX_HUFF_TABLES]; tinfl_bit_buf_t m_bit_buf; size_t m_dist_from_out_buf_start; - tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE]; + mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; + mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2]; + mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2]; + mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1]; + mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2]; mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; }; @@ -1120,6 +1181,8 @@ struct tinfl_decompressor_tag { } #endif +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + #pragma once /* ------------------- ZIP archive reading/writing */ @@ -1133,7 +1196,7 @@ extern "C" { enum { /* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */ - MZ_ZIP_MAX_IO_BUF_SIZE = 8 * 1024, + MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512 }; @@ -1152,10 +1215,6 @@ typedef struct { mz_uint16 m_bit_flag; mz_uint16 m_method; -#ifndef MINIZ_NO_TIME - MZ_TIME_T m_time; -#endif - /* CRC-32 of uncompressed data. */ mz_uint32 m_crc32; @@ -1196,6 +1255,11 @@ typedef struct { /* Guaranteed to be zero terminated, may be truncated to fit. */ char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; +#ifdef MINIZ_NO_TIME + MZ_TIME_T m_padding; +#else + MZ_TIME_T m_time; +#endif } mz_zip_archive_file_stat; typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, @@ -1316,9 +1380,7 @@ typedef struct { mz_uint flags; int status; -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - mz_uint file_crc32; -#endif + mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs; mz_zip_archive_file_stat file_stat; @@ -1329,6 +1391,12 @@ typedef struct { tinfl_decompressor inflator; +#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + mz_uint padding; +#else + mz_uint file_crc32; +#endif + } mz_zip_reader_extract_iter_state; /* -------- ZIP reading */ @@ -1541,9 +1609,9 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile( /* TODO */ typedef void *mz_zip_streaming_extract_state_ptr; mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); + mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs); size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); #endif @@ -1565,9 +1633,11 @@ MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr); +#ifndef MINIZ_NO_STDIO MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr); +#endif /* Universal end function - calls either mz_zip_reader_end() or * mz_zip_writer_end(). */ @@ -1705,7 +1775,7 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader( * valid. */ MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); -/* Finalizes a heap archive, returning a poiner to the heap block and its size. +/* Finalizes a heap archive, returning a pointer to the heap block and its size. */ /* The heap block will be allocated using the mz_zip_archive's alloc/realloc * callbacks. */ @@ -1741,6 +1811,7 @@ MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2( size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr); +#ifndef MINIZ_NO_STDIO /* Reads a single file from an archive into a heap block. */ /* If pComment is not NULL, only the file with the specified comment will be * extracted. */ @@ -1752,6 +1823,7 @@ mz_zip_extract_archive_file_to_heap(const char *pZip_filename, MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2( const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr); +#endif #endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ @@ -1939,6 +2011,8 @@ const char *mz_version(void) { return MZ_VERSION; } #ifndef MINIZ_NO_ZLIB_APIS +#ifndef MINIZ_NO_DEFLATE_APIS + int mz_deflateInit(mz_streamp pStream, int level) { return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); @@ -2070,17 +2144,21 @@ mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) { } int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len, int level) { + const unsigned char *pSource, mz_ulong pSource_len, + int level) { int status; mz_stream stream; memset(&stream, 0, sizeof(stream)); +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__) /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) +#else + if ((mz_uint64)(pSource_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; +#endif stream.next_in = pSource; - stream.avail_in = (mz_uint32)source_len; + stream.avail_in = (mz_uint32)pSource_len; stream.next_out = pDest; stream.avail_out = (mz_uint32)*pDest_len; @@ -2108,6 +2186,10 @@ mz_ulong mz_compressBound(mz_ulong source_len) { return mz_deflateBound(NULL, source_len); } +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS + typedef struct { tinfl_decompressor m_decomp; mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; @@ -2320,9 +2402,12 @@ int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, int status; memset(&stream, 0, sizeof(stream)); +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__) /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU) +#else + if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; +#endif stream.next_in = pSource; stream.avail_in = (mz_uint32)*pSource_len; @@ -2350,6 +2435,8 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, return mz_uncompress2(pDest, pDest_len, pSource, &source_len); } +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + const char *mz_error(int err) { static struct { int m_err; @@ -2429,6 +2516,8 @@ const char *mz_error(int err) { * **************************************************************************/ +#ifndef MINIZ_NO_DEFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -2550,7 +2639,7 @@ static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms1) { mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1; - MZ_CLEAR_OBJ(hist); + MZ_CLEAR_ARR(hist); for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; @@ -2654,7 +2743,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int static_table) { int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; - MZ_CLEAR_OBJ(num_codes); + MZ_CLEAR_ARR(num_codes); if (static_table) { for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; @@ -2678,8 +2767,8 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); - MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); - MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]); + MZ_CLEAR_ARR(d->m_huff_codes[table_num]); for (i = 1, j = num_used_syms; i <= code_size_limit; i++) for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); @@ -2758,7 +2847,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, } \ } -static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { +static const mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; static void tdefl_start_dynamic_block(tdefl_compressor *d) { @@ -2895,8 +2984,8 @@ static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { if (flags & 1) { mz_uint s0, s1, n0, n1, sym, num_extra_bits; - mz_uint match_len = pLZ_codes[0], - match_dist = *(const mz_uint16 *)(pLZ_codes + 1); + mz_uint match_len = pLZ_codes[0]; + mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); @@ -2944,7 +3033,7 @@ static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { if (pOutput_buf >= d->m_pOutput_buf_end) return MZ_FALSE; - *(mz_uint64 *)pOutput_buf = bit_buffer; + memcpy(pOutput_buf, &bit_buffer, sizeof(mz_uint64)); pOutput_buf += (bits_in >> 3); bit_buffer >>= (bits_in & ~7); bits_in &= 7; @@ -3021,6 +3110,9 @@ static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) { return tdefl_compress_lz_codes(d); } +static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32, + 128, 256, 512, 768, 1500}; + static int tdefl_flush_block(tdefl_compressor *d, int flush) { mz_uint saved_bit_buf, saved_bits_in; mz_uint8 *pSaved_output_buf; @@ -3045,8 +3137,29 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush) { d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) { - TDEFL_PUT_BITS(0x78, 8); - TDEFL_PUT_BITS(0x01, 8); + const mz_uint8 cmf = 0x78; + mz_uint8 flg, flevel = 3; + mz_uint header, i, mz_un = sizeof(s_tdefl_num_probes) / sizeof(mz_uint); + + /* Determine compression level by reversing the process in + * tdefl_create_comp_flags_from_zip_params() */ + for (i = 0; i < mz_un; i++) + if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF)) + break; + + if (i < 2) + flevel = 0; + else if (i < 6) + flevel = 1; + else if (i == 6) + flevel = 2; + + header = cmf << 8 | (flevel << 6); + header += 31 - (header % 31); + flg = header & 0xFF; + + TDEFL_PUT_BITS(cmf, 8); + TDEFL_PUT_BITS(flg, 8); } TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); @@ -3529,7 +3642,7 @@ static mz_bool tdefl_compress_normal(tdefl_compressor *d) { d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); - const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + const mz_uint8 *pSrc_end = pSrc ? pSrc + num_bytes_to_process : NULL; src_buf_left -= num_bytes_to_process; d->m_lookahead_size += num_bytes_to_process; while (pSrc != pSrc_end) { @@ -3739,8 +3852,8 @@ tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, return d->m_prev_return_status; d->m_finished = (flush == TDEFL_FINISH); if (flush == TDEFL_FULL_FLUSH) { - MZ_CLEAR_OBJ(d->m_hash); - MZ_CLEAR_OBJ(d->m_next); + MZ_CLEAR_ARR(d->m_hash); + MZ_CLEAR_ARR(d->m_next); d->m_dict_size = 0; } } @@ -3764,7 +3877,7 @@ tdefl_status tdefl_init(tdefl_compressor *d, d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) - MZ_CLEAR_OBJ(d->m_hash); + MZ_CLEAR_ARR(d->m_hash); d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = @@ -3787,7 +3900,7 @@ tdefl_status tdefl_init(tdefl_compressor *d, d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) - MZ_CLEAR_OBJ(d->m_dict); + MZ_CLEAR_ARR(d->m_dict); memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); memset(&d->m_huff_count[1][0], 0, @@ -3880,9 +3993,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, return out_buf.m_size; } -static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32, - 128, 256, 512, 768, 1500}; - /* level may actually range from [0,10] (10 is a "hidden" max level, where we * want a bit more compression and it's fine if throughput to fall off a cliff * on some files). */ @@ -4016,7 +4126,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, */ /* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */ /* structure size and allocation mechanism. */ -tdefl_compressor *tdefl_compressor_alloc() { +tdefl_compressor *tdefl_compressor_alloc(void) { return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); } @@ -4030,6 +4140,8 @@ void tdefl_compressor_free(tdefl_compressor *pComp) { MZ_FREE(pComp); } #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ /************************************************************************** * * Copyright 2013-2014 RAD Game Tools and Valve Software @@ -4056,6 +4168,8 @@ void tdefl_compressor_free(tdefl_compressor *pComp) { MZ_FREE(pComp); } * **************************************************************************/ +#ifndef MINIZ_NO_INFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -4134,9 +4248,9 @@ extern "C" { * If this fails, it reads another byte, and tries again until it succeeds or * until the */ /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ -#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ +#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \ do { \ - temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ if (temp >= 0) { \ code_len = temp >> 9; \ if ((code_len) && (num_bits >= code_len)) \ @@ -4144,7 +4258,7 @@ extern "C" { } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ code_len = TINFL_FAST_LOOKUP_BITS; \ do { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while ((temp < 0) && (num_bits >= (code_len + 1))); \ if (temp >= 0) \ break; \ @@ -4169,13 +4283,13 @@ extern "C" { * 1+zillion bytes */ /* following the deflate data and our non-conservative read-ahead path won't * kick in here on this code. This is much trickier. */ -#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ +#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \ do { \ int temp; \ mz_uint code_len, c; \ if (num_bits < 15) { \ if ((pIn_buf_end - pIn_buf_cur) < 2) { \ - TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \ } else { \ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \ (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \ @@ -4183,13 +4297,12 @@ extern "C" { num_bits += 16; \ } \ } \ - if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \ - 0) \ + if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ code_len = temp >> 9, temp &= 511; \ else { \ code_len = TINFL_FAST_LOOKUP_BITS; \ do { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ @@ -4198,27 +4311,39 @@ extern "C" { } \ MZ_MACRO_END +static void tinfl_clear_tree(tinfl_decompressor *r) { + if (r->m_type == 0) + MZ_CLEAR_ARR(r->m_tree_0); + else if (r->m_type == 1) + MZ_CLEAR_ARR(r->m_tree_1); + else + MZ_CLEAR_ARR(r->m_tree_2); +} + tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) { - static const int s_length_base[31] = { + static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const int s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, - 4, 4, 5, 5, 5, 5, 0, 0, 0}; - static const int s_dist_base[32] = { + static const mz_uint8 s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 0, 0, 0}; + static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; - static const int s_dist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + static const mz_uint8 s_dist_extra[32] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - static const int s_min_table_sizes[3] = {257, 1, 4}; + static const mz_uint16 s_min_table_sizes[3] = {257, 1, 4}; + + mz_int16 *pTrees[3]; + mz_uint8 *pCode_sizes[3]; tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; @@ -4226,7 +4351,9 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = - pOut_buf_next + *pOut_buf_size; + pOut_buf_next ? pOut_buf_next + + *pOut_buf_size + : NULL; size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 @@ -4242,6 +4369,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, return TINFL_STATUS_BAD_PARAM; } + pTrees[0] = r->m_tree_0; + pTrees[1] = r->m_tree_1; + pTrees[2] = r->m_tree_2; + pCode_sizes[0] = r->m_code_size_0; + pCode_sizes[1] = r->m_code_size_1; + pCode_sizes[2] = r->m_code_size_2; + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; @@ -4260,7 +4394,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < - (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4))))); if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } @@ -4312,11 +4446,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); } else { if (r->m_type == 1) { - mz_uint8 *p = r->m_tables[0].m_code_size; + mz_uint8 *p = r->m_code_size_0; mz_uint i; r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; - TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + TINFL_MEMSET(r->m_code_size_1, 5, 32); for (i = 0; i <= 143; ++i) *p++ = 8; for (; i <= 255; ++i) @@ -4330,25 +4464,29 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } - MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); + MZ_CLEAR_ARR(r->m_code_size_2); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); - r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; + r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s; } r->m_table_sizes[2] = 19; } for (; (int)r->m_type >= 0; r->m_type--) { int tree_next, tree_cur; - tinfl_huff_table *pTable; + mz_int16 *pLookUp; + mz_int16 *pTree; + mz_uint8 *pCode_size; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; - pTable = &r->m_tables[r->m_type]; - MZ_CLEAR_OBJ(total_syms); - MZ_CLEAR_OBJ(pTable->m_look_up); - MZ_CLEAR_OBJ(pTable->m_tree); + pLookUp = r->m_look_up[r->m_type]; + pTree = pTrees[r->m_type]; + pCode_size = pCode_sizes[r->m_type]; + MZ_CLEAR_ARR(total_syms); + TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0])); + tinfl_clear_tree(r); for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pTable->m_code_size[i]]++; + total_syms[pCode_size[i]]++; used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; for (i = 1; i <= 15; ++i) { @@ -4360,9 +4498,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, } for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { - mz_uint rev_code = 0, l, cur_code, - code_size = pTable->m_code_size[sym_index]; - + mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index]; if (!code_size) continue; cur_code = next_code[code_size]++; @@ -4371,15 +4507,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { - pTable->m_look_up[rev_code] = k; + pLookUp[rev_code] = k; rev_code += (1 << code_size); } continue; } if (0 == - (tree_cur = pTable->m_look_up[rev_code & - (TINFL_FAST_LOOKUP_SIZE - 1)])) { - pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = + (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { + pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; @@ -4387,22 +4522,21 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_tree[-tree_cur - 1]) { - pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; + if (!pTree[-tree_cur - 1]) { + pTree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else - tree_cur = pTable->m_tree[-tree_cur - 1]; + tree_cur = pTree[-tree_cur - 1]; } tree_cur -= ((rev_code >>= 1) & 1); - (void)rev_code; // unused - pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + pTree[-tree_cur - 1] = (mz_int16)sym_index; } if (r->m_type == 2) { for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) { mz_uint s; - TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); + TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; @@ -4420,10 +4554,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) { TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); } - TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, - r->m_table_sizes[0]); - TINFL_MEMCPY(r->m_tables[1].m_code_size, - r->m_len_codes + r->m_table_sizes[0], + TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]); + TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); } } @@ -4432,7 +4564,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, for (;;) { if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) { - TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0); if (counter >= 256) break; while (pOut_buf_cur >= pOut_buf_end) { @@ -4458,15 +4590,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, } #endif if ((sym2 = - r->m_tables[0] - .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= + r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { code_len = TINFL_FAST_LOOKUP_BITS; do { - sym2 = r->m_tables[0] - .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } counter = sym2; @@ -4484,15 +4614,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, } #endif if ((sym2 = - r->m_tables[0] - .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= + r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { code_len = TINFL_FAST_LOOKUP_BITS; do { - sym2 = r->m_tables[0] - .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } bit_buf >>= code_len; @@ -4519,7 +4647,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, counter += extra_bits; } - TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1); num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; if (num_extra) { @@ -4601,7 +4729,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, --pIn_buf_cur; num_bits -= 8; } - bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); + bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits); MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */ @@ -4636,8 +4764,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, } } r->m_num_bits = num_bits; - r->m_bit_buf = - bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); + r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits); r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; @@ -4743,6 +4870,7 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, size_t in_buf_ofs = 0, dict_ofs = 0; if (!pDict) return TINFL_STATUS_FAILED; + memset(pDict, 0, TINFL_LZ_DICT_SIZE); tinfl_init(&decomp); for (;;) { size_t in_buf_size = *pIn_buf_size - in_buf_ofs, @@ -4768,7 +4896,7 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, } #ifndef MINIZ_NO_MALLOC -tinfl_decompressor *tinfl_decompressor_alloc() { +tinfl_decompressor *tinfl_decompressor_alloc(void) { tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor)); if (pDecomp) @@ -4782,6 +4910,8 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp) { MZ_FREE(pDecomp); } #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ /************************************************************************** * * Copyright 2013-2014 RAD Game Tools and Valve Software @@ -4822,78 +4952,55 @@ extern "C" { #else #include -#if defined(_MSC_VER) +#if defined(_MSC_VER) || defined(__MINGW64__) + +#define WIN32_LEAN_AND_MEAN #include -#ifndef MINIZ_NO_TIME -#include -#endif -static wchar_t *str2wstr(const char *str) { - size_t len = strlen(str) + 1; - wchar_t *wstr = (wchar_t *)malloc(len * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, str, (int)(len * sizeof(char)), wstr, - (int)len); - return wstr; + +static WCHAR *mz_utf8z_to_widechar(const char *str) { + int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars); + return wStr; } static FILE *mz_fopen(const char *pFilename, const char *pMode) { + WCHAR *wFilename = mz_utf8z_to_widechar(pFilename); + WCHAR *wMode = mz_utf8z_to_widechar(pMode); FILE *pFile = NULL; - 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 + errno_t err = _wfopen_s(&pFile, wFilename, wMode); free(wFilename); free(wMode); - - return pFile; + return err ? NULL : pFile; } static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { + WCHAR *wPath = mz_utf8z_to_widechar(pPath); + WCHAR *wMode = mz_utf8z_to_widechar(pMode); FILE *pFile = NULL; - int res = 0; - - 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 - + errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream); free(wPath); free(wMode); - -#ifndef ZIP_ENABLE_SHARABLE_FILE_OPEN - if (res) { - return NULL; - } -#endif - - return pFile; + return err ? NULL : pFile; } -static int mz_stat(const char *pPath, struct _stat64 *buffer) { - wchar_t *wPath = str2wstr(pPath); +static int mz_stat64(const char *path, struct __stat64 *buffer) { + WCHAR *wPath = mz_utf8z_to_widechar(path); int res = _wstat64(wPath, buffer); - free(wPath); - return res; } static int mz_mkdir(const char *pDirname) { - wchar_t *wDirname = str2wstr(pDirname); + WCHAR *wDirname = mz_utf8z_to_widechar(pDirname); int res = _wmkdir(wDirname); - free(wDirname); - return res; } +#ifndef MINIZ_NO_TIME +#include +#endif #define MZ_FOPEN mz_fopen #define MZ_FCLOSE fclose #define MZ_FREAD fread @@ -4901,24 +5008,22 @@ static int mz_mkdir(const char *pDirname) { #define MZ_FTELL64 _ftelli64 #define MZ_FSEEK64 _fseeki64 #define MZ_FILE_STAT_STRUCT _stat64 -#define MZ_FILE_STAT mz_stat +#define MZ_FILE_STAT mz_stat64 #define MZ_FFLUSH fflush #define MZ_FREOPEN mz_freopen #define MZ_DELETE_FILE remove #define MZ_MKDIR(d) mz_mkdir(d) -#elif defined(__MINGW32__) || defined(__MINGW64__) -#include +#elif defined(__MINGW32__) || defined(__WATCOMC__) #ifndef MINIZ_NO_TIME #include #endif - #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek +#define MZ_FTELL64 _ftelli64 +#define MZ_FSEEK64 _fseeki64 #define MZ_FILE_STAT_STRUCT stat #define MZ_FILE_STAT stat #define MZ_FFLUSH fflush @@ -4926,29 +5031,10 @@ static int mz_mkdir(const char *pDirname) { #define MZ_DELETE_FILE remove #define MZ_MKDIR(d) _mkdir(d) -#elif defined(__FreeBSD__) -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello -#define MZ_FSEEK64 fseeko -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(p, m, s) freopen(p, m, s) -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) mkdir(d, 0755) - #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME #include #endif - #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread @@ -4970,7 +5056,6 @@ static int mz_mkdir(const char *pDirname) { #ifndef MINIZ_NO_TIME #include #endif - #define MZ_FOPEN(f, m) fopen64(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread @@ -4984,11 +5069,10 @@ static int mz_mkdir(const char *pDirname) { #define MZ_DELETE_FILE remove #define MZ_MKDIR(d) mkdir(d, 0755) -#elif defined(__APPLE__) +#elif defined(__APPLE__) || defined(__FreeBSD__) #ifndef MINIZ_NO_TIME #include #endif - #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread @@ -5008,7 +5092,6 @@ static int mz_mkdir(const char *pDirname) { #ifndef MINIZ_NO_TIME #include #endif - #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread @@ -5026,7 +5109,6 @@ static int mz_mkdir(const char *pDirname) { #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #define MZ_MKDIR(d) mkdir(d, 0755) - #endif /* #ifdef _MSC_VER */ #endif /* #ifdef MINIZ_NO_STDIO */ @@ -5142,7 +5224,7 @@ struct mz_zip_internal_state_tag { mz_zip_array m_sorted_central_dir_offsets; /* The flags passed in when the archive is initially opened. */ - uint32_t m_init_flags; + mz_uint32 m_init_flags; /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */ @@ -5648,7 +5730,8 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, ((num_this_disk != 1) || (cdir_disk_index != 1))) return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) + if (cdir_size < + (mz_uint64)pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) @@ -5817,7 +5900,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, void mz_zip_zero_struct(mz_zip_archive *pZip) { if (pZip) - MZ_CLEAR_OBJ(*pZip); + MZ_CLEAR_PTR(pZip); } static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, @@ -6300,10 +6383,7 @@ static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, pStat->m_local_header_ofs = MZ_READ_LE64(pField_data); pField_data += sizeof(mz_uint64); - (void)pField_data; // unused - field_data_remaining -= sizeof(mz_uint64); - (void)field_data_remaining; // unused } break; @@ -6361,7 +6441,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const mz_zip_array *pCentral_dir = &pState->m_central_dir; mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT( &pState->m_sorted_central_dir_offsets, mz_uint32, 0); - const uint32_t size = pZip->m_total_files; + const mz_uint32 size = pZip->m_total_files; const mz_uint filename_len = (mz_uint)strlen(pFilename); if (pIndex) @@ -6376,7 +6456,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, while (l <= h) { mz_int64 m = l + ((h - l) >> 1); - uint32_t file_index = pIndices[(uint32_t)m]; + mz_uint32 file_index = pIndices[(mz_uint32)m]; int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); @@ -6651,16 +6731,16 @@ mz_bool mz_zip_reader_extract_file_to_mem_no_alloc( mz_uint32 file_index; if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) return MZ_FALSE; - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, - flags, pUser_read_buf, - user_read_buf_size); + return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, + buf_size, flags, pUser_read_buf, + user_read_buf_size, NULL); } mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) { - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, - flags, NULL, 0); + return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, + buf_size, flags, NULL, 0, NULL); } mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, @@ -6745,7 +6825,7 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, return MZ_FALSE; /* A directory or zero length file */ - if (file_stat.m_is_directory || (!file_stat.m_comp_size)) + if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) return MZ_TRUE; /* Encryption and patch files are not supported. */ @@ -7187,7 +7267,7 @@ size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state *pState, MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain); /* Copy data to caller's buffer */ - memcpy((uint8_t *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy); + memcpy((mz_uint8 *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy); #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS /* Perform CRC */ @@ -7275,7 +7355,7 @@ mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; - if (file_stat.m_is_directory || (!file_stat.m_is_supported)) + if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); pFile = MZ_FOPEN(pDst_filename, "wb"); @@ -7319,7 +7399,7 @@ mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; - if (file_stat.m_is_directory || (!file_stat.m_is_supported)) + if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); return mz_zip_reader_extract_to_callback( @@ -7384,7 +7464,7 @@ mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, return MZ_FALSE; /* A directory or zero length file */ - if (file_stat.m_is_directory || (!file_stat.m_uncomp_size)) + if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size)) return MZ_TRUE; /* Encryption and patch files are not supported. */ @@ -7586,7 +7666,7 @@ mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) { mz_zip_internal_state *pState; - uint32_t i; + mz_uint32 i; if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead)) @@ -7602,9 +7682,6 @@ mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) { if (pZip->m_archive_size > MZ_UINT32_MAX) return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); } else { - if (pZip->m_total_files >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); } @@ -7960,7 +8037,7 @@ mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 cur_ofs = 0; char buf[4096]; - MZ_CLEAR_OBJ(buf); + MZ_CLEAR_ARR(buf); do { size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); @@ -8404,7 +8481,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 = 0, cur_archive_file_ofs = 0, comp_size = 0; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, + cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; tdefl_compressor *pComp = NULL; @@ -8436,8 +8514,6 @@ 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) @@ -8447,7 +8523,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2( pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ } - if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) { + if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) { pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ } @@ -8543,7 +8619,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2( } cur_archive_file_ofs += num_alignment_padding_bytes; - MZ_CLEAR_OBJ(local_dir_header); + MZ_CLEAR_ARR(local_dir_header); if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { @@ -8709,13 +8785,11 @@ mz_bool mz_zip_writer_add_read_buf_callback( mz_uint level_and_flags, mz_uint32 ext_attributes, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - mz_uint16 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) - ? 0 - : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; + mz_uint16 gen_flags; 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 = 0, uncomp_size = 0, - comp_size = 0; + mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, + uncomp_size = 0, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; mz_uint8 *pExtra_data = NULL; @@ -8724,13 +8798,17 @@ mz_bool mz_zip_writer_add_read_buf_callback( mz_zip_internal_state *pState; mz_uint64 file_ofs = 0, cur_archive_header_file_ofs; - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; - if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; level = level_and_flags & 0xF; + gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) + ? 0 + : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; + + if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) + gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; + /* Sanity checks */ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || @@ -8738,7 +8816,6 @@ 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 */ @@ -8816,7 +8893,7 @@ mz_bool mz_zip_writer_add_read_buf_callback( method = MZ_DEFLATED; } - MZ_CLEAR_OBJ(local_dir_header); + MZ_CLEAR_ARR(local_dir_header); if (pState->m_zip64) { if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) { pExtra_data = extra_data; @@ -9147,7 +9224,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, static mz_bool mz_zip_writer_update_zip64_extension_block( mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, - uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, + mz_uint32 ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) { /* + 64 should be enough for any new zip64 data */ if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE)) @@ -9493,12 +9570,13 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, if (pZip->m_pState->m_zip64) { /* dest is zip64, so upgrade the data descriptor */ - const mz_uint32 *pSrc_descriptor = - (const mz_uint32 *)((const mz_uint8 *)pBuf + - (has_id ? sizeof(mz_uint32) : 0)); - const mz_uint32 src_crc32 = pSrc_descriptor[0]; - const mz_uint64 src_comp_size = pSrc_descriptor[1]; - const mz_uint64 src_uncomp_size = pSrc_descriptor[2]; + const mz_uint8 *pSrc_descriptor = + (const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0); + const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor); + const mz_uint64 src_comp_size = + MZ_READ_LE32(pSrc_descriptor + sizeof(mz_uint32)); + const mz_uint64 src_uncomp_size = + MZ_READ_LE32(pSrc_descriptor + 2 * sizeof(mz_uint32)); mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID); mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32); @@ -9653,8 +9731,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { pState = pZip->m_pState; if (pState->m_zip64) { - if ((pZip->m_total_files > MZ_UINT32_MAX) || - (pState->m_central_dir.m_size >= MZ_UINT32_MAX)) + if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX) return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); } else { if ((pZip->m_total_files > MZ_UINT16_MAX) || @@ -9682,7 +9759,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { /* Write zip64 end of central directory header */ mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size; - MZ_CLEAR_OBJ(hdr); + MZ_CLEAR_ARR(hdr); MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG); MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, @@ -9705,7 +9782,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE; /* Write zip64 end of central directory locator */ - MZ_CLEAR_OBJ(hdr); + MZ_CLEAR_ARR(hdr); MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG); MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, @@ -9720,7 +9797,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { } /* Write end of central directory record */ - MZ_CLEAR_OBJ(hdr); + MZ_CLEAR_ARR(hdr); MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, diff --git a/thirdparty/zip/zip.c b/thirdparty/zip/zip.c index 13ed5bc4c57d2d..43c938e9849fd4 100644 --- a/thirdparty/zip/zip.c +++ b/thirdparty/zip/zip.c @@ -116,7 +116,7 @@ struct zip_entry_mark_t { size_t lf_length; }; -static const char *const zip_errlist[30] = { +static const char *const zip_errlist[33] = { NULL, "not initialized\0", "invalid entry name\0", @@ -147,11 +147,14 @@ static const char *const zip_errlist[30] = { "fseek error\0", "fread error\0", "fwrite error\0", + "cannot initialize reader\0", + "cannot initialize writer\0", + "cannot initialize writer from reader\0", }; const char *zip_strerror(int errnum) { errnum = -errnum; - if (errnum <= 0 || errnum >= 30) { + if (errnum <= 0 || errnum >= 33) { return NULL; } @@ -179,18 +182,18 @@ static const char *zip_basename(const char *name) { static int zip_mkpath(char *path) { char *p; - char npath[MAX_PATH + 1]; + char npath[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE + 1]; int len = 0; int has_device = HAS_DEVICE(path); - memset(npath, 0, MAX_PATH + 1); + memset(npath, 0, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE + 1); if (has_device) { // only on windows npath[0] = path[0]; npath[1] = path[1]; len = 2; } - for (p = path + len; *p && len < MAX_PATH; p++) { + for (p = path + len; *p && len < MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE; p++) { if (ISSLASH(*p) && ((!has_device && len > 0) || (has_device && len > 2))) { #if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ defined(__MINGW32__) @@ -303,24 +306,24 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, void *arg) { int err = 0; mz_uint i, n; - char path[MAX_PATH + 1]; - char symlink_to[MAX_PATH + 1]; + char path[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE + 1]; + char symlink_to[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE + 1]; mz_zip_archive_file_stat info; - size_t dirlen = 0; + size_t dirlen = 0, filename_size = MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE; mz_uint32 xattr = 0; memset(path, 0, sizeof(path)); memset(symlink_to, 0, sizeof(symlink_to)); dirlen = strlen(dir); - if (dirlen + 1 > MAX_PATH) { + if (dirlen + 1 > MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE) { return ZIP_EINVENTNAME; } memset((void *)&info, 0, sizeof(mz_zip_archive_file_stat)); #if defined(_MSC_VER) - strcpy_s(path, MAX_PATH, dir); + strcpy_s(path, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE, dir); #else strcpy(path, dir); #endif @@ -334,6 +337,9 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, ++dirlen; } + if (filename_size > MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - dirlen) { + filename_size = MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - dirlen; + } // Get and print information about each file in the archive. n = mz_zip_reader_get_num_files(zip_archive); for (i = 0; i < n; ++i) { @@ -349,11 +355,11 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, err = ZIP_EINVENTNAME; goto out; } + #if defined(_MSC_VER) - strncpy_s(&path[dirlen], MAX_PATH - dirlen, info.m_filename, - MAX_PATH - dirlen); + strncpy_s(&path[dirlen], filename_size, info.m_filename, filename_size); #else - strncpy(&path[dirlen], info.m_filename, MAX_PATH - dirlen); + strncpy(&path[dirlen], info.m_filename, filename_size); #endif err = zip_mkpath(path); if (err < 0) { @@ -371,9 +377,10 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, #if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ defined(__MINGW32__) #else - 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)) { + if (info.m_uncomp_size > MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE || + !mz_zip_reader_extract_to_mem_no_alloc( + zip_archive, i, symlink_to, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE, 0, + NULL, 0)) { err = ZIP_EMEMNOALLOC; goto out; } @@ -437,7 +444,7 @@ static ssize_t zip_entry_mark(struct zip_t *zip, } mz_zip_archive_file_stat file_stat; - mz_uint64 d_pos = ~0UL; + mz_uint64 d_pos = UINT64_MAX; for (i = 0; i < n; ++i) { if ((err = zip_entry_openbyindex(zip, i))) { return (ssize_t)err; @@ -483,6 +490,62 @@ static ssize_t zip_entry_mark(struct zip_t *zip, return err; } +static ssize_t zip_entry_markbyindex(struct zip_t *zip, + struct zip_entry_mark_t *entry_mark, + const ssize_t n, size_t entries[], + const size_t len) { + ssize_t i = 0; + ssize_t err = 0; + if (!zip || !entry_mark || !entries) { + return ZIP_ENOINIT; + } + + mz_zip_archive_file_stat file_stat; + mz_uint64 d_pos = UINT64_MAX; + for (i = 0; i < n; ++i) { + if ((err = zip_entry_openbyindex(zip, i))) { + return (ssize_t)err; + } + + mz_bool matches = MZ_FALSE; + { + size_t j; + for (j = 0; j < len; ++j) { + if ((size_t)i == entries[j]) { + matches = MZ_TRUE; + break; + } + } + } + if (matches) { + entry_mark[i].type = MZ_DELETE; + } else { + entry_mark[i].type = MZ_KEEP; + } + + if (!mz_zip_reader_file_stat(&zip->archive, i, &file_stat)) { + return ZIP_ENOENT; + } + + zip_entry_close(zip); + + entry_mark[i].m_local_header_ofs = file_stat.m_local_header_ofs; + entry_mark[i].file_index = (ssize_t)-1; + entry_mark[i].lf_length = 0; + if ((entry_mark[i].type) == MZ_DELETE && + (d_pos > entry_mark[i].m_local_header_ofs)) { + d_pos = entry_mark[i].m_local_header_ofs; + } + } + + for (i = 0; i < n; ++i) { + if ((entry_mark[i].m_local_header_ofs > d_pos) && + (entry_mark[i].type != MZ_DELETE)) { + entry_mark[i].type = MZ_MOVE; + } + } + return err; +} static ssize_t zip_index_next(mz_uint64 *local_header_ofs_array, ssize_t cur_index) { ssize_t new_index = 0, i; @@ -576,6 +639,21 @@ static ssize_t zip_entry_set(struct zip_t *zip, return 0; } +static ssize_t zip_entry_setbyindex(struct zip_t *zip, + struct zip_entry_mark_t *entry_mark, + ssize_t n, size_t entries[], + const size_t len) { + ssize_t err = 0; + + if ((err = zip_entry_markbyindex(zip, entry_mark, n, entries, len)) < 0) { + return err; + } + if ((err = zip_entry_finalize(zip, entry_mark, n)) < 0) { + return err; + } + return 0; +} + static ssize_t zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to, const mz_uint64 from, const size_t length, mz_uint8 *move_buf, const size_t capacity_size) { @@ -808,10 +886,18 @@ static ssize_t zip_entries_delete_mark(struct zip_t *zip, } struct zip_t *zip_open(const char *zipname, int level, char mode) { + int errnum = 0; + return zip_openwitherror(zipname, level, mode, &errnum); +} + +struct zip_t *zip_openwitherror(const char *zipname, int level, char mode, + int *errnum) { struct zip_t *zip = NULL; + *errnum = 0; if (!zipname || strlen(zipname) < 1) { // zip_t archive name is empty or NULL + *errnum = ZIP_EINVZIPNAME; goto cleanup; } @@ -819,12 +905,16 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { level = MZ_DEFAULT_LEVEL; if ((level & 0xF) > MZ_UBER_COMPRESSION) { // Wrong compression level + *errnum = ZIP_EINVLVL; goto cleanup; } zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t)); - if (!zip) + if (!zip) { + // out of memory + *errnum = ZIP_EOOMEM; goto cleanup; + } zip->level = (mz_uint)level; switch (mode) { @@ -833,11 +923,22 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { if (!mz_zip_writer_init_file_v2(&(zip->archive), zipname, 0, MZ_ZIP_FLAG_WRITE_ZIP64)) { // Cannot initialize zip_archive writer + *errnum = ZIP_EWINIT; goto cleanup; } break; case 'r': + if (!mz_zip_reader_init_file_v2( + &(zip->archive), zipname, + zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) { + // An archive file does not exist or cannot initialize + // zip_archive reader + *errnum = ZIP_ERINIT; + goto cleanup; + } + break; + case 'a': case 'd': if (!mz_zip_reader_init_file_v2_rpb( @@ -845,11 +946,13 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) { // An archive file does not exist or cannot initialize // zip_archive reader + *errnum = ZIP_ERINIT; goto cleanup; } if ((mode == 'a' || mode == 'd')) { if (!mz_zip_writer_init_from_reader_v2_noreopen(&(zip->archive), zipname, 0)) { + *errnum = ZIP_EWRINIT; mz_zip_reader_end(&(zip->archive)); goto cleanup; } @@ -857,6 +960,7 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { break; default: + *errnum = ZIP_EINVMODE; goto cleanup; } @@ -869,12 +973,21 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { void zip_close(struct zip_t *zip) { if (zip) { + mz_zip_archive *pZip = &(zip->archive); // Always finalize, even if adding failed for some reason, so we have a // valid central directory. - mz_zip_writer_finalize_archive(&(zip->archive)); - zip_archive_truncate(&(zip->archive)); - mz_zip_writer_end(&(zip->archive)); - mz_zip_reader_end(&(zip->archive)); + if (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) { + mz_zip_writer_finalize_archive(pZip); + } + + if (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING || + pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED) { + zip_archive_truncate(pZip); + mz_zip_writer_end(pZip); + } + if (pZip->m_zip_mode == MZ_ZIP_MODE_READING) { + mz_zip_reader_end(pZip); + } CLEANUP(zip); } @@ -896,7 +1009,7 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname, mz_uint num_alignment_padding_bytes, level; mz_zip_archive_file_stat stats; int err = 0; - mz_uint16 dos_time, dos_date; + mz_uint16 dos_time = 0, dos_date = 0; mz_uint32 extra_size = 0; mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; mz_uint64 local_dir_header_ofs = 0; @@ -1591,6 +1704,41 @@ ssize_t zip_entries_delete(struct zip_t *zip, char *const entries[], return err; } +ssize_t zip_entries_deletebyindex(struct zip_t *zip, size_t entries[], + size_t len) { + ssize_t n = 0; + ssize_t err = 0; + struct zip_entry_mark_t *entry_mark = NULL; + + if (zip == NULL || (entries == NULL && len != 0)) { + return ZIP_ENOINIT; + } + + if (entries == NULL && len == 0) { + return 0; + } + + n = zip_entries_total(zip); + + entry_mark = (struct zip_entry_mark_t *)calloc( + (size_t)n, sizeof(struct zip_entry_mark_t)); + if (!entry_mark) { + return ZIP_EOOMEM; + } + + zip->archive.m_zip_mode = MZ_ZIP_MODE_READING; + + err = zip_entry_setbyindex(zip, entry_mark, n, entries, len); + if (err < 0) { + CLEANUP(entry_mark); + return err; + } + + err = zip_entries_delete_mark(zip, entry_mark, (int)n); + CLEANUP(entry_mark); + return err; +} + int zip_stream_extract(const char *stream, size_t size, const char *dir, int (*on_extract)(const char *filename, void *arg), void *arg) { @@ -1613,8 +1761,16 @@ int zip_stream_extract(const char *stream, size_t size, const char *dir, struct zip_t *zip_stream_open(const char *stream, size_t size, int level, char mode) { + int errnum = 0; + return zip_stream_openwitherror(stream, size, level, mode, &errnum); +} + +struct zip_t *zip_stream_openwitherror(const char *stream, size_t size, + int level, char mode, int *errnum) { struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t)); if (!zip) { + // out of memory + *errnum = ZIP_EOOMEM; return NULL; } @@ -1623,23 +1779,29 @@ struct zip_t *zip_stream_open(const char *stream, size_t size, int level, } if ((level & 0xF) > MZ_UBER_COMPRESSION) { // Wrong compression level + *errnum = ZIP_EINVLVL; goto cleanup; } zip->level = (mz_uint)level; if ((stream != NULL) && (size > 0) && (mode == 'r')) { if (!mz_zip_reader_init_mem(&(zip->archive), stream, size, 0)) { + *errnum = ZIP_ERINIT; goto cleanup; } } else if ((stream == NULL) && (size == 0) && (mode == 'w')) { // Create a new archive. if (!mz_zip_writer_init_heap(&(zip->archive), 0, 1024)) { // Cannot initialize zip_archive writer + *errnum = ZIP_EWINIT; goto cleanup; } } else { + *errnum = ZIP_EINVMODE; goto cleanup; } + + *errnum = 0; return zip; cleanup: diff --git a/thirdparty/zip/zip.h b/thirdparty/zip/zip.h index 6de72194c26b6c..ce2246e810a8fb 100644 --- a/thirdparty/zip/zip.h +++ b/thirdparty/zip/zip.h @@ -44,14 +44,10 @@ typedef long ssize_t; /* byte count or error */ #endif #endif -#ifndef MAX_PATH -#define MAX_PATH 1024 /* # chars in a path name including NULL */ -#endif - /** * @mainpage * - * Documenation for @ref zip. + * Documentation for @ref zip. */ /** @@ -96,11 +92,14 @@ typedef long ssize_t; /* byte count or error */ #define ZIP_EFSEEK -27 // fseek error #define ZIP_EFREAD -28 // fread error #define ZIP_EFWRITE -29 // fwrite error +#define ZIP_ERINIT -30 // cannot initialize reader +#define ZIP_EWINIT -31 // cannot initialize writer +#define ZIP_EWRINIT -32 // cannot initialize writer from reader /** - * Looks up the error message string coresponding to an error number. + * Looks up the error message string corresponding to an error number. * @param errnum error number - * @return error message string coresponding to errnum or NULL if error is not + * @return error message string corresponding to errnum or NULL if error is not * found. */ extern ZIP_EXPORT const char *zip_strerror(int errnum); @@ -128,6 +127,23 @@ struct zip_t; extern ZIP_EXPORT struct zip_t *zip_open(const char *zipname, int level, char mode); +/** + * Opens zip archive with compression level using the given mode. + * The function additionally returns @param errnum - + * + * @param zipname zip archive file name. + * @param level compression level (0-9 are the standard zlib-style levels). + * @param mode file access mode. + * - 'r': opens a file for reading/extracting (the file must exists). + * - 'w': creates an empty file for writing. + * - 'a': appends to an existing archive. + * @param errnum 0 on success, negative number (< 0) on error. + * + * @return the zip archive handler or NULL on error + */ +extern ZIP_EXPORT struct zip_t * +zip_openwitherror(const char *zipname, int level, char mode, int *errnum); + /** * Closes the zip archive, releases resources - always finalize. * @@ -374,6 +390,18 @@ extern ZIP_EXPORT ssize_t zip_entries_total(struct zip_t *zip); extern ZIP_EXPORT ssize_t zip_entries_delete(struct zip_t *zip, char *const entries[], size_t len); +/** + * Deletes zip archive entries. + * + * @param zip zip archive handler. + * @param entries array of zip archive entries indices to be deleted. + * @param len the number of entries to be deleted. + * @return the number of deleted entries, or negative number (< 0) on error. + */ +extern ZIP_EXPORT ssize_t zip_entries_deletebyindex(struct zip_t *zip, + size_t entries[], + size_t len); + /** * Extracts a zip archive stream into directory. * @@ -401,12 +429,37 @@ zip_stream_extract(const char *stream, size_t size, const char *dir, * * @param stream zip archive stream. * @param size stream size. + * @param level compression level (0-9 are the standard zlib-style levels). + * @param mode file access mode. + * - 'r': opens a file for reading/extracting (the file must exists). + * - 'w': creates an empty file for writing. + * - 'a': appends to an existing archive. * * @return the zip archive handler or NULL on error */ extern ZIP_EXPORT struct zip_t *zip_stream_open(const char *stream, size_t size, int level, char mode); +/** + * Opens zip archive stream into memory. + * The function additionally returns @param errnum - + * + * @param stream zip archive stream. + * @param size stream size.* + * @param level compression level (0-9 are the standard zlib-style levels). + * @param mode file access mode. + * - 'r': opens a file for reading/extracting (the file must exists). + * - 'w': creates an empty file for writing. + * - 'a': appends to an existing archive. + * @param errnum 0 on success, negative number (< 0) on error. + * + * @return the zip archive handler or NULL on error + */ +extern ZIP_EXPORT struct zip_t *zip_stream_openwitherror(const char *stream, + size_t size, int level, + char mode, + int *errnum); + /** * Copy zip archive stream output buffer. *