Compare commits

..

70 Commits

Author SHA1 Message Date
Martin Raiber
0c30a001bc
Merge pull request #329 from iibclothier/master
Remedy CVE-2018-12913
2024-12-29 22:45:57 +01:00
iibclothier
8980137de6
Merge pull request #1 from iibclothier/fix_cifuzz_yml
Update ci-fuzz.yml
2024-12-28 11:45:33 -06:00
iibclothier
4d99a8f7c2
Update ci-fuzz.yml
Try version 4
2024-12-28 11:24:41 -06:00
iibclothier
13c4e52c91
Update ci-fuzz.yml
Version 1 is deprecated, bump to version 2.
2024-12-28 11:18:43 -06:00
iibclothier
d9be48fbe6 Fix formatting 2024-12-18 08:16:26 -06:00
iibclothier
3a404922aa Merge branch 'Branch_3.0.2'
# Conflicts:
#	miniz_tinfl.c
2024-12-18 08:12:02 -06:00
iibclothier
e680017bae Add a check to guard against potential infinite loop when given a bad zip file. See https://github.com/Edward-L/my-cve-list/blob/master/miniz/README.md
and https://nvd.nist.gov/vuln/detail/CVE-2018-12913 for details.
2024-12-18 08:04:53 -06:00
Martin
2fa13ca8a3 Replace defines with function wrappers etc. as much as possible 2024-12-06 21:30:49 +01:00
Martin Raiber
0f4cbb8c27
Merge pull request #325 from tyler92/add-in-place-fuzzer
Add fuzzer for mz_zip_add_mem_to_archive_file_in_place function
2024-11-17 23:49:18 +01:00
Mikhail Khachayants
efbf3935b1 Add fuzzer for mz_zip_add_mem_to_archive_file_in_place function 2024-11-17 22:48:27 +02:00
Martin Raiber
35528ad769
Merge pull request #316 from zhaozg/fix/stdio
cmake: new option BUILD_NO_STDIO to enable MINIZ_NO_STDIO
2024-10-17 20:11:01 +02:00
zhaozg
189f56edaa cmake: new option BUILD_NO_STDIO to enable MINIZ_NO_STDIO 2024-10-17 11:27:24 +08:00
Martin
11e7c39508 Avoid fdreopen if possible
Avoid using fdropen in mz_zip_add_mem_to_archive_file_in_place or
if new flag MZ_ZIP_FLAG_READ_ALLOW_WRITING is set.

This improves performance, but also fdreopen is broken on Android
(some kind of race).
2024-10-16 23:07:29 +02:00
Martin Raiber
1ff82be7d6 Cast enum value to int 2024-08-05 10:46:09 +02:00
Martin Raiber
8e8e609e02 Re-use types from stdint.h 2024-08-05 10:45:42 +02:00
Martin Raiber
bf7a1f0a5a
Merge pull request #315 from zhaozg/master
fix ops detect for MZ_ZIP_TYPE_USER
2024-07-09 23:07:05 +02:00
Martin Raiber
4000bc3a87
Update c-cpp.yml 2024-07-09 22:49:42 +02:00
zhaozg
200c9053d0 fix ops detect for MZ_ZIP_TYPE_USER 2024-07-09 15:35:28 +08:00
Martin Raiber
8573fd7cd6
Merge pull request #310 from LemonBoy/fuzzer-fix
Two small fixes
2024-06-10 22:26:59 +02:00
LemonBoy
961de84cbb Limit the archive offset detection to files
It makes sense to avoid changing the offset and/or the archive size when
the user specifies a buffer rather than a file.
2024-06-10 11:57:36 +02:00
LemonBoy
0283a1796e Guard against malformed input files
Ensure the archive start offset can never be negative.
Fixes a case found by OSSFuzz.
2024-06-10 11:56:48 +02:00
Martin Raiber
3c46a05141
Merge pull request #309 from LemonBoy/zip-offset
Support Zip archives not starting at zero offset
2024-06-09 21:50:49 +02:00
LemonBoy
43bc679d05 Support Zip archives not starting at zero offset
Zip archives are usually read from the back to the front, making it
possible to append them to other files (e.g. executables) in order to
provide some kind of embedded filesystem.

We can actually extract the start of the archive by looking at the
central directory offset, by comparing the specified and the actual file
offset.

The Zip64 format adds another challenge as the EOCD locator specifies
the offset to the EOCD starting from the beginning of the archive. Such
relative offset cannot be directly used for archives not starting at
position zero, hence the addition of another step that tries to locate
the 64bit EOCD right before the EOCD locator. The added overhead is
pretty small (and could be made smaller by reading both the presumed
EOCD and EOCD locator at once) and works pretty well for 90% of the
archives I've tested it with, if that heuristic fails the old behaviour
is preserved.
2024-06-01 11:48:07 +02:00
Martin
8714fd3cd8 Format code with clang-format 2024-05-16 21:24:56 +02:00
Martin Raiber
60ec4a72b9
Merge pull request #305 from rojer/warnings
Fix unused arg warnings when building with MINIZ_NO_TIME
2024-05-16 21:05:51 +02:00
Martin Raiber
3cc84f4f0c
Merge pull request #306 from rojer/lm_redefine
Do not redefine TDEFL_LESS_MEMORY if already defined
2024-05-16 21:05:24 +02:00
Deomid rojer Ryabkov
2552e6d45a Do not redefine TDEFL_LESS_MEMORY if already defined 2024-03-23 19:57:23 +00:00
Deomid rojer Ryabkov
622aea128a Fix unused arg warnings when building with MINIZ_NO_TIME 2024-03-23 19:55:43 +00:00
Martin Raiber
16413c213d
Merge pull request #299 from DavidKorczynski/fix-fuzzer-build
Fix OSS-Fuzz build
2024-01-06 11:53:43 +01:00
David Korczynski
a77af68d92 fix OSS-Fuzz build
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64398

Signed-off-by: David Korczynski <david@adalogics.com>
2024-01-02 03:16:18 -08:00
Martin Raiber
e5700656b3
Merge pull request #287 from Wertzui123/Wertzui123-patch-1
Don't redefine `WIN32_LEAN_AND_MEAN` if already defined
2023-11-19 21:09:11 +01:00
Martin Raiber
4d6f89cb0a
Merge pull request #288 from jpcha2/master
Remove parameter check in `tinfl_decompress` that breaks `tinfl_decompress_mem_to_heap`
2023-11-19 20:57:40 +01:00
Martin
f8a09fe199 Fix step description 2023-11-19 20:55:38 +01:00
Martin
6cfbb0d1d8 Fix preset file 2023-11-19 20:54:09 +01:00
Martin
fa8ef4584b Fix preset file 2023-11-19 20:52:45 +01:00
Martin
039b1d2962 Use unix makefiles generator 2023-11-19 20:50:45 +01:00
Martin Raiber
32bb60d989
Update c-cpp.yml 2023-11-19 20:47:38 +01:00
Martin
05ab4dc05c Add some catch2 tests 2023-11-19 20:45:17 +01:00
Martin
697f010d70 Revert parameter check
Check breaks tinfl_decompress_mem_to_heap
2023-11-19 20:27:07 +01:00
John Paul Chacha
bd9e22f577
Merge pull request #2 from jpcha2/jpcha2-patch-1-param-check-tinfl_decompress
Update miniz_tinfl.c to remove parameter check that breaks tinfl_decompress_mem_to_heap()
2023-10-09 09:20:34 +03:00
John Paul Chacha
9aef68479f
Update miniz_tinfl.c
Remove parameter check that breaks tinfl_decompress_mem_to_heap() (see discussion on pull request #268)
2023-10-09 08:39:00 +03:00
Wertzui123
69763e8811
Don't redefine WIN32_LEAN_AND_MEAN if already defined 2023-10-07 14:13:08 +02:00
Martin Raiber
18795fa61e
Merge pull request #286 from Sororfortuna/patch-1
Bump cmake minimum version
2023-09-28 20:07:39 +02:00
Martin Raiber
96b0c0fc64
Merge pull request #266 from fabiangreffrath/lfs_linux64
Fix missing large file support warning on 64-bit Linux
2023-09-28 20:07:21 +02:00
Martin Raiber
acfba6a21d
Merge pull request #280 from nyq/nyq-s_tdefl_num_probes-cpp
Update miniz_tdef.c to enable compiling in forced-C++ mode
2023-09-28 20:05:56 +02:00
Martin Raiber
93ded54847
Merge pull request #282 from nyq/nyq-fix-version-in-comment
Update miniz.h to correctly reflect release version in the title comment
2023-09-28 20:03:00 +02:00
Martin Raiber
a23a38bf53
Merge pull request #283 from nyq/nyq-fix-min-max-conflicts
Prevent min/max conflicts between windows.h and std namespace
2023-09-28 20:00:07 +02:00
Igor Alexey
d0190e5cdf
bump cmake minimum version 2023-09-28 09:01:25 -03:00
Nyq
90a5b2f89b
Prevent min/max conflicts between windows.h and std namespace
Miniz started including windows.h from version 3.0.0 and on when compiling for Windows using MSVC.

windows.h header file is known to conflict with C++ std namespace by defining its own min/max macros. It is a common practice to disable these ancient macros in windows.h by declaring NOMINMAX macro prior to including windows.h in code.

While this issue does not affect miniz directly due to the fact that it is straight-C code and it does not use min/max from C++ std namespace, it does affect other projects like miniz-cpp which wrap and amalgamate miniz and then both compile in C++ mode and use min/max from std namespace.

It is therefore proposed to prefix inclusion of windows.h in miniz_zip.c by the following lines:

#ifndef NOMINMAX
#define NOMINMAX
#endif
2023-08-15 07:21:03 -04:00
Nyq
6f09a0f0b5
Update miniz.h to correctly reflect release version in the title comment
The version number in the title comment (line 1) was not updated since version 3.0.0, which causes confusion between versions 3.0.0, 3.0.1 and 3.0.2. It would be good if the title comment in this header file was updated for each release as it is exactly that this comment is being looked at by most programmers when checking the library version in their code trees.
2023-08-15 06:58:55 -04:00
Nyq
fd55960854
Update miniz_zip.c to prevent compilation warning when compiling for Windows in straight C mode
Summary:
Added conditional macro definition to prevent MSVC compiler warning C5105 when compiling for Windows in straight C mode

Details:
Since version 3.0.0 miniz_zip.c includes windows.h header file when compiling for Windows using MSVC. However, when compiling miniz_zip.c using MSVC17 in straight-C mode (no C++), this inclusion causes warning C5105:

winbase.h(9531,5): warning C5105: macro expansion producing 'defined' has undefined behavior

This warning is not produced when compiling in C++ mode.

In order to prevent the warning, any straight-C code that wants to include windows.h should make an additional define before including:
#ifndef __cplusplus
#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
#endif
#include <windows.h>
2023-08-15 05:39:55 -04:00
Nyq
b0af33a61b
Update miniz_tdef.c to enable compiling in forced-C++ mode
Summary:
Merged definition of static const mz_uint s_tdefl_num_probes[11] with its declaration to avoid compilation error when compiling in forced-C++mode

Details:
When miniz_tdef.c is compiled in C++ mode (either by forcing the compiler to treat the input as C++ or by renaming the file into miniz.cpp), MSVC17 produces the following error:
```
miniz_tdef.cpp(2113,22): error C2086: 'const mz_uint s_tdefl_num_probes[11]': redefinition
miniz_tdef.cpp(1254,22): message : see declaration of 's_tdefl_num_probes'
```
This happens because in miniz_tdef.c we have the following:

```
/*Line 606:*/ static const mz_uint s_tdefl_num_probes[11];
/*Line 1465:*/ static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
```
While miniz_tdef.c is a C source file and not C++, sometimes it is used in C++ projects where settings are such that mixed C/C++ compilation is not allowed and all input source files are treated as forced C++. So there would be no harm to make a small adjustment so that the source code is conformant with both C and C++ requirements.

There are two ways it can be done:
Option 1: change line 606 from `static const mz_uint s_tdefl_num_probes[11];` to `extern const mz_uint s_tdefl_num_probes[11];`
Option2: eliminate line 1465 entirely and move line 2113 into line 1254 so that the code looks like this:
```
/*Line 606:*/ static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
/*Line 1465:*/ //Nothing here
```
Either option works for both C and C++ and really there is no harm in simply moving the full definition up like in option B and avoid duplication.

This change implements option B.
2023-08-15 04:50:07 -04:00
Martin Raiber
9ae305f6e1
Merge pull request #268 from jpcha2/master
Ensure correct integer promotion when adding
2023-04-12 21:10:11 +02:00
Martin Raiber
d9d197c926
Merge pull request #270 from J5lx/mingw32-unicode
Fix Unicode paths on MinGW32
2023-04-12 21:07:54 +02:00
Jakob Gahde
654bf8bdeb
Fix Unicode paths on MinGW32 2023-02-14 07:10:06 +01:00
jpcha2
fe6330e1d8
Update miniz_tinfl.c
Additional parameter checks
2023-01-17 12:25:12 +03:00
jpcha2
f259216256
Merge pull request #1 from jpcha2/jpcha2-patch-1-int64-promotion-order
Update miniz_zip.c
2023-01-17 11:52:16 +03:00
jpcha2
f0709ed3f5
Update miniz_zip.c
Code Quality (Avoid Integer Overflow): Ensure correct order of integer size promotion when doing additions by placing the mz_uint64 value first or explicitly casting the first value to mz_uint64.
2023-01-17 11:49:41 +03:00
Martin Raiber
293d4db1b7
Increment version 2023-01-15 12:55:58 +01:00
Martin Raiber
12680974d1
Increment version 2023-01-15 12:55:30 +01:00
Martin Raiber
ad8dedc1b3
Update ChangeLog.md 2023-01-15 12:52:28 +01:00
Martin Raiber
08c03ff478
Merge pull request #264 from jpcha2/patch-1
Update miniz_zip.c
2023-01-15 12:51:17 +01:00
Fabian Greffrath
2ec92b4852 Fix missing large file support warning on 64-bit Linux
Pragmatic approach: Treat Linux on x86_64 the same as Mac OS X and FreeBSD,
i.e. as a Unix-like 64-bit operating system with know large file support.

Fixes #257
2022-12-14 10:12:10 +01:00
jpcha2
78e9404362
Update miniz_zip.c
Bugfix: MultiByteToWideChar() is being called with a byte count instead of a character count. This will cause a buffer overrun.
2022-11-21 04:36:20 +03:00
Martin Raiber
963a27a112
Increment version 2022-11-06 13:47:54 +01:00
Martin Raiber
2363190ebf
Increment version 2022-11-06 13:47:03 +01:00
Martin Raiber
7265019066
Update changelog 2022-11-06 13:43:12 +01:00
Martin Raiber
83341a5605
Merge pull request #263 from nekonomicon/match_dist
Fix variable declaration.
2022-11-06 13:42:00 +01:00
Martin Raiber
39622ead92
Test compile with MINIZ_USE_UNALIGNED_LOADS_AND_STORES=1 2022-11-06 12:40:00 +01:00
Andrey Akhmichin
ab052e6e58
Fix variable declaration. 2022-11-06 14:55:25 +05:00
36 changed files with 32709 additions and 8245 deletions

View File

@ -44,3 +44,4 @@ SpacesInCStyleCastParentheses: false
SpaceAfterControlStatementKeyword: true SpaceAfterControlStatementKeyword: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
SortIncludes: false

View File

@ -15,3 +15,27 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: amalgamate - name: amalgamate
run: bash amalgamate.sh run: bash amalgamate.sh
- name: Run CMake consuming CMakePreset.json and run tests
uses: lukka/run-cmake@v10
with:
# This is the name of the CMakePresets.json's configuration to use to generate
# the project files. This configuration leverages the vcpkg.cmake toolchain file to
# run vcpkg and install all dependencies specified in vcpkg.json.
configurePreset: 'gcc'
# Additional arguments can be appended to the cmake command.
# This is useful to reduce the number of CMake's Presets since you can reuse
# an existing preset with different variables.
configurePresetAdditionalArgs: "['-DENABLE_YOUR_FEATURE=1']"
# This is the name of the CMakePresets.json's configuration to build the project.
buildPreset: 'gcc'
# Additional arguments can be appended when building, for example to specify the
# configuration to build.
# This is useful to reduce the number of CMake's Presets you need in CMakePresets.json.
buildPresetAdditionalArgs: "['--config Release']"
# This is the name of the CMakePresets.json's configuration to test the project with.
testPreset: 'gcc'
# Additional arguments can be appended when testing, for example to specify the config
# to test.
# This is useful to reduce the number of CMake's Presets you need in CMakePresets.json.
testPresetAdditionalArgs: "[]"

View File

@ -16,7 +16,7 @@ jobs:
fuzz-seconds: 900 fuzz-seconds: 900
dry-run: false dry-run: false
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: artifacts name: artifacts

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.5)
# determine whether this is a standalone project or included by other projects # determine whether this is a standalone project or included by other projects
set (MINIZ_STANDALONE_PROJECT ON) set (MINIZ_STANDALONE_PROJECT ON)
@ -10,7 +10,7 @@ if(CMAKE_MINOR_VERSION LESS 12)
project(miniz) project(miniz)
# see issue https://gitlab.kitware.com/cmake/cmake/merge_requests/1799 # see issue https://gitlab.kitware.com/cmake/cmake/merge_requests/1799
else() else()
project(miniz C) project(miniz)
set(CMAKE_C_STANDARD 90) set(CMAKE_C_STANDARD 90)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
# set(CMAKE_C_VISIBILITY_PRESET hidden) # set(CMAKE_C_VISIBILITY_PRESET hidden)
@ -25,7 +25,7 @@ endif()
set(MINIZ_API_VERSION 3) set(MINIZ_API_VERSION 3)
set(MINIZ_MINOR_VERSION 0) set(MINIZ_MINOR_VERSION 0)
set(MINIZ_PATCH_VERSION 0) set(MINIZ_PATCH_VERSION 2)
set(MINIZ_VERSION set(MINIZ_VERSION
${MINIZ_API_VERSION}.${MINIZ_MINOR_VERSION}.${MINIZ_PATCH_VERSION}) ${MINIZ_API_VERSION}.${MINIZ_MINOR_VERSION}.${MINIZ_PATCH_VERSION})
@ -42,6 +42,8 @@ option(BUILD_FUZZERS "Build fuzz targets" OFF)
option(AMALGAMATE_SOURCES "Amalgamate sources into miniz.h/c" OFF) option(AMALGAMATE_SOURCES "Amalgamate sources into miniz.h/c" OFF)
option(BUILD_HEADER_ONLY "Build a header-only version" OFF) option(BUILD_HEADER_ONLY "Build a header-only version" OFF)
option(BUILD_SHARED_LIBS "Build shared library instead of static" OFF) option(BUILD_SHARED_LIBS "Build shared library instead of static" OFF)
option(BUILD_NO_STDIO" Build a without stdio version" OFF)
option(BUILD_TESTS "Build tests" ${MINIZ_STANDALONE_PROJECT})
option(INSTALL_PROJECT "Install project" ${MINIZ_STANDALONE_PROJECT}) option(INSTALL_PROJECT "Install project" ${MINIZ_STANDALONE_PROJECT})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
@ -177,6 +179,10 @@ if(NOT BUILD_HEADER_ONLY)
endif() endif()
endif() endif()
if(BUILD_NO_STDIO)
target_compile_definitions(${PROJECT_NAME} PRIVATE MINIZ_NO_STDIO)
endif()
set_property(TARGET ${PROJECT_NAME} PROPERTY set_property(TARGET ${PROJECT_NAME} PROPERTY
INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${MINIZ_API_VERSION}) INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${MINIZ_API_VERSION})
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY
@ -241,8 +247,10 @@ if(BUILD_EXAMPLES)
add_executable(example1 ${EXAMPLE1_SRC_LIST}) add_executable(example1 ${EXAMPLE1_SRC_LIST})
target_link_libraries(example1 miniz) target_link_libraries(example1 miniz)
if(NOT BUILD_NO_STDIO)
add_executable(example2 ${EXAMPLE2_SRC_LIST}) add_executable(example2 ${EXAMPLE2_SRC_LIST})
target_link_libraries(example2 miniz) target_link_libraries(example2 miniz)
endif()
add_executable(example3 ${EXAMPLE3_SRC_LIST}) add_executable(example3 ${EXAMPLE3_SRC_LIST})
target_link_libraries(example3 miniz) target_link_libraries(example3 miniz)
add_executable(example4 ${EXAMPLE4_SRC_LIST}) add_executable(example4 ${EXAMPLE4_SRC_LIST})
@ -270,6 +278,7 @@ if(BUILD_FUZZERS)
set(SMALL_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/small_fuzzer.c") set(SMALL_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/small_fuzzer.c")
set(LARGE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/large_fuzzer.c") set(LARGE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/large_fuzzer.c")
set(ZIP_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/zip_fuzzer.c") set(ZIP_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/zip_fuzzer.c")
set(ADD_IN_PLACE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/add_in_place_fuzzer.c")
add_executable(checksum_fuzzer ${CHECKSUM_FUZZER_SRC_LIST}) add_executable(checksum_fuzzer ${CHECKSUM_FUZZER_SRC_LIST})
target_link_libraries(checksum_fuzzer miniz) target_link_libraries(checksum_fuzzer miniz)
@ -294,6 +303,24 @@ if(BUILD_FUZZERS)
add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST}) add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST})
target_link_libraries(zip_fuzzer miniz) target_link_libraries(zip_fuzzer miniz)
add_executable(add_in_place_fuzzer ${ADD_IN_PLACE_FUZZER_SRC_LIST})
target_link_libraries(add_in_place_fuzzer miniz)
endif()
if(BUILD_TESTS)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
add_executable(catch_tests tests/main.cpp tests/catch_amalgamated.cpp)
if(BUILD_NO_STDIO)
target_compile_definitions(catch_tests PRIVATE -DMINIZ_NO_STDIO)
endif()
target_link_libraries(catch_tests miniz)
enable_testing()
add_test(NAME catch_tests COMMAND $<TARGET_FILE:catch_tests>)
endif() endif()
set(INCLUDE_INSTALL_DIR "include") set(INCLUDE_INSTALL_DIR "include")

31
CMakePresets.json Normal file
View File

@ -0,0 +1,31 @@
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 5,
"patch": 0
},
"configurePresets": [
{
"name": "gcc",
"displayName": "GCC",
"description": "Default build options for GCC",
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/build"
}
],
"buildPresets": [
{
"name": "gcc",
"configurePreset": "gcc"
}
],
"testPresets": [
{
"name": "gcc",
"configurePreset": "gcc",
"output": {"outputOnFailure": true},
"execution": {"noTestsAction": "error", "stopOnFailure": true}
}
]
}

View File

@ -1,5 +1,13 @@
## Changelog ## Changelog
### 3.0.2
- Fix buffer overrun in mz_utf8z_to_widechar on Windows
### 3.0.1
- Fix compilation error with MINIZ_USE_UNALIGNED_LOADS_AND_STORES=1
### 3.0.0 ### 3.0.0
- Reduce memory usage for inflate. This changes `struct tinfl_decompressor_tag` and therefore requires a major version bump (breaks ABI compatibility) - Reduce memory usage for inflate. This changes `struct tinfl_decompressor_tag` and therefore requires a major version bump (breaks ABI compatibility)

View File

@ -23,6 +23,8 @@ do
echo "Test compile with GCC and define $def..." echo "Test compile with GCC and define $def..."
gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out -D${def} gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out -D${def}
done done
echo "Test compile with GCC and MINIZ_USE_UNALIGNED_LOADS_AND_STORES=1..."
gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out -DMINIZ_USE_UNALIGNED_LOADS_AND_STORES=1
rm test.out rm test.out
rm main.c rm main.c

View File

@ -7,12 +7,12 @@ typedef unsigned short uint16;
typedef unsigned int uint; typedef unsigned int uint;
// The string to compress. // The string to compress.
static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."; "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -21,12 +21,12 @@ typedef unsigned int uint;
// The string to compress. // The string to compress.
static const char *s_pTest_str = static const char *s_pTest_str =
"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \ "MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and"
"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \ "if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it"
"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \ "actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be"
"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \ "guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as"
"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \ "the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas."
"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \ "No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any"
"event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded."; "event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded.";
static const char *s_pComment = "This is a comment"; static const char *s_pComment = "This is a comment";

View File

@ -29,12 +29,17 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
const int saturation = 1; const int saturation = 1;
const int color_rotate = 0; const int color_rotate = 0;
if (min == max) max = min + 1; if (min == max)
if (invert) hue = max - (hue - min); max = min + 1;
if (!saturation) { if (invert)
hue = max - (hue - min);
if (!saturation)
{
p->r = p->g = p->b = 255 * (max - hue) / (max - min); p->r = p->g = p->b = 255 * (max - hue) / (max - min);
return; return;
} else { }
else
{
const double h_dbl = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6); const double h_dbl = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
const double c_dbl = 255 * saturation; const double c_dbl = 255 * saturation;
const double X_dbl = c_dbl * (1 - fabs(fmod(h_dbl, 2) - 1)); const double X_dbl = c_dbl * (1 - fabs(fmod(h_dbl, 2) - 1));
@ -44,13 +49,31 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
p->r = p->g = p->b = 0; p->r = p->g = p->b = 0;
switch(h) { switch (h)
case 0: p->r = c; p->g = X; return; {
case 1: p->r = X; p->g = c; return; case 0:
case 2: p->g = c; p->b = X; return; p->r = c;
case 3: p->g = X; p->b = c; return; p->g = X;
case 4: p->r = X; p->b = c; return; return;
default:p->r = c; p->b = X; case 1:
p->r = X;
p->g = c;
return;
case 2:
p->g = c;
p->b = X;
return;
case 3:
p->g = X;
p->b = c;
return;
case 4:
p->r = X;
p->b = c;
return;
default:
p->r = c;
p->b = X;
} }
} }
} }

View File

@ -31,7 +31,8 @@ typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- zlib-style API's */ /* ------------------- zlib-style API's */
@ -93,8 +94,7 @@ mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
*/ */
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
{ {
static const mz_uint32 s_crc_table[256] = static const mz_uint32 s_crc_table[256] = {
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
@ -602,8 +602,7 @@ const char *mz_error(int err)
{ {
int m_err; int m_err;
const char *m_pDesc; const char *m_pDesc;
} s_error_descs[] = } s_error_descs[] = {
{
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
}; };
mz_uint i; mz_uint i;

125
miniz.h
View File

@ -1,4 +1,4 @@
/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing /* miniz.c 3.0.2 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
See "unlicense" statement at the end of this file. See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013 Rich Geldreich <richgel99@gmail.com>, 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 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
@ -223,7 +223,8 @@
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- zlib-style API Definitions. */ /* ------------------- zlib-style API Definitions. */
@ -272,10 +273,10 @@ enum
MZ_DEFAULT_COMPRESSION = -1 MZ_DEFAULT_COMPRESSION = -1
}; };
#define MZ_VERSION "11.0.0" #define MZ_VERSION "11.0.2"
#define MZ_VERNUM 0xB000 #define MZ_VERNUM 0xB002
#define MZ_VER_MAJOR 11 #define MZ_VER_MAJOR 11
#define MZ_VER_MINOR 0 #define MZ_VER_MINOR 2
#define MZ_VER_REVISION 0 #define MZ_VER_REVISION 0
#define MZ_VER_SUBREVISION 0 #define MZ_VER_SUBREVISION 0
@ -478,44 +479,116 @@ typedef void *const voidpc;
#define Z_FIXED MZ_FIXED #define Z_FIXED MZ_FIXED
#define Z_DEFLATED MZ_DEFLATED #define Z_DEFLATED MZ_DEFLATED
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
#define alloc_func mz_alloc_func /* See mz_alloc_func */
#define free_func mz_free_func typedef void *(*alloc_func)(void *opaque, size_t items, size_t size);
/* See mz_free_func */
typedef void (*free_func)(void *opaque, void *address);
#define internal_state mz_internal_state #define internal_state mz_internal_state
#define z_stream mz_stream #define z_stream mz_stream
#ifndef MINIZ_NO_DEFLATE_APIS #ifndef MINIZ_NO_DEFLATE_APIS
#define deflateInit mz_deflateInit /* Compatiblity with zlib API. See called functions for documentation */
#define deflateInit2 mz_deflateInit2 static int deflateInit(mz_streamp pStream, int level)
#define deflateReset mz_deflateReset {
#define deflate mz_deflate return mz_deflateInit(pStream, level);
#define deflateEnd mz_deflateEnd }
#define deflateBound mz_deflateBound static int deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
#define compress mz_compress {
#define compress2 mz_compress2 return mz_deflateInit2(pStream, level, method, window_bits, mem_level, strategy);
#define compressBound mz_compressBound }
static int deflateReset(mz_streamp pStream)
{
return mz_deflateReset(pStream);
}
static int deflate(mz_streamp pStream, int flush)
{
return mz_deflate(pStream, flush);
}
static int deflateEnd(mz_streamp pStream)
{
return mz_deflateEnd(pStream);
}
static mz_ulong deflateBound(mz_streamp pStream, mz_ulong source_len)
{
return mz_deflateBound(pStream, source_len);
}
static int compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
return mz_compress(pDest, pDest_len, pSource, source_len);
}
static int compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
{
return mz_compress2(pDest, pDest_len, pSource, source_len, level);
}
static mz_ulong compressBound(mz_ulong source_len)
{
return mz_compressBound(source_len);
}
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ #endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
#ifndef MINIZ_NO_INFLATE_APIS #ifndef MINIZ_NO_INFLATE_APIS
#define inflateInit mz_inflateInit /* Compatiblity with zlib API. See called functions for documentation */
#define inflateInit2 mz_inflateInit2 static int inflateInit(mz_streamp pStream)
#define inflateReset mz_inflateReset {
#define inflate mz_inflate return mz_inflateInit(pStream);
#define inflateEnd mz_inflateEnd }
#define uncompress mz_uncompress
#define uncompress2 mz_uncompress2 static int inflateInit2(mz_streamp pStream, int window_bits)
{
return mz_inflateInit2(pStream, window_bits);
}
static int inflateReset(mz_streamp pStream)
{
return mz_inflateReset(pStream);
}
static int inflate(mz_streamp pStream, int flush)
{
return mz_inflate(pStream, flush);
}
static int inflateEnd(mz_streamp pStream)
{
return mz_inflateEnd(pStream);
}
static int uncompress(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong source_len)
{
return mz_uncompress(pDest, pDest_len, pSource, source_len);
}
static int uncompress2(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong* pSource_len)
{
return mz_uncompress2(pDest, pDest_len, pSource, pSource_len);
}
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ #endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
#define crc32 mz_crc32 static mz_ulong crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len)
#define adler32 mz_adler32 {
return mz_crc32(crc, ptr, buf_len);
}
static mz_ulong adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
{
return mz_adler32(adler, ptr, buf_len);
}
#define MAX_WBITS 15 #define MAX_WBITS 15
#define MAX_MEM_LEVEL 9 #define MAX_MEM_LEVEL 9
#define zError mz_error
static const char* zError(int err)
{
return mz_error(err);
}
#define ZLIB_VERSION MZ_VERSION #define ZLIB_VERSION MZ_VERSION
#define ZLIB_VERNUM MZ_VERNUM #define ZLIB_VERNUM MZ_VERNUM
#define ZLIB_VER_MAJOR MZ_VER_MAJOR #define ZLIB_VER_MAJOR MZ_VER_MAJOR
#define ZLIB_VER_MINOR MZ_VER_MINOR #define ZLIB_VER_MINOR MZ_VER_MINOR
#define ZLIB_VER_REVISION MZ_VER_REVISION #define ZLIB_VER_REVISION MZ_VER_REVISION
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
#define zlibVersion mz_version #define zlibVersion mz_version
#define zlib_version mz_version() #define zlib_version mz_version()
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ #endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */

View File

@ -8,10 +8,10 @@
/* ------------------- Types and macros */ /* ------------------- Types and macros */
typedef unsigned char mz_uint8; typedef unsigned char mz_uint8;
typedef signed short mz_int16; typedef int16_t mz_int16;
typedef unsigned short mz_uint16; typedef uint16_t mz_uint16;
typedef unsigned int mz_uint32; typedef uint32_t mz_uint32;
typedef unsigned int mz_uint; typedef uint32_t mz_uint;
typedef int64_t mz_int64; typedef int64_t mz_int64;
typedef uint64_t mz_uint64; typedef uint64_t mz_uint64;
typedef int mz_bool; typedef int mz_bool;
@ -81,7 +81,8 @@ typedef struct mz_dummy_time_t_tag
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size); extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);

View File

@ -29,14 +29,14 @@
#ifndef MINIZ_NO_DEFLATE_APIS #ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- Low-level Compression (independent from all decompression API's) */ /* ------------------- Low-level Compression (independent from all decompression API's) */
/* Purposely making these tables static for faster init and thread safety. */ /* Purposely making these tables static for faster init and thread safety. */
static const mz_uint16 s_tdefl_len_sym[256] = static const mz_uint16 s_tdefl_len_sym[256] = {
{
257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
@ -47,16 +47,14 @@ static const mz_uint16 s_tdefl_len_sym[256] =
284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
}; };
static const mz_uint8 s_tdefl_len_extra[256] = static const mz_uint8 s_tdefl_len_extra[256] = {
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
}; };
static const mz_uint8 s_tdefl_small_dist_sym[512] = static const mz_uint8 s_tdefl_small_dist_sym[512] = {
{
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
@ -71,8 +69,7 @@ static const mz_uint8 s_tdefl_small_dist_sym[512] =
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
}; };
static const mz_uint8 s_tdefl_small_dist_extra[512] = static const mz_uint8 s_tdefl_small_dist_extra[512] = {
{
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
@ -83,15 +80,13 @@ static const mz_uint8 s_tdefl_small_dist_extra[512] =
7, 7, 7, 7, 7, 7, 7, 7 7, 7, 7, 7, 7, 7, 7, 7
}; };
static const mz_uint8 s_tdefl_large_dist_sym[128] = static const mz_uint8 s_tdefl_large_dist_sym[128] = {
{
0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
}; };
static const mz_uint8 s_tdefl_large_dist_extra[128] = static const mz_uint8 s_tdefl_large_dist_extra[128] = {
{
0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
@ -476,7 +471,7 @@ static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
{ {
mz_uint s0, s1, n0, n1, sym, num_extra_bits; mz_uint s0, s1, n0, n1, sym, num_extra_bits;
mz_uint match_len = pLZ_codes[0]; mz_uint match_len = pLZ_codes[0];
match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
pLZ_codes += 3; pLZ_codes += 3;
MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
@ -603,7 +598,7 @@ static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
return tdefl_compress_lz_codes(d); return tdefl_compress_lz_codes(d);
} }
static const mz_uint s_tdefl_num_probes[11]; 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) static int tdefl_flush_block(tdefl_compressor *d, int flush)
{ {
@ -631,7 +626,8 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush)
/* Determine compression level by reversing the process in tdefl_create_comp_flags_from_zip_params() */ /* Determine compression level by reversing the process in tdefl_create_comp_flags_from_zip_params() */
for (i = 0; i < mz_un; i++) for (i = 0; i < mz_un; i++)
if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF)) break; if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF))
break;
if (i < 2) if (i < 2)
flevel = 0; flevel = 0;
@ -1462,8 +1458,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
return out_buf.m_size; 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). */ /* 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) mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
{ {

View File

@ -4,12 +4,15 @@
#ifndef MINIZ_NO_DEFLATE_APIS #ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- Low-level Compression API Definitions */ /* ------------------- Low-level Compression API Definitions */
/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */ /* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */
#ifndef TDEFL_LESS_MEMORY
#define TDEFL_LESS_MEMORY 0 #define TDEFL_LESS_MEMORY 0
#endif
/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */ /* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */
/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */ /* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */
@ -103,7 +106,7 @@ enum
enum enum
{ {
TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, TDEFL_OUT_BUF_SIZE = (mz_uint)((TDEFL_LZ_CODE_BUF_SIZE * 13) / 10),
TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_MAX_HUFF_SYMBOLS = 288,
TDEFL_LZ_HASH_BITS = 15, TDEFL_LZ_HASH_BITS = 15,
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
@ -113,7 +116,8 @@ enum
#endif #endif
/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */ /* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
typedef enum { typedef enum
{
TDEFL_STATUS_BAD_PARAM = -2, TDEFL_STATUS_BAD_PARAM = -2,
TDEFL_STATUS_PUT_BUF_FAILED = -1, TDEFL_STATUS_PUT_BUF_FAILED = -1,
TDEFL_STATUS_OKAY = 0, TDEFL_STATUS_OKAY = 0,
@ -121,7 +125,8 @@ typedef enum {
} tdefl_status; } tdefl_status;
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */ /* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
typedef enum { typedef enum
{
TDEFL_NO_FLUSH = 0, TDEFL_NO_FLUSH = 0,
TDEFL_SYNC_FLUSH = 2, TDEFL_SYNC_FLUSH = 2,
TDEFL_FULL_FLUSH = 3, TDEFL_FULL_FLUSH = 3,

View File

@ -29,7 +29,8 @@
#ifndef MINIZ_NO_INFLATE_APIS #ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- Low-level Decompression (completely independent from all compression API's) */ /* ------------------- Low-level Decompression (completely independent from all compression API's) */
@ -490,6 +491,12 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
bit_buf >>= code_len; bit_buf >>= code_len;
num_bits -= code_len; num_bits -= code_len;
/* assert(sym2 != 0 && counter != 0); */
if (sym2 == 0 && counter == 0)
{
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
}
pOut_buf_cur[0] = (mz_uint8)counter; pOut_buf_cur[0] = (mz_uint8)counter;
if (sym2 & 256) if (sym2 & 256)
{ {

View File

@ -5,7 +5,8 @@
#ifndef MINIZ_NO_INFLATE_APIS #ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* Decompression flags used by tinfl_decompress(). */ /* Decompression flags used by tinfl_decompress(). */
/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */ /* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */
@ -55,7 +56,8 @@ MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
#define TINFL_LZ_DICT_SIZE 32768 #define TINFL_LZ_DICT_SIZE 32768
/* Return status. */ /* Return status. */
typedef enum { typedef enum
{
/* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */ /* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
/* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */ /* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */ /* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */

View File

@ -29,7 +29,8 @@
#ifndef MINIZ_NO_ARCHIVE_APIS #ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* ------------------- .ZIP archive reading */ /* ------------------- .ZIP archive reading */
@ -39,16 +40,24 @@ extern "C" {
#else #else
#include <sys/stat.h> #include <sys/stat.h>
#if defined(_MSC_VER) || defined(__MINGW64__) #if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif
#ifndef __cplusplus
#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h> #include <windows.h>
static WCHAR *mz_utf8z_to_widechar(const char *str) static WCHAR *mz_utf8z_to_widechar(const char *str)
{ {
int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR)); WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR));
MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, sizeof(WCHAR) * reqChars); MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
return wStr; return wStr;
} }
@ -74,6 +83,15 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
return err ? NULL : pFile; return err ? NULL : pFile;
} }
#if defined(__MINGW32__)
static int mz_stat(const char *path, struct _stat *buffer)
{
WCHAR *wPath = mz_utf8z_to_widechar(path);
int res = _wstat(wPath, buffer);
free(wPath);
return res;
}
#else
static int mz_stat64(const char *path, struct __stat64 *buffer) static int mz_stat64(const char *path, struct __stat64 *buffer)
{ {
WCHAR *wPath = mz_utf8z_to_widechar(path); WCHAR *wPath = mz_utf8z_to_widechar(path);
@ -81,6 +99,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
free(wPath); free(wPath);
return res; return res;
} }
#endif
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME
#include <sys/utime.h> #include <sys/utime.h>
@ -91,13 +110,18 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
#define MZ_FWRITE fwrite #define MZ_FWRITE fwrite
#define MZ_FTELL64 _ftelli64 #define MZ_FTELL64 _ftelli64
#define MZ_FSEEK64 _fseeki64 #define MZ_FSEEK64 _fseeki64
#if defined(__MINGW32__)
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT mz_stat
#else
#define MZ_FILE_STAT_STRUCT _stat64 #define MZ_FILE_STAT_STRUCT _stat64
#define MZ_FILE_STAT mz_stat64 #define MZ_FILE_STAT mz_stat64
#endif
#define MZ_FFLUSH fflush #define MZ_FFLUSH fflush
#define MZ_FREOPEN mz_freopen #define MZ_FREOPEN mz_freopen
#define MZ_DELETE_FILE remove #define MZ_DELETE_FILE remove
#elif defined(__MINGW32__) || defined(__WATCOMC__) #elif defined(__WATCOMC__)
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME
#include <sys/utime.h> #include <sys/utime.h>
#endif #endif
@ -145,7 +169,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer)
#define MZ_FREOPEN(p, m, s) freopen64(p, m, s) #define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
#define MZ_DELETE_FILE remove #define MZ_DELETE_FILE remove
#elif defined(__APPLE__) || defined(__FreeBSD__) #elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__linux__) && defined(__x86_64__))
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME
#include <utime.h> #include <utime.h>
#endif #endif
@ -613,7 +637,7 @@ static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 r
} }
/* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */ /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size))) if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
return MZ_FALSE; return MZ_FALSE;
cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
@ -623,10 +647,23 @@ static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 r
return MZ_TRUE; return MZ_TRUE;
} }
static mz_bool mz_zip_reader_eocd64_valid(mz_zip_archive *pZip, uint64_t offset, uint8_t *buf)
{
if (pZip->m_pRead(pZip->m_pIO_opaque, offset, buf, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
{
if (MZ_READ_LE32(buf + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
{
return MZ_TRUE;
}
}
return MZ_FALSE;
}
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags) static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
{ {
mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0; mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
mz_uint64 cdir_ofs = 0; mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
mz_int64 cur_file_ofs = 0; mz_int64 cur_file_ofs = 0;
const mz_uint8 *p; const mz_uint8 *p;
@ -648,6 +685,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs)) if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR); return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
eocd_ofs = cur_file_ofs;
/* Read and verify the end of central directory record. */ /* Read and verify the end of central directory record. */
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
@ -660,19 +698,38 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
{ {
if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG)
{
zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
{
if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
{ {
pZip->m_pState->m_zip64 = MZ_TRUE; pZip->m_pState->m_zip64 = MZ_TRUE;
} }
} }
} }
if (pZip->m_pState->m_zip64)
{
/* Try locating the EOCD64 right before the EOCD64 locator. This works even
* when the effective start of the zip header is not yet known. */
if (cur_file_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
zip64_end_of_central_dir_ofs = cur_file_ofs -
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE -
MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
pZip64_end_of_central_dir))
{
/* That failed, try reading where the locator tells us to. */
zip64_end_of_central_dir_ofs = MZ_READ_LE64(
pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
if (zip64_end_of_central_dir_ofs >
(pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
pZip64_end_of_central_dir))
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
} }
} }
@ -733,6 +790,30 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
if (eocd_ofs < cdir_ofs + cdir_size)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
/* The end of central dir follows the central dir, unless the zip file has
* some trailing data (e.g. it is appended to an executable file). */
archive_ofs = eocd_ofs - (cdir_ofs + cdir_size);
if (pZip->m_pState->m_zip64)
{
if (archive_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
archive_ofs -= MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
}
/* Update the archive start position, but only if not specified. */
if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE || pZip->m_zip_type == MZ_ZIP_TYPE_CFILE ||
pZip->m_zip_type == MZ_ZIP_TYPE_USER) && pZip->m_pState->m_file_archive_start_ofs == 0)
{
pZip->m_pState->m_file_archive_start_ofs = archive_ofs;
pZip->m_archive_size -= archive_ofs;
}
pZip->m_central_directory_file_ofs = cdir_ofs; pZip->m_central_directory_file_ofs = cdir_ofs;
if (pZip->m_total_files) if (pZip->m_total_files)
@ -1021,7 +1102,7 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename,
if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
pFile = MZ_FOPEN(pFilename, "rb"); pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ? "r+b" : "rb");
if (!pFile) if (!pFile)
return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
@ -1460,8 +1541,7 @@ 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); return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
} }
static 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)
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; 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; mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
@ -1474,10 +1554,11 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc1(mz_zip_archive *pZip, mz_uint fil
if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead)) 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); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
if (st) { if (st)
{
file_stat = *st; file_stat = *st;
} else }
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE; return MZ_FALSE;
/* A directory or zero length file */ /* A directory or zero length file */
@ -1505,7 +1586,7 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc1(mz_zip_archive *pZip, mz_uint fil
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -1717,7 +1798,7 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_ind
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -1959,7 +2040,7 @@ mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive
return NULL; return NULL;
} }
pState->cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); pState->cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size) if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
{ {
mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -2943,7 +3024,8 @@ mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFil
if (pZip->m_pIO_opaque != pZip) if (pZip->m_pIO_opaque != pZip)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
!(flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING) )
{ {
if (!pFilename) if (!pFilename)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
@ -3251,6 +3333,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
time(&cur_time); time(&cur_time);
mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
} }
#else
(void)last_modified;
#endif /* #ifndef MINIZ_NO_TIME */ #endif /* #ifndef MINIZ_NO_TIME */
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
@ -3277,10 +3361,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
if (!pState->m_zip64) if (!pState->m_zip64)
{ {
/* Bail early if the archive would obviously become too large */ /* 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 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 +
+ 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)
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)
{ {
pState->m_zip64 = MZ_TRUE; pState->m_zip64 = MZ_TRUE;
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
@ -3538,9 +3620,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
if (!pState->m_zip64) if (!pState->m_zip64)
{ {
/* Bail early if the archive would obviously become too large */ /* 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 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 + 1024 + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
+ archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
{ {
pState->m_zip64 = MZ_TRUE; pState->m_zip64 = MZ_TRUE;
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
@ -3552,6 +3632,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
{ {
mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date); mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
} }
#else
(void)pFile_time;
#endif #endif
if (max_size <= 3) if (max_size <= 3)
@ -4037,7 +4119,7 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *
local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size; src_archive_bytes_remaining = src_file_stat.m_comp_size + local_header_filename_size + local_header_extra_len;
/* Try to find a zip64 extended information field */ /* Try to find a zip64 extended information field */
if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX))) if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
@ -4487,14 +4569,14 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, co
else else
{ {
/* Append to an existing archive. */ /* Append to an existing archive. */
if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY | MZ_ZIP_FLAG_READ_ALLOW_WRITING, 0, 0))
{ {
if (pErr) if (pErr)
*pErr = zip_archive.m_last_error; *pErr = zip_archive.m_last_error;
return MZ_FALSE; return MZ_FALSE;
} }
if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags)) if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_READ_ALLOW_WRITING))
{ {
if (pErr) if (pErr)
*pErr = zip_archive.m_last_error; *pErr = zip_archive.m_last_error;

View File

@ -7,7 +7,8 @@
#ifndef MINIZ_NO_ARCHIVE_APIS #ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
enum enum
@ -82,14 +83,16 @@ typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
struct mz_zip_internal_state_tag; struct mz_zip_internal_state_tag;
typedef struct mz_zip_internal_state_tag mz_zip_internal_state; typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
typedef enum { typedef enum
{
MZ_ZIP_MODE_INVALID = 0, MZ_ZIP_MODE_INVALID = 0,
MZ_ZIP_MODE_READING = 1, MZ_ZIP_MODE_READING = 1,
MZ_ZIP_MODE_WRITING = 2, MZ_ZIP_MODE_WRITING = 2,
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
} mz_zip_mode; } mz_zip_mode;
typedef enum { typedef enum
{
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
@ -101,10 +104,12 @@ typedef enum {
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000, MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
/*After adding a compressed file, seek back /*After adding a compressed file, seek back
to local file header and set the correct sizes*/ to local file header and set the correct sizes*/
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000 MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000,
MZ_ZIP_FLAG_READ_ALLOW_WRITING = 0x40000
} mz_zip_flags; } mz_zip_flags;
typedef enum { typedef enum
{
MZ_ZIP_TYPE_INVALID = 0, MZ_ZIP_TYPE_INVALID = 0,
MZ_ZIP_TYPE_USER, MZ_ZIP_TYPE_USER,
MZ_ZIP_TYPE_MEMORY, MZ_ZIP_TYPE_MEMORY,
@ -115,7 +120,8 @@ typedef enum {
} mz_zip_type; } mz_zip_type;
/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */ /* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
typedef enum { typedef enum
{
MZ_ZIP_NO_ERROR = 0, MZ_ZIP_NO_ERROR = 0,
MZ_ZIP_UNDEFINED_ERROR, MZ_ZIP_UNDEFINED_ERROR,
MZ_ZIP_TOO_MANY_FILES, MZ_ZIP_TOO_MANY_FILES,
@ -394,7 +400,6 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, c
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 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); const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#ifndef MINIZ_NO_STDIO #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. */ /* 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. */ /* 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. */

View File

@ -0,0 +1,87 @@
#include <stdio.h>
#include <limits.h>
#include "miniz.h"
static const mz_uint files_count = 5;
static const mz_uint max_file_size = 1024 * 1024;
static const char *zip_file_name = "/tmp/miniz-fuzzer-test.zip";
/* Read 32-bit integer from the fuzzer input with range [0, max] */
static mz_uint read_uint32(const mz_uint8 **data, size_t *size, mz_uint max)
{
mz_uint value = 0;
if (*size >= sizeof(mz_uint))
{
memcpy(&value, *data, sizeof(mz_uint));
*data += sizeof(mz_uint);
*size -= sizeof(mz_uint);
value = MZ_MIN(max == UINT_MAX ? value : value % (max + 1), *size);
}
return value;
}
/* Read random-length null terminated string from the fuzzer input */
static mz_bool read_string(const mz_uint8 **data, size_t *size, char *destination, mz_uint max_len)
{
mz_uint filename_len = read_uint32(data, size, max_len - 1);
memcpy(destination, *data, filename_len);
destination[filename_len] = 0;
*data += filename_len;
*size -= filename_len;
return filename_len > 0;
}
/* Get random-length buffer from the fuzzer input */
static mz_bool read_buffer(const mz_uint8 **data, size_t *size, const mz_uint8 **destination, mz_uint *len)
{
*len = read_uint32(data, size, max_file_size);
*destination = *data;
*data += *len;
*size -= *len;
return *len > 0;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
mz_uint i;
char archive_file_name[FILENAME_MAX];
const mz_uint8 *file_data;
mz_uint file_length, flags;
size_t extracted_size;
mz_uint8 *extracted_data;
const char *comment = mz_version();
/* Remove the temporary file for better reproducibility */
remove(zip_file_name);
for (i = 0; i < files_count; ++i)
{
/* Fill archive file name */
if (!read_string(&data, &size, archive_file_name, sizeof(archive_file_name)))
{
break;
}
/* Prepare file's content */
if (!read_buffer(&data, &size, &file_data, &file_length))
{
break;
}
/* Prepare flags for adding file */
flags = read_uint32(&data, &size, UINT_MAX);
mz_zip_add_mem_to_archive_file_in_place(zip_file_name, archive_file_name, file_data, file_length, comment,
(mz_uint16)strlen(comment), flags);
/* Prepare flags for extracting file */
flags = read_uint32(&data, &size, UINT_MAX);
extracted_data = mz_zip_extract_archive_file_to_heap(zip_file_name, archive_file_name, &extracted_size, flags);
free(extracted_data);
}
remove(zip_file_name);
return 0;
}

10795
tests/catch_amalgamated.cpp Normal file

File diff suppressed because it is too large Load Diff

13143
tests/catch_amalgamated.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,8 @@ static const size_t kMaxSize = 1024 * 1024;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen)
{ {
/* Discard inputs larger than 1Mb. */ /* Discard inputs larger than 1Mb. */
if (dataLen < 1 || dataLen > kMaxSize) return 0; if (dataLen < 1 || dataLen > kMaxSize)
return 0;
uint32_t crc = crc32(0L, NULL, 0); uint32_t crc = crc32(0L, NULL, 0);
uint32_t adler = adler32(0L, NULL, 0); uint32_t adler = adler32(0L, NULL, 0);

View File

@ -26,7 +26,10 @@ static void check_compress_level(uint8_t *compr, size_t comprLen,
assert(0 == memcmp(data, uncompr, dataLen)); assert(0 == memcmp(data, uncompr, dataLen));
} }
#define put_byte(s, i, c) {s[i] = (unsigned char)(c);} #define put_byte(s, i, c) \
{ \
s[i] = (unsigned char)(c); \
}
static void write_zlib_header(uint8_t *s) static void write_zlib_header(uint8_t *s)
{ {

View File

@ -11,8 +11,10 @@
#include "miniz.h" #include "miniz.h"
#define CHECK_ERR(err, msg) { \ #define CHECK_ERR(err, msg) \
if (err != Z_OK) { \ { \
if (err != Z_OK) \
{ \
fprintf(stderr, "%s error: %d\n", msg, err); \ fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \ exit(1); \
} \ } \
@ -23,7 +25,6 @@ static size_t dataLen;
static alloc_func zalloc = NULL; static alloc_func zalloc = NULL;
static free_func zfree = NULL; static free_func zfree = NULL;
void test_flush(unsigned char *compr, size_t *comprLen) void test_flush(unsigned char *compr, size_t *comprLen)
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */

View File

@ -30,7 +30,8 @@ int main(int argc, char **argv)
siz_buf = ftell(f); siz_buf = ftell(f);
rewind(f); rewind(f);
if(siz_buf < 1) goto err; if (siz_buf < 1)
goto err;
buf = (char *)malloc(siz_buf); buf = (char *)malloc(siz_buf);
if (buf == NULL) if (buf == NULL)

View File

@ -11,8 +11,10 @@
#include "miniz.h" #include "miniz.h"
#define CHECK_ERR(err, msg) { \ #define CHECK_ERR(err, msg) \
if (err != Z_OK) { \ { \
if (err != Z_OK) \
{ \
fprintf(stderr, "%s error: %d\n", msg, err); \ fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \ exit(1); \
} \ } \
@ -94,7 +96,8 @@ void test_large_inflate(unsigned char *compr, size_t comprLen,
d_stream.next_out = uncompr; /* discard the output */ d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (unsigned int)uncomprLen; d_stream.avail_out = (unsigned int)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break; if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "large inflate"); CHECK_ERR(err, "large inflate");
} }

131
tests/main.cpp Normal file
View File

@ -0,0 +1,131 @@
#include "catch_amalgamated.hpp"
#include "../miniz.h"
#include <assert.h>
#include <string>
#ifdef _WIN32
#define unlink _unlink
#else
#include <unistd.h>
#endif
#ifndef MINIZ_NO_STDIO
bool create_test_zip()
{
unlink("test.zip");
mz_zip_archive zip_archive = {};
auto b = mz_zip_writer_init_file(&zip_archive, "test.zip", 0);
if (!b)
return false;
b = mz_zip_writer_add_mem(&zip_archive, "test.txt", "foo", 3, MZ_DEFAULT_COMPRESSION);
if (!b)
return false;
b = mz_zip_writer_finalize_archive(&zip_archive);
if (!b)
return false;
b = mz_zip_writer_end(&zip_archive);
if (!b)
return false;
return true;
}
TEST_CASE("Zip writer tests")
{
auto b = create_test_zip();
REQUIRE(b);
SECTION("Test test.txt content correct")
{
mz_zip_archive zip_archive = {};
auto b = mz_zip_reader_init_file(&zip_archive, "test.zip", 0);
REQUIRE(b);
size_t content_size;
auto content = mz_zip_reader_extract_file_to_heap(&zip_archive, "test.txt", &content_size, 0);
std::string_view content_view(reinterpret_cast<char *>(content), content_size);
REQUIRE(content_view == "foo");
REQUIRE(content_view.size() == 3);
free(content);
mz_zip_reader_end(&zip_archive);
}
SECTION("Test repeated file addition to zip")
{
mz_zip_archive zip_archive = {};
auto b = mz_zip_writer_init_file(&zip_archive, "test2.zip", 0);
REQUIRE(b);
b = mz_zip_writer_finalize_archive(&zip_archive);
REQUIRE(b);
b = mz_zip_writer_end(&zip_archive);
REQUIRE(b);
for (int i = 0; i < 50; i++)
{
const char *str = "hello world";
b = mz_zip_add_mem_to_archive_file_in_place(
std::string("test2.zip").c_str(), ("file1.txt" + std::to_string(i)).c_str(),
str, (mz_uint16)strlen(str),
NULL, 0,
MZ_BEST_COMPRESSION);
REQUIRE(b);
}
}
}
#endif
TEST_CASE("Tinfl / tdefl tests")
{
SECTION("simple_test1")
{
size_t cmp_len = 0;
const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456";
size_t uncomp_len = strlen(p);
void *pComp_data = tdefl_compress_mem_to_heap(p, uncomp_len, &cmp_len, TDEFL_WRITE_ZLIB_HEADER);
REQUIRE(pComp_data);
size_t decomp_len = 0;
void *pDecomp_data = tinfl_decompress_mem_to_heap(pComp_data, cmp_len, &decomp_len, TINFL_FLAG_PARSE_ZLIB_HEADER);
REQUIRE(pDecomp_data);
REQUIRE(decomp_len == uncomp_len);
REQUIRE(memcmp(pDecomp_data, p, uncomp_len) == 0);
free(pComp_data);
free(pDecomp_data);
}
SECTION("simple_test2")
{
uint8_t cmp_buf[1024], decomp_buf[1024];
uLong cmp_len = sizeof(cmp_buf);
const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456";
uLong uncomp_len = (uLong)strlen(p);
int status = compress(cmp_buf, &cmp_len, (const uint8_t *)p, uncomp_len);
REQUIRE(status == Z_OK);
REQUIRE(cmp_len <= compressBound(uncomp_len));
uLong decomp_len = sizeof(decomp_buf);
status = uncompress(decomp_buf, &decomp_len, cmp_buf, cmp_len);
;
REQUIRE(status == Z_OK);
REQUIRE(decomp_len == uncomp_len);
REQUIRE(memcmp(decomp_buf, p, uncomp_len) == 0);
}
}

View File

@ -18,9 +18,15 @@
# This script is meant to be run by # This script is meant to be run by
# https://github.com/google/oss-fuzz/blob/master/projects/miniz/Dockerfile # https://github.com/google/oss-fuzz/blob/master/projects/miniz/Dockerfile
cat << "EOF" > miniz_export.h
#ifndef MINIZ_EXPORT
#define MINIZ_EXPORT
#endif
EOF
mkdir build mkdir build
cd build cd build
cmake .. -DAMALGAMATE_SOURCES=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FUZZERS=ON cmake .. -DAMALGAMATE_SOURCES=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FUZZERS=ON -DBUILD_TESTS=OFF
make -j$(nproc) make -j$(nproc)
cd .. cd ..

View File

@ -11,8 +11,10 @@
#include "miniz.h" #include "miniz.h"
#define CHECK_ERR(err, msg) { \ #define CHECK_ERR(err, msg) \
if (err != Z_OK) { \ { \
if (err != Z_OK) \
{ \
fprintf(stderr, "%s error: %d\n", msg, err); \ fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \ exit(1); \
} \ } \

View File

@ -14,7 +14,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{ {
unsigned long int buffer_length = sizeof(buffer); unsigned long int buffer_length = sizeof(buffer);
if (Z_OK != uncompress2(buffer, &buffer_length, data, &size)) return 0; if (Z_OK != uncompress2(buffer, &buffer_length, data, &size))
return 0;
return 0; return 0;
} }

View File

@ -12,7 +12,8 @@ static const size_t data_max = 1024 * 256;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{ {
if(size > data_max) return 0; if (size > data_max)
return 0;
int ret = 0; int ret = 0;
mz_zip_archive zip; mz_zip_archive zip;
@ -20,7 +21,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
mz_uint flags = 0; mz_uint flags = 0;
if(!mz_zip_reader_init_mem(&zip, data, size, flags)) return 0; if (!mz_zip_reader_init_mem(&zip, data, size, flags))
return 0;
mz_uint i, files; mz_uint i, files;
@ -30,22 +32,26 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{ {
mz_zip_clear_last_error(&zip); mz_zip_clear_last_error(&zip);
if(mz_zip_reader_is_file_a_directory(&zip, i)) continue; if (mz_zip_reader_is_file_a_directory(&zip, i))
continue;
mz_zip_validate_file(&zip, i, MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY); mz_zip_validate_file(&zip, i, MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY);
if(mz_zip_reader_is_file_encrypted(&zip, i)) continue; if (mz_zip_reader_is_file_encrypted(&zip, i))
continue;
mz_zip_clear_last_error(&zip); mz_zip_clear_last_error(&zip);
mz_uint ret = mz_zip_reader_get_filename(&zip, i, filename, filename_max); mz_uint ret = mz_zip_reader_get_filename(&zip, i, filename, filename_max);
if(mz_zip_get_last_error(&zip)) continue; if (mz_zip_get_last_error(&zip))
continue;
mz_zip_archive_file_stat file_stat = { 0 }; mz_zip_archive_file_stat file_stat = { 0 };
mz_bool status = mz_zip_reader_file_stat(&zip, i, &file_stat) != 0; mz_bool status = mz_zip_reader_file_stat(&zip, i, &file_stat) != 0;
if ((file_stat.m_method) && (file_stat.m_method != MZ_DEFLATED)) continue; if ((file_stat.m_method) && (file_stat.m_method != MZ_DEFLATED))
continue;
mz_zip_reader_extract_file_to_mem(&zip, file_stat.m_filename, read_buf, read_buf_size, 0); mz_zip_reader_extract_file_to_mem(&zip, file_stat.m_filename, read_buf, read_buf_size, 0);
} }