Compare commits

...

164 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
Martin
39f65158c7 Update changelog 2022-10-23 18:40:45 +02:00
Martin Raiber
ca0cdfc52d
Merge pull request #252 from JonLiu1993/vcpkg-instructions
Add vcpkg installation instructions
2022-08-25 22:03:10 +02:00
Martin Raiber
7b9bcf7f94
Merge pull request #234 from gtreshchev/bit-shift-fix
Bit shift fix
2022-08-25 22:02:34 +02:00
Martin Raiber
92ab73ac32
Merge pull request #236 from Dialga/patch-1
Fix callback typo
2022-08-25 22:02:06 +02:00
Martin Raiber
78ef92043c
Merge pull request #237 from jodavaho/dev/fix_shadow_warning
Fix for n shadows variable
2022-08-25 22:01:46 +02:00
Martin Raiber
11f77193b7
Merge pull request #241 from systoolz/patch-1
missing const in declaration
2022-08-25 21:59:05 +02:00
Martin Raiber
4a8dc21d9d
Merge pull request #238 from kobrineli/fix-overflow
Fix integer overflow in header corruption check.
2022-08-25 21:58:37 +02:00
Martin Raiber
725b8df44c
Merge pull request #239 from MatthewGentoo/cmake--pkgconfig
pkg-config tweaks
2022-08-25 21:58:04 +02:00
Martin Raiber
8cdf426109
Merge branch 'master' into cmake--pkgconfig 2022-08-25 21:57:56 +02:00
Martin Raiber
680454c21e
Merge pull request #247 from davidebeatrici/miniz.pc.ib-include-dir-fix
miniz.pc.in: fix include path not containing the "miniz" suffix
2022-08-25 21:57:01 +02:00
Jonliu1993
a203b9a0d4 Add vcpkg installation instructions 2022-08-25 16:21:22 +08:00
Davide Beatrici
d4ad2bf51e miniz.pc.in: fix include path not containing the "miniz" suffix 2022-08-02 19:25:10 +02:00
Martin Raiber
be92575500
Merge pull request #240 from AMDmi3/freebsd
Fix compatibility with FreeBSD and improve readability in miniz_zip.c
2022-07-09 13:00:58 +02:00
systoolz
a2b5326d86
missing const in declaration 2022-06-10 22:17:21 +07:00
Dmitry Marakasov
de0a4d2444 Use stdio functions without 64 suffix on FreeBSD
FreeBSD neither has nor needs suffixed functions
2022-06-08 20:36:46 +03:00
Dmitry Marakasov
482c77e661 Add blank lines between if blocks in miniz_zip.c for readability 2022-06-08 20:32:54 +03:00
Matthew Smith
37ea28133d
build: Set pkgconfig includedir to miniz directory
Allows users to include <miniz.h> instead of <miniz/miniz.h> which
seems to be the intended behaviour.
2022-06-04 09:31:06 +01:00
Matthew Smith
9cd715b3b1
build: Install .pc file in correct directory
/usr/share/pkgconfig should be used for architecture independent
libraries (e.g. data or scripts), while an architecture dependent
directory like /usr/lib64/pkgconfig should be used for native
binaries.

Co-authored-by: Sam James <sam@gentoo.org>
2022-06-04 09:22:37 +01:00
Eli Kobrin
a9d7f80cc6 Fix integer overflow in header corruption check. 2022-05-20 16:30:30 +03:00
Josh Vander Hook
8db69b6b59 Fix for n shadows variable 2022-05-19 11:24:55 -07:00
Georgy Treshchev
c610f58a57 Replacing "1ULL" with "(size_t)1" 2022-05-16 19:47:54 +04:00
Dialga
e1e7f70e59
Fix callback typo 2022-05-17 01:37:04 +12:00
Martin Raiber
76b3a87285
Update ChangeLog.md 2022-05-08 16:53:32 +02:00
Martin Raiber
5c9c89509c
Merge pull request #231 from nedelec/master
Fixed alignment problems on MacOS
2022-05-08 16:48:02 +02:00
Martin Raiber
719967dc82
Merge pull request #225 from randy408/zlib_flevel
deflate: write zlib FLEVEL based on compression level
2022-05-08 16:46:36 +02:00
Martin Raiber
18bc504331
Merge pull request #224 from Dialga/patch-1
Add switch case for MZ_ZIP_TOTAL_ERRORS
2022-05-08 16:44:03 +02:00
Martin Raiber
144c351f34
Update miniz_tdef.c
Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>
2022-05-06 21:30:08 +02:00
Martin Raiber
bc77ea1017
Update miniz_tdef.c
Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>
2022-05-06 21:30:02 +02:00
Randy
7c459c8a05
Update miniz_tdef.c
Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com>
2022-05-06 05:01:09 +02:00
Georgy Treshchev
118b2e3d34 Bit shift fix 2022-05-01 11:33:43 +04:00
Francois Nedelec
e7d0e216d5 Fixed alignment problems on MacOS 2022-04-01 14:34:04 +01:00
Martin Raiber
5a38f5564a Increment version in cmake 2022-02-27 20:09:11 +01:00
Martin Raiber
9eedb97176 Clear whole tree to prevent uninitialized value 2022-02-27 20:08:22 +01:00
Martin Raiber
8a7cf60c7a
Merge pull request #226 from sezero/w1
replace use of stdint.h types with mz_ variants
2022-02-09 21:36:23 +01:00
Martin Raiber
d9bd65a843
Merge pull request #227 from sezero/u0
tdefl_compress_normal: Avoid NULL ptr arithmetic UB
2022-02-09 21:35:06 +01:00
Andrius Mitkus
71ba5d12d6 Avoid NULL ptr arithmetic UB 2022-02-09 09:48:30 +03:00
Ozkan Sezer
e285002431 replace use of stdint.h types with mz_ variants 2022-02-09 09:36:50 +03:00
Randy
cd1dc96d27 deflate: write zlib FLEVEL based on compression level 2022-02-08 23:24:02 +01:00
Dialga
5245b1c52f
Add switch case for MZ_ZIP_TOTAL_ERRORS 2022-02-07 11:03:31 +13:00
Martin
842a20e586 Update ChangeLog 2022-02-06 14:58:49 +01:00
Martin
edc251cfa9 Add padding to structures so it continues to work if features differ 2022-02-06 14:57:58 +01:00
Martin
9ffbe56a73 Update ChangeLog 2022-02-06 14:39:43 +01:00
Martin
f2b59b344d Increment major version 2022-02-06 14:39:27 +01:00
Martin
0ce345c44a Disable building shared lib by default 2022-02-06 14:30:35 +01:00
Martin
0796bdbee6 Disable treating warnings as error with MSVC 2022-02-06 14:29:22 +01:00
Martin Raiber
056cc8db14
Merge pull request #159 from christiansandberg/reduced-inflate-memory-usage
Reduce memory usage for inflate
2022-02-06 14:16:40 +01:00
Christian Sandberg
60942b0f04 Initialize tree and code size tables separately 2022-01-24 09:55:56 +01:00
Christian Sandberg
8997650f5c Remove m_tables 2022-01-23 20:24:58 +01:00
Christian Sandberg
698faddd95 Minor formatting fix 2022-01-23 14:14:27 +01:00
Christian Sandberg
ff862d4596 Fix -Wshadow 2022-01-23 14:12:48 +01:00
Christian Sandberg
740049e643 Merge branch 'master' into reduced-inflate-memory-usage 2022-01-23 13:32:56 +01:00
Martin Raiber
2cd06e3f32
Merge pull request #217 from sezero/ub-fix
tinfl_decompress: avoid NULL ptr arithmetic UB:
2022-01-22 22:16:45 +01:00
Martin Raiber
f3d9e2293b
Fix return value 2022-01-22 22:14:31 +01:00
Martin Raiber
1541a11e9b
Merge pull request #220 from sezero/z64
miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
2022-01-22 20:12:07 +01:00
Ozkan Sezer
501a761549 miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
Fixes: https://github.com/richgel999/miniz/issues/218
2022-01-02 20:56:56 +03:00
Ozkan Sezer
aa70ef1644 tinfl_decompress: avoid NULL ptr arithmetic UB:
Fixes: https://github.com/richgel999/miniz/issues/216

Also see:
6b8c30e4a9
2021-12-27 10:50:32 +03:00
Martin
13b21dddc7 Remove total files check (its 32-bit uint)
This fixes a compiler warning. The check didn't do
anything since m_total_files is a 32-bit uint and
MZ_UINT32_MAX is actually a valid value.
2021-12-11 12:59:21 +01:00
Martin
a956b4c753 Fix MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 not being set 2021-12-11 12:51:50 +01:00
Martin
ecbbbe0138 Fix function declaration if MINIZ_NO_STDIO is used 2021-11-28 18:38:56 +01:00
Martin
72e7267054 Fix unaligned pointer access 2021-11-28 18:37:55 +01:00
Martin
12b78b6d5a Fix function definitions
Fix function definitions tdefl_compressor_alloc(void) and
tinfl_decompressor_alloc(void) to not accept any amount of arguments.
2021-11-28 18:36:40 +01:00
Martin
2beb69d0a5 Don't use unaligned stores and loads per default 2021-11-28 18:35:46 +01:00
Martin
0a88083589 Improve endianess detection 2021-11-28 18:35:19 +01:00
Martin
3e5e488ba9 Use level_and_flags after MZ_DEFAULT_COMPRESSION has been handled 2021-11-28 18:08:27 +01:00
Martin
75c948a1dd Only define MINIZ_EXPORT if not already defined 2021-11-28 17:35:49 +01:00
Martin
b4108c6fcf Adjust usage text
Miniz has a history of being a single header library. Nowadays this
might be less important. So clarify that the library can be used
via other ways.
2021-11-28 17:26:16 +01:00
Martin Raiber
e6a7c5daed
Merge pull request #204 from DimitriPapadopoulos/codespell
Fix a couple typos found by codespell
2021-11-11 21:42:04 +01:00
Martin Raiber
66c7313326
Merge pull request #197 from ccawley2011/patch-3
Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
2021-11-11 21:39:08 +01:00
Martin Raiber
82d6810a38
Merge pull request #193 from ccawley2011/no-inflate-deflate
Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS
2021-11-11 21:36:53 +01:00
Martin
ee4deb08fa Merge remote-tracking branch 'ccawley2011/mingw-watcom'
# Conflicts:
#	examples/example6.c
2021-11-11 21:36:15 +01:00
Martin Raiber
cb2b132b86
Merge pull request #196 from ccawley2011/patch-2
Set MINIZ_LITTLE_ENDIAN only if not set
2021-11-11 21:26:54 +01:00
Martin Raiber
591faa9574
Merge pull request #207 from SamuelMarks/c89
C89 support
2021-11-11 21:25:11 +01:00
Martin Raiber
3a387ec369
Merge pull request #208 from ell1e/fix_mingw_cross
Fix MinGW cross compilation by removing unneeded capitalization
2021-11-11 21:24:08 +01:00
Ellie
cda0b3e7f0 Fix MinGW cross compilation by removing unneeded capitalization 2021-11-11 13:38:57 +01:00
Samuel Marks
e841503cad
[CMakeLists.txt] Enforce C89; [examples/example6.c] Conform to C89; [miniz_zip.c] Use lowercase <windows.h> 2021-11-10 21:59:32 -05:00
Dimitri Papadopoulos
a7961f5b4c
Fix a couple typos found by codespell 2021-11-03 14:04:11 +01:00
Martin Raiber
ca1a779ee1
Merge pull request #195 from ccawley2011/patch-1
Avoid using unaligned memory access in UBSan builds
2021-10-03 13:13:13 +02:00
Martin Raiber
18da352921
Merge pull request #203 from prezi/prezi-patch-2
Support for unicode characters in paths and filenames on windows
2021-10-03 13:12:31 +02:00
Zsombor Fazekas
d9c899cea4 Use _wstat64 instead _stat64 on windows 2021-09-16 12:12:07 +02:00
Zsombor Fazekas
70c79cc9d5 Use wfopen on windows 2021-09-16 12:00:44 +02:00
Cameron Cawley
583f4f27c2
Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
Co-authored-by: sezero <sezero@users.noreply.github.com>
2021-07-25 15:36:22 +01:00
Cameron Cawley
9b89689723 Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS 2021-07-20 20:19:32 +01:00
Cameron Cawley
f99eae6e04
Set MINIZ_LITTLE_ENDIAN only if not set 2021-07-20 20:17:06 +01:00
Cameron Cawley
fc0c0f585e
Avoid using unaligned memory access in UBSan builds 2021-07-20 18:22:34 +01:00
Cameron Cawley
78ae375016 Fix "'&array' may not produce intended result" warnings with OpenWatcom
Co-authored-by: sezero <sezero@users.noreply.github.com>
2021-07-20 18:08:11 +01:00
Cameron Cawley
f542e6df73 Fix "Comparison result always 0" warnings with OpenWatcom 2021-07-20 18:05:16 +01:00
Cameron Cawley
46347635c8 Fix building example6 with C89 compilers 2021-07-20 18:05:16 +01:00
Cameron Cawley
c0aad72d46 Use _ftelli64, _fseeki64 and stat with MinGW32 and OpenWatcom 2021-07-20 18:04:52 +01:00
Martin
08f2c2d7e3 Fix test 2021-06-27 23:22:31 +02:00
Christian Sandberg
49860a15fa Eliminate 64-bit operations on 32-bit machines 2020-07-03 13:22:18 +02:00
Christian Sandberg
524906517d Cache pointers to tables for speed 2020-06-23 11:51:26 +02:00
Christian Sandberg
3d000933a7 Reduce size of const data 2020-06-23 11:42:03 +02:00
Christian Sandberg
40b0612004 Skip unnecessary pointer usage 2020-06-22 19:39:52 +02:00
Christian Sandberg
8da3cbb64e Reduce memory usage for inflate
Use Huffman tables with correct sizes instead of always 288
2020-06-20 17:31:32 +02:00
40 changed files with 32924 additions and 8221 deletions

View File

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

View File

@ -15,3 +15,27 @@ jobs:
- uses: actions/checkout@v2
- name: amalgamate
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
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
if: failure()
with:
name: artifacts

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/_build
/amalgamation
/bin

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
set (MINIZ_STANDALONE_PROJECT ON)
@ -10,12 +10,22 @@ if(CMAKE_MINOR_VERSION LESS 12)
project(miniz)
# see issue https://gitlab.kitware.com/cmake/cmake/merge_requests/1799
else()
project(miniz C)
project(miniz)
set(CMAKE_C_STANDARD 90)
set(CMAKE_VERBOSE_MAKEFILE ON)
# set(CMAKE_C_VISIBILITY_PRESET hidden)
# set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
if (MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /Zi /permissive-")
else ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow -Wformat=2 -Wall -Wno-overlength-strings -pedantic")
endif ()
endif()
set(MINIZ_API_VERSION 2)
set(MINIZ_MINOR_VERSION 2)
set(MINIZ_PATCH_VERSION 0)
set(MINIZ_API_VERSION 3)
set(MINIZ_MINOR_VERSION 0)
set(MINIZ_PATCH_VERSION 2)
set(MINIZ_VERSION
${MINIZ_API_VERSION}.${MINIZ_MINOR_VERSION}.${MINIZ_PATCH_VERSION})
@ -31,7 +41,9 @@ option(BUILD_EXAMPLES "Build examples" ${MINIZ_STANDALONE_PROJECT})
option(BUILD_FUZZERS "Build fuzz targets" OFF)
option(AMALGAMATE_SOURCES "Amalgamate sources into miniz.h/c" OFF)
option(BUILD_HEADER_ONLY "Build a header-only version" OFF)
option(BUILD_SHARED_LIBS "Build shared library instead of static" ON)
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})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
@ -68,7 +80,7 @@ if(AMALGAMATE_SOURCES)
string(REPLACE "#include \"${REPLACE_STRING}.h\"" "" AMAL_MINIZ_H "${AMAL_MINIZ_H}")
string(REPLACE "#include \"${REPLACE_STRING}.h\"" "" AMAL_MINIZ_C "${AMAL_MINIZ_C}")
endforeach()
string(CONCAT AMAL_MINIZ_H "#define MINIZ_EXPORT\n" "${AMAL_MINIZ_H}")
string(CONCAT AMAL_MINIZ_H "#ifndef MINIZ_EXPORT\n#define MINIZ_EXPORT\n#endif\n" "${AMAL_MINIZ_H}")
if(BUILD_HEADER_ONLY)
string(CONCAT AMAL_MINIZ_H "${AMAL_MINIZ_H}" "\n#ifndef MINIZ_HEADER_FILE_ONLY\n"
"${AMAL_MINIZ_C}" "\n#endif // MINIZ_HEADER_FILE_ONLY\n")
@ -163,10 +175,14 @@ if(NOT BUILD_HEADER_ONLY)
if(INSTALL_PROJECT)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/miniz.pc
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
endif()
if(BUILD_NO_STDIO)
target_compile_definitions(${PROJECT_NAME} PRIVATE MINIZ_NO_STDIO)
endif()
set_property(TARGET ${PROJECT_NAME} PROPERTY
INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${MINIZ_API_VERSION})
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY
@ -231,8 +247,10 @@ if(BUILD_EXAMPLES)
add_executable(example1 ${EXAMPLE1_SRC_LIST})
target_link_libraries(example1 miniz)
if(NOT BUILD_NO_STDIO)
add_executable(example2 ${EXAMPLE2_SRC_LIST})
target_link_libraries(example2 miniz)
endif()
add_executable(example3 ${EXAMPLE3_SRC_LIST})
target_link_libraries(example3 miniz)
add_executable(example4 ${EXAMPLE4_SRC_LIST})
@ -260,6 +278,7 @@ if(BUILD_FUZZERS)
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(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})
target_link_libraries(checksum_fuzzer miniz)
@ -284,6 +303,24 @@ if(BUILD_FUZZERS)
add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST})
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()
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,48 @@
## 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
- Reduce memory usage for inflate. This changes `struct tinfl_decompressor_tag` and therefore requires a major version bump (breaks ABI compatibility)
- Add padding to structures so it continues to work if features differ. This also changes some structures
- Use _ftelli64, _fseeki64 and stat with MinGW32 and OpenWatcom
- Fix varios warnings with OpenWatcom compiler
- Avoid using unaligned memory access in UBSan builds
- Set MINIZ_LITTLE_ENDIAN only if not set
- Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS
- Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
- Use wfopen on windows
- Use _wstat64 instead _stat64 on windows
- Use level_and_flags after MZ_DEFAULT_COMPRESSION has been handled
- Improve endianess detection
- Don't use unaligned stores and loads per default
- Fix function declaration if MINIZ_NO_STDIO is used
- Fix MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 not being set
- Remove total files check (its 32-bit uint)
- tinfl_decompress: avoid NULL ptr arithmetic UB
- miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
- Eliminate 64-bit operations on 32-bit machines
- Disable treating warnings as error with MSVC
- Disable building shared lib via CMake by default
- Fixed alignment problems on MacOS
- Fixed get error string for MZ_ZIP_TOTAL_ERRORS
- Write correct FLEVEL 2-bit value in zlib header
- miniz.pc.in: fix include path not containing the "miniz" suffix
- Fix compatibility with FreeBSD
- pkg-config tweaks
- Fix integer overflow in header corruption check
- Fix some warnings
- tdefl_compress_normal: Avoid NULL ptr arithmetic UB
- replace use of stdint.h types with mz_ variants
### 2.2.0
- Fix examples with amalgamation
@ -123,7 +166,7 @@ Merged over a few very minor bug fixes that I fixed in the zip64 branch. This is
Interim bugfix release while I work on the next major release with zip64 and streaming compression/decompression support. Fixed the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com), which could cause the locate files func to not find files when this flag was specified. Also fixed a bug in mz_zip_reader_extract_to_mem_no_alloc() with user provided read buffers (thanks kymoon). I also merged lots of compiler fixes from various github repo branches and Google Code issue reports. I finally added cmake support (only tested under for Linux so far), compiled and tested with clang v3.3 and gcc 4.6 (under Linux), added defl_write_image_to_png_file_in_memory_ex() (supports Y flipping for OpenGL use, real-time compression), added a new PNG example (example6.c - Mandelbrot), and I added 64-bit file I/O support (stat64(), etc.) for glibc.
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
would only have occurred in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
(which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
- Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
- Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.

View File

@ -18,11 +18,13 @@ then
echo "Test compile with clang..."
clang -Wall -Wpedantic -fsanitize=unsigned-integer-overflow -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out
fi
for def in MINIZ_NO_STDIO MINIZ_NO_TIME MINIZ_NO_ARCHIVE_APIS MINIZ_NO_ARCHIVE_WRITING_APIS MINIZ_NO_ZLIB_APIS MINIZ_NO_ZLIB_COMPATIBLE_NAMES MINIZ_NO_MALLOC
for def in MINIZ_NO_STDIO MINIZ_NO_TIME MINIZ_NO_DEFLATE_APIS MINIZ_NO_INFLATE_APIS MINIZ_NO_ARCHIVE_APIS MINIZ_NO_ARCHIVE_WRITING_APIS MINIZ_NO_ZLIB_APIS MINIZ_NO_ZLIB_COMPATIBLE_NAMES MINIZ_NO_MALLOC
do
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}
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 main.c

View File

@ -7,12 +7,12 @@ typedef unsigned short uint16;
typedef unsigned int uint;
// The string to compress.
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." \
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.";
int main(int argc, char *argv[])

View File

@ -21,12 +21,12 @@ typedef unsigned int uint;
// The string to compress.
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" \
"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" \
"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." \
"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" \
"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"
"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"
"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"
"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";

View File

@ -100,7 +100,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@ -47,7 +47,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@ -132,7 +132,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@ -29,32 +29,57 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
const int saturation = 1;
const int color_rotate = 0;
if (min == max) max = min + 1;
if (invert) hue = max - (hue - min);
if (!saturation) {
if (min == max)
max = min + 1;
if (invert)
hue = max - (hue - min);
if (!saturation)
{
p->r = p->g = p->b = 255 * (max - hue) / (max - min);
return;
}
double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
double c = 255.0f * saturation;
double X = c * (1 - fabs(fmod(h, 2) - 1));
else
{
const double h_dbl = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
const double c_dbl = 255 * saturation;
const double X_dbl = c_dbl * (1 - fabs(fmod(h_dbl, 2) - 1));
const int h = (int)h_dbl;
const int c = (int)c_dbl;
const int X = (int)X_dbl;
p->r = p->g = p->b = 0;
switch((int)h) {
case 0: p->r = c; p->g = X; return;
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;
switch (h)
{
case 0:
p->r = c;
p->g = X;
return;
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;
}
}
}
int main(int argc, char *argv[])
{
(void)argc, (void)argv;
// Image resolution
const int iXmax = 4096;
const int iYmax = 4096;
@ -89,6 +114,8 @@ int main(int argc, char *argv[])
int MinIter = 9999, MaxIter = 0;
(void)argc, (void)argv;
for (iY = 0; iY < iYmax; iY++)
{
Cy = CyMin + iY * PixelHeight;
@ -134,7 +161,7 @@ int main(int argc, char *argv[])
uint Iterations = color[0] | (color[1] << 8U);
hsv_to_rgb(Iterations, MinIter, MaxIter, (rgb_t *)color);
hsv_to_rgb((int)Iterations, MinIter, MaxIter, (rgb_t *)color);
}
}

21
miniz.c
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];
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- 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)
{
static const mz_uint32 s_crc_table[256] =
{
static const mz_uint32 s_crc_table[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
@ -186,6 +186,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);
@ -320,7 +322,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;
@ -353,6 +355,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;
@ -559,7 +565,7 @@ int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned cha
memset(&stream, 0, sizeof(stream));
/* In case mz_ulong is 64-bits (argh I hate longs). */
if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU)
if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
return MZ_PARAM_ERROR;
stream.next_in = pSource;
@ -588,14 +594,15 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char
return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
}
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
const char *mz_error(int err)
{
static struct
{
int m_err;
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_uint i;

181
miniz.h
View File

@ -1,4 +1,4 @@
/* miniz.c 2.2.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.
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
@ -115,7 +115,7 @@
#include "miniz_export.h"
/* 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 */
@ -125,6 +125,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 */
@ -143,6 +149,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
@ -161,18 +175,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
@ -187,7 +223,8 @@
#endif
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- zlib-style API Definitions. */
@ -236,9 +273,9 @@ enum
MZ_DEFAULT_COMPRESSION = -1
};
#define MZ_VERSION "10.2.0"
#define MZ_VERNUM 0xA100
#define MZ_VER_MAJOR 10
#define MZ_VERSION "11.0.2"
#define MZ_VERNUM 0xB002
#define MZ_VER_MAJOR 11
#define MZ_VER_MINOR 2
#define MZ_VER_REVISION 0
#define MZ_VER_SUBREVISION 0
@ -304,6 +341,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. */
@ -356,6 +395,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 +432,7 @@ MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
/* 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);
@ -435,37 +479,116 @@ typedef void *const voidpc;
#define Z_FIXED MZ_FIXED
#define Z_DEFLATED MZ_DEFLATED
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
#define alloc_func mz_alloc_func
#define free_func mz_free_func
/* See mz_alloc_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 z_stream mz_stream
#define deflateInit mz_deflateInit
#define deflateInit2 mz_deflateInit2
#define deflateReset mz_deflateReset
#define deflate mz_deflate
#define deflateEnd mz_deflateEnd
#define deflateBound mz_deflateBound
#define compress mz_compress
#define compress2 mz_compress2
#define compressBound mz_compressBound
#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
#define crc32 mz_crc32
#define adler32 mz_adler32
#ifndef MINIZ_NO_DEFLATE_APIS
/* Compatiblity with zlib API. See called functions for documentation */
static int deflateInit(mz_streamp pStream, int level)
{
return mz_deflateInit(pStream, level);
}
static int deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
{
return mz_deflateInit2(pStream, level, method, window_bits, mem_level, strategy);
}
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*/
#ifndef MINIZ_NO_INFLATE_APIS
/* Compatiblity with zlib API. See called functions for documentation */
static int inflateInit(mz_streamp pStream)
{
return mz_inflateInit(pStream);
}
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*/
static mz_ulong crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len)
{
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_MEM_LEVEL 9
#define zError mz_error
static const char* zError(int err)
{
return mz_error(err);
}
#define ZLIB_VERSION MZ_VERSION
#define ZLIB_VERNUM MZ_VERNUM
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
#define ZLIB_VER_MINOR MZ_VER_MINOR
#define ZLIB_VER_REVISION MZ_VER_REVISION
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
#define zlibVersion mz_version
#define zlib_version mz_version()
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */

View File

@ -1,7 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@

View File

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

View File

@ -26,15 +26,17 @@
#include "miniz.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- Low-level Compression (independent from all decompression API's) */
/* 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,
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,
@ -45,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
};
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,
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, 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,
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,
@ -69,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
};
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,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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,
@ -81,15 +80,13 @@ static const mz_uint8 s_tdefl_small_dist_extra[512] =
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,
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
};
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,
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
@ -104,7 +101,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;
@ -222,7 +219,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++)
@ -248,8 +245,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);
@ -335,7 +332,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)
{
@ -473,7 +470,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]]);
@ -518,7 +516,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;
@ -600,6 +598,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;
@ -620,8 +620,28 @@ 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);
@ -1092,7 +1112,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)
@ -1302,8 +1322,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;
}
}
@ -1326,7 +1346,7 @@ 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;
@ -1347,7 +1367,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;
@ -1438,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;
}
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)
{
@ -1557,7 +1575,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));
}
@ -1575,3 +1593,5 @@ void tdefl_compressor_free(tdefl_compressor *pComp)
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@ -1,13 +1,18 @@
#pragma once
#include "miniz_common.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- 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). */
#ifndef TDEFL_LESS_MEMORY
#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_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). */
@ -101,7 +106,7 @@ enum
enum
{
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_LZ_HASH_BITS = 15,
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
@ -111,7 +116,8 @@ enum
#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. */
typedef enum {
typedef enum
{
TDEFL_STATUS_BAD_PARAM = -2,
TDEFL_STATUS_PUT_BUF_FAILED = -1,
TDEFL_STATUS_OKAY = 0,
@ -119,7 +125,8 @@ typedef enum {
} tdefl_status;
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
typedef enum {
typedef enum
{
TDEFL_NO_FLUSH = 0,
TDEFL_SYNC_FLUSH = 2,
TDEFL_FULL_FLUSH = 3,
@ -188,3 +195,5 @@ MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@ -26,8 +26,11 @@
#include "miniz.h"
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- Low-level Decompression (completely independent from all compression API's) */
@ -106,10 +109,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; \
@ -121,7 +124,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; \
@ -137,7 +140,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; \
@ -146,7 +149,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 \
{ \
@ -155,14 +158,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; \
@ -171,20 +174,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). */
@ -194,6 +210,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;
@ -210,7 +233,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);
@ -271,11 +294,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)
@ -292,26 +315,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)
@ -325,7 +352,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]++;
@ -336,14 +363,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;
}
@ -351,24 +378,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;
@ -388,8 +415,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 (;;)
@ -399,7 +426,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)
@ -427,14 +454,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;
@ -451,19 +478,25 @@ 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;
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;
if (sym2 & 256)
{
@ -487,7 +520,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)
@ -572,7 +605,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)
@ -604,7 +637,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;
@ -699,6 +732,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 (;;)
{
@ -721,7 +755,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)
@ -738,3 +772,5 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/

View File

@ -2,8 +2,11 @@
#include "miniz_common.h"
/* ------------------- Low-level Decompression API Definitions */
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* 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. */
@ -53,7 +56,8 @@ MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
#define TINFL_LZ_DICT_SIZE 32768
/* 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 */
/* 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. */
@ -110,12 +114,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
@ -135,10 +133,18 @@ 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*/

View File

@ -29,7 +29,8 @@
#ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* ------------------- .ZIP archive reading */
@ -39,20 +40,67 @@ extern "C" {
#else
#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
#endif
#ifndef __cplusplus
#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
static WCHAR *mz_utf8z_to_widechar(const char *str)
{
int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR));
MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
return wStr;
}
static FILE *mz_fopen(const char *pFilename, const char *pMode)
{
WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
FILE *pFile = NULL;
fopen_s(&pFile, pFilename, pMode);
return pFile;
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)
{
WCHAR *wPath = mz_utf8z_to_widechar(pPath);
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
FILE *pFile = NULL;
if (freopen_s(&pFile, pPath, pMode, pStream))
return NULL;
return pFile;
errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
free(wPath);
free(wMode);
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)
{
WCHAR *wPath = mz_utf8z_to_widechar(path);
int res = _wstat64(wPath, buffer);
free(wPath);
return res;
}
#endif
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
@ -62,12 +110,18 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
#define MZ_FWRITE fwrite
#define MZ_FTELL64 _ftelli64
#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 _stat64
#define MZ_FILE_STAT mz_stat64
#endif
#define MZ_FFLUSH fflush
#define MZ_FREOPEN mz_freopen
#define MZ_DELETE_FILE remove
#elif defined(__MINGW32__)
#elif defined(__WATCOMC__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
@ -75,13 +129,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 <sys/utime.h>
@ -97,6 +152,7 @@ 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) /* gcc, clang */
#ifndef MINIZ_NO_TIME
#include <utime.h>
@ -112,7 +168,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__) || (defined(__linux__) && defined(__x86_64__))
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
@ -258,7 +315,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;
@ -580,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) */
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;
cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
@ -590,10 +647,23 @@ static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 r
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)
{
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;
const mz_uint8 *p;
@ -615,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))
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. */
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);
@ -627,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 (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;
}
}
}
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);
}
}
@ -694,12 +784,36 @@ 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)
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;
if (pZip->m_total_files)
@ -845,7 +959,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)
@ -988,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)))
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)
return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
@ -1319,7 +1433,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)
@ -1334,7 +1448,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)
@ -1427,7 +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);
}
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;
@ -1440,7 +1554,11 @@ 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 (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
if (st)
{
file_stat = *st;
}
else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE;
/* A directory or zero length file */
@ -1468,7 +1586,7 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
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)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -1570,17 +1688,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)
@ -1590,23 +1713,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);
@ -1619,7 +1736,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;
@ -1681,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)
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)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -1923,7 +2040,7 @@ mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive
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)
{
mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
@ -2080,7 +2197,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 */
@ -2449,7 +2566,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);
@ -2467,9 +2584,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);
}
@ -2831,7 +2945,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
{
@ -2910,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)
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)
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
@ -3194,7 +3309,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); */
@ -3218,6 +3333,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
time(&cur_time);
mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
}
#else
(void)last_modified;
#endif /* #ifndef MINIZ_NO_TIME */
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
@ -3244,10 +3361,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 +
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)
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)
{
pState->m_zip64 = MZ_TRUE;
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
@ -3287,7 +3402,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))
{
@ -3437,7 +3552,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
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 = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
mz_uint16 gen_flags;
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
@ -3449,13 +3564,15 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
mz_zip_internal_state *pState;
mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
level = level_and_flags & 0xF;
gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
/* Sanity checks */
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
@ -3503,9 +3620,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
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 + 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)
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)
{
pState->m_zip64 = MZ_TRUE;
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
@ -3517,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);
}
#else
(void)pFile_time;
#endif
if (max_size <= 3)
@ -3540,7 +3657,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
method = MZ_DEFLATED;
}
MZ_CLEAR_OBJ(local_dir_header);
MZ_CLEAR_ARR(local_dir_header);
if (pState->m_zip64)
{
if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
@ -3844,7 +3961,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))
@ -4002,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_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);
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 */
if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
@ -4160,10 +4277,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);
@ -4299,7 +4416,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
@ -4327,7 +4444,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 */
@ -4342,7 +4459,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);
@ -4353,7 +4470,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));
@ -4452,14 +4569,14 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, co
else
{
/* 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)
*pErr = zip_archive.m_last_error;
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)
*pErr = zip_archive.m_last_error;
@ -4669,7 +4786,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;
}

View File

@ -7,7 +7,8 @@
#ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
enum
@ -32,10 +33,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;
@ -72,6 +69,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);
@ -81,14 +83,16 @@ typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
struct mz_zip_internal_state_tag;
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
typedef enum {
typedef enum
{
MZ_ZIP_MODE_INVALID = 0,
MZ_ZIP_MODE_READING = 1,
MZ_ZIP_MODE_WRITING = 2,
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
} mz_zip_mode;
typedef enum {
typedef enum
{
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
@ -100,10 +104,12 @@ typedef enum {
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_FLAG_WRITE_HEADER_SET_SIZE = 0x20000,
MZ_ZIP_FLAG_READ_ALLOW_WRITING = 0x40000
} mz_zip_flags;
typedef enum {
typedef enum
{
MZ_ZIP_TYPE_INVALID = 0,
MZ_ZIP_TYPE_USER,
MZ_ZIP_TYPE_MEMORY,
@ -114,7 +120,8 @@ typedef enum {
} mz_zip_type;
/* 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_UNDEFINED_ERROR,
MZ_ZIP_TOO_MANY_FILES,
@ -183,9 +190,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;
@ -195,6 +200,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 */
@ -318,9 +329,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
@ -334,7 +345,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);
@ -387,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 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. */
@ -408,7 +420,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);
@ -425,11 +437,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 */

View File

@ -4,7 +4,7 @@ Miniz is a lossless, high performance data compression library in a single sourc
## Usage
Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz.
Releases are available at the [releases page](https://github.com/richgel999/miniz/releases) as a pair of `miniz.c`/`miniz.h` files which can be simply added to a project. To create this file pair the different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) during build. Alternatively use as cmake or meson module (or build system of your choice).
## Features
@ -18,6 +18,18 @@ Please use the files from the [releases page](https://github.com/richgel999/mini
* Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c
* A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.)
## Building miniz - Using vcpkg
You can download and install miniz using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install miniz
The miniz port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Known Problems
* No support for encrypted archives. Not sure how useful this stuff is in practice.

View File

@ -4,6 +4,11 @@ set -e
. amalgamate.sh
cat << "EOF" > miniz_export.h
#ifndef MINIZ_EXPORT
#define MINIZ_EXPORT
#endif
EOF
g++ tests/miniz_tester.cpp tests/timer.cpp amalgamation/miniz.c -o miniz_tester -I. -ggdb -O2
for i in 1 2 3 4 5 6

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)
{
/* 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 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));
}
#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)
{

View File

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

View File

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

View File

@ -11,8 +11,10 @@
#include "miniz.h"
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
#define CHECK_ERR(err, msg) \
{ \
if (err != Z_OK) \
{ \
fprintf(stderr, "%s error: %d\n", msg, err); \
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.avail_out = (unsigned int)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
if (err == Z_STREAM_END)
break;
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
# 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
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)
cd ..

View File

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

View File

@ -14,7 +14,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
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;
}

View File

@ -12,7 +12,8 @@ static const size_t data_max = 1024 * 256;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
if(size > data_max) return 0;
if (size > data_max)
return 0;
int ret = 0;
mz_zip_archive zip;
@ -20,7 +21,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
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;
@ -30,22 +32,26 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
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);
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_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_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);
}