From ab6f27dfea7d16f00955de6e744377409e9b2072 Mon Sep 17 00:00:00 2001 From: Thomas Johnstone Date: Thu, 11 Jul 2024 15:03:52 +1000 Subject: [PATCH] Update miniz to 3.0.2 This fixes the size returned from mz_zip_reader_extract_to_heap for large resource buffers More details can be found here: https://github.com/richgel999/miniz/pull/220 --- renderdoc/3rdparty/miniz/miniz.c | 486 +++++++++++++++++++++---------- renderdoc/3rdparty/miniz/miniz.h | 142 +++++++-- 2 files changed, 437 insertions(+), 191 deletions(-) diff --git a/renderdoc/3rdparty/miniz/miniz.c b/renderdoc/3rdparty/miniz/miniz.c index 4ba0210b9..a5a5b36ca 100644 --- a/renderdoc/3rdparty/miniz/miniz.c +++ b/renderdoc/3rdparty/miniz/miniz.c @@ -187,6 +187,8 @@ const char *mz_version(void) #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); @@ -321,7 +323,7 @@ int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char memset(&stream, 0, sizeof(stream)); /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) + if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; stream.next_in = pSource; @@ -354,6 +356,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; @@ -553,19 +559,18 @@ int mz_inflateEnd(mz_streamp pStream) } return MZ_OK; } - -int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len) { mz_stream stream; int status; memset(&stream, 0, sizeof(stream)); /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) + if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; 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; @@ -574,6 +579,7 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char return status; status = mz_inflate(&stream, MZ_FINISH); + *pSource_len = *pSource_len - stream.avail_in; if (status != MZ_STREAM_END) { mz_inflateEnd(&stream); @@ -584,6 +590,13 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char return mz_inflateEnd(&stream); } +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_uncompress2(pDest, pDest_len, pSource, &source_len); +} + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + const char *mz_error(int err) { static struct @@ -661,6 +674,8 @@ const char *mz_error(int err) +#ifndef MINIZ_NO_DEFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -739,7 +754,7 @@ static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *p { 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; @@ -857,7 +872,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int { 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++) @@ -883,8 +898,8 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int 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); @@ -970,7 +985,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int } \ } -static 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 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) { @@ -1108,7 +1123,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]]); @@ -1153,7 +1169,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; @@ -1235,6 +1251,8 @@ 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; @@ -1255,8 +1273,27 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush) 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); @@ -1709,9 +1746,7 @@ static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; - - if (match_len >= TDEFL_MIN_MATCH_LEN) - d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; + d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; } static mz_bool tdefl_compress_normal(tdefl_compressor *d) @@ -1729,7 +1764,7 @@ static mz_bool tdefl_compress_normal(tdefl_compressor *d) mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ 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) @@ -1939,8 +1974,8 @@ tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pI 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; } } @@ -1963,11 +1998,12 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun 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 = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; + *d->m_pLZ_flags = 0; d->m_num_flags_left = 8; d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; @@ -1983,7 +2019,7 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun 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, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); return TDEFL_STATUS_OKAY; @@ -2074,8 +2110,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void 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). */ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) { @@ -2193,7 +2227,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, /* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */ /* 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)); } @@ -2211,6 +2245,8 @@ void tdefl_compressor_free(tdefl_compressor *pComp) #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ /************************************************************************** * * Copyright 2013-2014 RAD Game Tools and Valve Software @@ -2239,6 +2275,8 @@ void tdefl_compressor_free(tdefl_compressor *pComp) +#ifndef MINIZ_NO_INFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -2319,10 +2357,10 @@ extern "C" { /* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ /* Huffman code by using whatever bits are currently present in the bit buffer. 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; \ @@ -2334,7 +2372,7 @@ extern "C" { 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; \ @@ -2350,7 +2388,7 @@ extern "C" { /* The slow path is only executed at the very end of the input buffer. */ /* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 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; \ @@ -2359,7 +2397,7 @@ extern "C" { { \ if ((pIn_buf_end - pIn_buf_cur) < 2) \ { \ - TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \ } \ else \ { \ @@ -2368,14 +2406,14 @@ 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; \ @@ -2384,20 +2422,33 @@ 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] = { 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] = { 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_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 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 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; tinfl_bit_buf_t bit_buf; 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; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = 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 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */ @@ -2407,6 +2458,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex 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; @@ -2423,7 +2481,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex TINFL_GET_BYTE(2, r->m_zhdr1); counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); 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))))); + counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4))))); if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); @@ -2484,11 +2542,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { 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) @@ -2505,26 +2563,30 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex 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) @@ -2538,7 +2600,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex } 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]++; @@ -2549,14 +2611,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex 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)])) + if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { - pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; + pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } @@ -2564,24 +2626,24 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_tree[-tree_cur - 1]) + if (!pTree[-tree_cur - 1]) { - pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; + 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); - 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; @@ -2601,8 +2663,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { 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], r->m_table_sizes[1]); + 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]); } } for (;;) @@ -2612,7 +2674,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { 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) @@ -2640,14 +2702,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex num_bits += 16; } #endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + if ((sym2 = 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; @@ -2664,14 +2726,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex num_bits += 16; } #endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + if ((sym2 = 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; @@ -2700,7 +2762,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex 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) @@ -2711,7 +2773,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex } dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; - if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) { TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); } @@ -2785,7 +2847,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex --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). */ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) @@ -2817,7 +2879,7 @@ common_exit: } } 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; @@ -2912,6 +2974,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 (;;) { @@ -2934,7 +2997,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) @@ -2951,6 +3014,8 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp) #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ /************************************************************************** * * Copyright 2013-2014 RAD Game Tools and Valve Software @@ -2993,19 +3058,48 @@ extern "C" { #include #if defined(_MSC_VER) || defined(__MINGW64__) + +#define WIN32_LEAN_AND_MEAN +#include + +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) { - FILE *pFile = NULL; - fopen_s(&pFile, pFilename, pMode); - return pFile; + WCHAR* wFilename = mz_utf8z_to_widechar(pFilename); + WCHAR* wMode = mz_utf8z_to_widechar(pMode); + FILE* pFile = NULL; + errno_t err = _wfopen_s(&pFile, wFilename, wMode); + free(wFilename); + free(wMode); + return err ? NULL : pFile; } + static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { - FILE *pFile = NULL; - if (freopen_s(&pFile, pPath, pMode, pStream)) - return NULL; - return pFile; + WCHAR* wPath = mz_utf8z_to_widechar(pPath); + WCHAR* wMode = mz_utf8z_to_widechar(pMode); + FILE* pFile = NULL; + errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream); + free(wPath); + free(wMode); + return err ? NULL : pFile; } + +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; +} + #ifndef MINIZ_NO_TIME #include #endif @@ -3016,11 +3110,12 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) #define MZ_FTELL64 _ftelli64 #define MZ_FSEEK64 _fseeki64 #define MZ_FILE_STAT_STRUCT _stat64 -#define MZ_FILE_STAT _stat64 +#define MZ_FILE_STAT mz_stat64 #define MZ_FFLUSH fflush #define MZ_FREOPEN mz_freopen #define MZ_DELETE_FILE remove -#elif defined(__MINGW32__) + +#elif defined(__MINGW32__) || defined(__WATCOMC__) #ifndef MINIZ_NO_TIME #include #endif @@ -3028,13 +3123,14 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello64 -#define MZ_FSEEK64 fseeko64 -#define MZ_FILE_STAT_STRUCT _stat -#define MZ_FILE_STAT _stat +#define MZ_FTELL64 _ftelli64 +#define MZ_FSEEK64 _fseeki64 +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove + #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME #include @@ -3050,7 +3146,8 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove -#elif defined(__USE_LARGEFILE64) + +#elif defined(__USE_LARGEFILE64) /* gcc, clang */ #ifndef MINIZ_NO_TIME #include #endif @@ -3065,7 +3162,8 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) #define MZ_FFLUSH fflush #define MZ_FREOPEN(p, m, s) freopen64(p, m, s) #define MZ_DELETE_FILE remove -#elif defined(__APPLE__) + +#elif defined(__APPLE__) || defined(__FreeBSD__) #ifndef MINIZ_NO_TIME #include #endif @@ -3082,7 +3180,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) #define MZ_DELETE_FILE remove #else -//#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.") +#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.") #ifndef MINIZ_NO_TIME #include #endif @@ -3211,7 +3309,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. */ mz_bool m_zip64; @@ -3230,7 +3328,7 @@ struct mz_zip_internal_state_tag #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size -#if defined(DEBUG) || defined(_DEBUG) || defined(NDEBUG) +#if defined(DEBUG) || defined(_DEBUG) static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index) { MZ_ASSERT(index < pArray->m_size); @@ -3647,7 +3745,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag if (((num_this_disk | cdir_disk_index) != 0) && ((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) @@ -3798,7 +3896,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag 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, mz_bool set_last_error) @@ -4272,7 +4370,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; 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) @@ -4287,7 +4385,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char 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); if (!comp) @@ -4380,7 +4478,8 @@ mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, co return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); } -mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) +static +mz_bool mz_zip_reader_extract_to_mem_no_alloc1(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size, const mz_zip_archive_file_stat *st) { int status = TINFL_STATUS_DONE; mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; @@ -4393,6 +4492,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead)) return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + if (st) { + file_stat = *st; + } else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; @@ -4523,17 +4625,22 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file return status == TINFL_STATUS_DONE; } +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t 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_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) { 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, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) @@ -4543,23 +4650,17 @@ mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFil void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) { - mz_uint64 comp_size, uncomp_size, alloc_size; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); + mz_zip_archive_file_stat file_stat; + mz_uint64 alloc_size; void *pBuf; if (pSize) *pSize = 0; - if (!p) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return NULL; - } - comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - - alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; + alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) { mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); @@ -4572,7 +4673,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, si return NULL; } - if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags)) + if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, (size_t)alloc_size, flags, NULL, 0, &file_stat)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return NULL; @@ -4598,7 +4699,9 @@ void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFile mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) { int status = TINFL_STATUS_DONE; +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS mz_uint file_crc32 = MZ_CRC32_INIT; +#endif mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; mz_zip_archive_file_stat file_stat; void *pRead_buf = NULL; @@ -4894,7 +4997,7 @@ mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))) { /* Decompression required, therefore intermediate read buffer required */ - pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); + pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)pState->read_buf_size))) { mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); @@ -5031,7 +5134,7 @@ size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, size_t to_copy = 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 */ @@ -5252,7 +5355,10 @@ mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint f return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + goto handle_failure; + } if (local_header_filename_len) { @@ -5286,14 +5392,20 @@ mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint f mz_uint32 field_id, field_data_size, field_total_size; if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + goto handle_failure; + } field_id = MZ_READ_LE16(pExtra_data); field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); field_total_size = field_data_size + sizeof(mz_uint16) * 2; if (field_total_size > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + goto handle_failure; + } if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { @@ -5391,7 +5503,7 @@ handle_failure: 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)) return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); @@ -5409,9 +5521,6 @@ mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) } 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); } @@ -5773,7 +5882,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 { @@ -6136,7 +6245,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n 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); */ @@ -6186,8 +6295,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n if (!pState->m_zip64) { /* Bail early if the archive would obviously become too large */ - if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size - + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + + if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) { @@ -6229,7 +6338,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n } 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)) { @@ -6376,35 +6485,37 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n return MZ_TRUE; } -mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, +mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, 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 = 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, ext_attributes = 0; - mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = size_to_add, 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; mz_uint32 extra_size = 0; mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; mz_zip_internal_state *pState; - mz_uint64 file_ofs = 0; - - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; + mz_uint64 file_ofs = 0, cur_archive_header_file_ofs; 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) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); pState = pZip->m_pState; - if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX)) + if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX)) { /* Source file is too large for non-zip64 */ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ @@ -6461,7 +6572,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA } #endif - if (uncomp_size <= 3) + if (max_size <= 3) level = 0; if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) @@ -6477,19 +6588,25 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } - if (uncomp_size && level) + if (max_size && level) { method = MZ_DEFLATED; } - MZ_CLEAR_OBJ(local_dir_header); + MZ_CLEAR_ARR(local_dir_header); if (pState->m_zip64) { - if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) + if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) { pExtra_data = extra_data; - extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, + (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + else + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL, + NULL, + (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); } if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, gen_flags, dos_time, dos_date)) @@ -6540,9 +6657,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA cur_archive_file_ofs += user_extra_data_len; } - if (uncomp_size) + if (max_size) { - mz_uint64 uncomp_remaining = uncomp_size; void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); if (!pRead_buf) { @@ -6551,19 +6667,27 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA if (!level) { - while (uncomp_remaining) + while (1) { - mz_uint n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); - if ((read_callback(callback_opaque, file_ofs, pRead_buf, n) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)) + size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE); + if (n == 0) + break; + + if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); } - file_ofs += n; + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + file_ofs += n; uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); - uncomp_remaining -= n; cur_archive_file_ofs += n; } + uncomp_size = file_ofs; comp_size = uncomp_size; } else @@ -6590,24 +6714,26 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA for (;;) { - size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); tdefl_status status; tdefl_flush flush = TDEFL_NO_FLUSH; - if (read_callback(callback_opaque, file_ofs, pRead_buf, in_buf_size)!= in_buf_size) + size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE); + if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) { mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); break; } - file_ofs += in_buf_size; - uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); - uncomp_remaining -= in_buf_size; + file_ofs += n; + uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque)) flush = TDEFL_FULL_FLUSH; - status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? flush : TDEFL_FINISH); + if (n == 0) + flush = TDEFL_FINISH; + + status = tdefl_compress_buffer(pComp, pRead_buf, n, flush); if (status == TDEFL_STATUS_DONE) { result = MZ_TRUE; @@ -6628,6 +6754,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA return MZ_FALSE; } + uncomp_size = file_ofs; comp_size = state.m_comp_size; cur_archive_file_ofs = state.m_cur_archive_file_ofs; } @@ -6635,6 +6762,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); } + if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)) { mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; @@ -6662,6 +6790,44 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA cur_archive_file_ofs += local_dir_footer_size; } + if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) + { + if (pExtra_data != NULL) + { + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, + (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size, + uncomp_crc32, method, gen_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + cur_archive_header_file_ofs = local_dir_header_ofs; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + if (pExtra_data != NULL) + { + cur_archive_header_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_header_file_ofs += archive_name_size; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_header_file_ofs += extra_size; + } + } + if (pExtra_data != NULL) { extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, @@ -6692,10 +6858,10 @@ static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *p return MZ_FREAD(pBuf, 1, n, pSrc_file); } -mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, +mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, size_to_add, pFile_time, pComment, comment_size, level_and_flags, + return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); } @@ -6731,7 +6897,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, } #endif /* #ifndef MINIZ_NO_STDIO */ -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_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) +static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, 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)) @@ -7047,10 +7213,10 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive * 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); @@ -7186,7 +7352,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) 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 @@ -7214,7 +7380,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, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64)); MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */ @@ -7229,7 +7395,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, rel_ofs_to_zip64_ecdr); MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1); @@ -7240,7 +7406,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, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); @@ -7556,7 +7722,9 @@ const char *mz_zip_get_error_string(mz_zip_error mz_err) case MZ_ZIP_VALIDATION_FAILED: return "validation failed"; case MZ_ZIP_WRITE_CALLBACK_FAILED: - return "write calledback failed"; + return "write callback failed"; + case MZ_ZIP_TOTAL_ERRORS: + return "total errors"; default: break; } diff --git a/renderdoc/3rdparty/miniz/miniz.h b/renderdoc/3rdparty/miniz/miniz.h index c5636c5e8..9fcfffcc8 100644 --- a/renderdoc/3rdparty/miniz/miniz.h +++ b/renderdoc/3rdparty/miniz/miniz.h @@ -1,5 +1,7 @@ +#ifndef MINIZ_EXPORT #define MINIZ_EXPORT -/* miniz.c 2.1.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing +#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: http://www.ietf.org/rfc/rfc1951.txt @@ -96,7 +98,7 @@ possibility that the archive's central directory could be lost with this method if anything goes wrong, though. - ZIP archive support limitations: - No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files. + No spanning support. Extraction functions can only handle unencrypted, stored or deflated files. Requires streams capable of seeking. * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the @@ -116,7 +118,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. */ + If all macros here are defined the only functionality remaining will be CRC-32 and adler-32. */ /* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */ /*#define MINIZ_NO_STDIO */ @@ -126,6 +128,12 @@ /* The current downside is the times written to your archives will be from 1979. */ /*#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 */ @@ -144,6 +152,14 @@ functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */ /*#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 */ #define MINIZ_NO_TIME @@ -162,18 +178,40 @@ #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 @@ -221,7 +259,7 @@ enum #define MZ_DEFLATED 8 /* Heap allocation callbacks. -Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. */ +Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */ typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); typedef void (*mz_free_func)(void *opaque, void *address); typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); @@ -237,10 +275,10 @@ enum MZ_DEFAULT_COMPRESSION = -1 }; -#define MZ_VERSION "10.1.0" -#define MZ_VERNUM 0xA100 -#define MZ_VER_MAJOR 10 -#define MZ_VER_MINOR 1 +#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 @@ -305,6 +343,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. */ @@ -357,6 +397,10 @@ MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const u /* mz_compressBound() returns a (very) conservative upper bound on the amount of 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); @@ -389,6 +433,8 @@ MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream); /* Single-call decompression. */ /* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */ MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_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. */ MINIZ_EXPORT const char *mz_error(int err); @@ -439,6 +485,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 @@ -448,12 +496,18 @@ 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 #define inflate mz_inflate #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 @@ -517,7 +571,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 @@ -539,6 +594,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)) @@ -575,6 +632,8 @@ extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, si #pragma once +#ifndef MINIZ_NO_DEFLATE_APIS + #ifdef __cplusplus extern "C" { #endif @@ -762,10 +821,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 @@ -874,12 +937,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 @@ -899,13 +956,21 @@ struct tinfl_decompressor_tag mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, 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]; }; #ifdef __cplusplus } #endif + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ #pragma once @@ -940,10 +1005,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; @@ -980,6 +1041,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, void *pBuf, size_t n); @@ -1005,7 +1071,10 @@ typedef enum { MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */ MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */ MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000, - MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000 + MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000, + /*After adding a compressed file, seek back + to local file header and set the correct sizes*/ + MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000 } mz_zip_flags; typedef enum { @@ -1088,9 +1157,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; void *pRead_buf; @@ -1100,6 +1167,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 */ @@ -1223,9 +1296,9 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, c /* 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 @@ -1239,7 +1312,9 @@ MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags /* Misc utils/helpers, valid for ZIP reading or writing */ 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(). */ MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip); @@ -1288,17 +1363,18 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const cha /* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */ /* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/ -MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 size_to_add, +MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len); + #ifndef MINIZ_NO_STDIO /* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */ /* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); /* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, +MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len); #endif @@ -1312,7 +1388,7 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_ /* An archive must be manually finalized by calling this function for it to be 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. */ MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize); @@ -1329,11 +1405,13 @@ MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip); MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, 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. */ /* Returns NULL on failure. */ MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags); 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 */