[Library] Update zlibng (#1255)

* Update zlibng

* Set cmake path more directly in zlibng to hopefully fix an issue with the build on drone

* I'm dumb, missing / in path

* Mackal helps with a dumb gitignore issue

* Adding all the files, not sure what's ignoring them and im tired of looking

* Some tweaks to zlibng build to hopefully get it to build properly. works on msvc now
This commit is contained in:
Alex
2021-02-23 17:00:26 -08:00
committed by GitHub
parent e6dee96266
commit 2957f5084d
184 changed files with 21431 additions and 11703 deletions
+3
View File
@@ -1,2 +1,5 @@
# ignore Makefiles; they're all automatically generated
Makefile
/switchlevels
/switchlevels.dSYM/
/switchlevels.exe
+13 -11
View File
@@ -5,16 +5,18 @@
#include <stdio.h>
int main(void) {
gzFile f;
int ret;
gzFile f;
int ret;
if(!(f = gzopen("/dev/null", "w"))) {
perror("/dev/null");
exit(1);
}
ret = gzprintf(f, "%10240s", "");
printf("gzprintf -> %d\n", ret);
ret = gzclose(f);
printf("gzclose -> %d [%d]\n", ret, errno);
exit(0);
if(!(f = gzopen("/dev/null", "w"))) {
perror("/dev/null");
exit(1);
}
ret = gzprintf(f, "%10240s", "");
printf("gzprintf -> %d\n", ret);
ret = gzclose(f);
printf("gzclose -> %d [%d]\n", ret, errno);
exit(0);
}
+4
View File
@@ -0,0 +1,4 @@
.....-.u..|u....-...!..A.#?)9.._B..F..|
00000650 fa 13 88 89 2c 1f 81 0f e4 e9 ce 39 a0 87 2e 2e |....,......9....|
00000660 a5 0c 08 9c ec fc 88 6d 16 02 0a a0 3d fc 36 29 |.......m....=.6)|
00000670 8d f5 c3 ba 1d 07 f4 78 e1 a0 41 f9 89 15 a5 69 |.......x..A....
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
oフ厠?フOフテフhファフユフ>フフ猯變ケフ侘ヤフEフsフ領採4フ厠体「フ6フフリフ賣\フフ5フェフイフ蔑mフフ摸醂コフ慘ルファフフ﨓﨓摸mフホフオフGフOフロフ フテフホフ;フ販フ栂モフタフラフ,フムフ「フ睥Aフ9フサフ賣のツフsフフシフンフフュフeフンフUフuフ﨓アフヒフwフ蔑Dプフ粁スフtフ槊」フケフOフ閒﨓pフGフーフタフ(フフ、フ{フ椴゚フユフフMフ#フ變﨓オフdフキフIプフhフ_フpフJフヌフ「フホフフoフ⇔チフ;フ<フ侘ZフネフムフoフWフソフ}フ睥フ:フ睥ァフ蔑サフeフFフtフ(フEフoフ猯pフフ「フ(フ;フ!フケフケフノフフ慘閒ヨフ4フネフ3フ粁Bフ捨ニフuフPフ6フ椴フ&フヲフウフ蔑チフサフフTフタファフbフフメフユフ{フニフ。フハフNフ9フヌフフBフム
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
Makefile.in: template for Unix Makefile
CVE-2003-0107.c:
CVE-2002-0059 :
CVE-2004-0797 :
CVE-2005-1849 :
CVE-2005-2096 : test cases for the relevant CVEs
testCVEinputs.sh: script to run tests for CVEs where input data is supplied
+31 -20
View File
@@ -7,14 +7,15 @@ CFLAGS=
EXE=
SRCDIR=
SRCTOP=
TEST_LDFLAGS=-L.. ../libz.a
LIBNAME=
TEST_LDFLAGS=-L.. ../$(LIBNAME).a
WITH_FUZZERS=
COMPATTESTS =
QEMU_RUN=
QEMU_VER:=$(shell command -v $(QEMU_RUN) --version 2> /dev/null)
all: oldtests cvetests $(COMPATTESTS) fuzzer
all: oldtests cvetests $(COMPATTESTS) fuzzer ghtests
oldtests: #set by ../configure
check_cross_dep:
@@ -45,35 +46,28 @@ fuzzer:
endif
teststatic: check_cross_dep
@TMPST=tmpst_$$; \
if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) | ${QEMU_RUN} ../minigzip$(EXE) -d && ${QEMU_RUN} ../example$(EXE) $$TMPST ; then \
@TMPST=tmpst_$$$$; \
HELLOST=tmphellost_$$$$; \
if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${QEMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${QEMU_RUN} ../example$(EXE) $$TMPST && ${QEMU_RUN} ../adler32_test$(EXE); then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; exit 1; \
fi
@rm -f tmpst_$$
fi; \
rm -f $$TMPST $$HELLOST
testshared: check_cross_dep
@LD_LIBRARY_PATH=`pwd`/..:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
LD_LIBRARYN32_PATH=`pwd`/..:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
DYLD_LIBRARY_PATH=`pwd`/..:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
SHLIB_PATH=`pwd`/..:$(SHLIB_PATH) ; export SHLIB_PATH; \
TMPSH=tmpsh_$$; \
if echo hello world | ${QEMU_RUN} ../minigzipsh$(EXE) | ${QEMU_RUN} ../minigzipsh$(EXE) -d && ${QEMU_RUN} ../examplesh$(EXE) $$TMPSH; then \
TMPSH=tmpsh_$$$$; \
HELLOSH=tmphellosh_$$$$; \
if echo hello world | ${QEMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${QEMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${QEMU_RUN} ../examplesh$(EXE) $$TMPSH && ${QEMU_RUN} ../adler32_testsh$(EXE); then \
echo ' *** zlib shared test OK ***'; \
else \
echo ' *** zlib shared test FAILED ***'; exit 1; \
fi
@rm -f tmpsh_$$
test64: check_cross_dep
@TMP64=tmp64_$$; \
if echo hello world | ${QEMU_RUN} ../minigzip64$(EXE) | ${QEMU_RUN} ../minigzip64$(EXE) -d && ${QEMU_RUN} ../example64$(EXE) $$TMP64; then \
echo ' *** zlib 64-bit test OK ***'; \
else \
echo ' *** zlib 64-bit test FAILED ***'; exit 1; \
fi
@rm -f tmp64_$$
fi; \
rm -f $$TMPSH $$HELLOSH
cvetests: testCVEinputs
@@ -96,10 +90,27 @@ CVE-2003-0107.o: $(SRCDIR)/CVE-2003-0107.c
CVE-2003-0107$(EXE): CVE-2003-0107.o
$(CC) $(CFLAGS) -o $@ CVE-2003-0107.o $(TEST_LDFLAGS)
.PHONY: ghtests
ghtests: testGH-361 testGH-364 testGH-751
.PHONY: testGH-361
testGH-361:
$(QEMU_RUN) ../minigzip$(EXE) -4 <$(SRCDIR)/GH-361/test.txt >/dev/null
switchlevels$(EXE): $(SRCDIR)/switchlevels.c
$(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS)
.PHONY: testGH-364
testGH-364: switchlevels$(EXE)
$(QEMU_RUN) ./switchlevels$(EXE) 1 5 9 3 <$(SRCDIR)/GH-364/test.bin >/dev/null
.PHONY: testGH-751
testGH-751:
$(QEMU_RUN) ../minigzip$(EXE) <$(SRCDIR)/GH-751/test.txt | $(QEMU_RUN) ../minigzip$(EXE) -d >/dev/null
clean:
rm -f *.o *.gcda *.gcno *.gcov
rm -f CVE-2003-0107$(EXE)
rm -f CVE-2003-0107$(EXE) switchlevels$(EXE)
distclean:
rm -f Makefile
+36
View File
@@ -0,0 +1,36 @@
Contents
--------
|Name|Description|
|-|-|
|[CVE-2003-0107.c](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT|
|[CVE-2002-0059](https://nvd.nist.gov/vuln/detail/CVE-2002-0059)|inflateEnd to release memory more than once|
|[CVE-2004-0797](https://nvd.nist.gov/vuln/detail/CVE-2004-0797)|Error handling in inflate and inflateBack causes crash|
|[CVE-2005-1849](https://nvd.nist.gov/vuln/detail/CVE-2005-1849)|inftrees.h bug causes crash|
|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description
|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches|
|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels|
|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick|
Copying
-------
Some of the files in _test_ are licensed differently:
- test/data/fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and
is licensed under the Creative Commons Attribution 3.0 license
(CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/
for more information.
- test/data/paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper
“Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA
Replication Timing in _Drosophila_” by Federico Comoglio and Renato Paro,
which is licensed under the CC-BY license. See
http://www.ploscompbiol.org/static/license for more information.
- test/data/lcet10.txt is from Project Gutenberg. It does not have expired
copyright, but is still in the public domain according to the license information.
(http://www.gutenberg.org/ebooks/53).
- test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri
that reproduced GH-382. It is licensed under the terms of the zlib license.
+12
View File
@@ -0,0 +1,12 @@
# See https://sourceware.org/libabigail/manual/libabigail-concepts.html#suppression-specifications
[suppress_type]
name = internal_state
[suppress_type]
name_regexp = z_stream.*
# Size varies with version number
[suppress_variable]
name = zlibng_string
@@ -0,0 +1,119 @@
<abi-corpus path='btmp1/libz.so.1.2.11' architecture='elf-arm' soname='libz.so.1'>
<elf-needed>
<dependency name='libc.so.6'/>
<dependency name='ld-linux-armhf.so.3'/>
</elf-needed>
<elf-function-symbols>
<elf-symbol name='adler32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='adler32_combine64' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='adler32_combine' version='ZLIB_1.2.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='adler32_z' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='compress' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='compress2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='compressBound' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='crc32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='crc32_combine64' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='crc32_combine' version='ZLIB_1.2.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='crc32_z' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateBound' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateCopy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateGetDictionary' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateInit2_' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateInit_' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateParams' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflatePending' version='ZLIB_1.2.5.1' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflatePrime' version='ZLIB_1.2.0.8' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateReset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateResetKeep' version='ZLIB_1.2.5.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateSetDictionary' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateSetHeader' version='ZLIB_1.2.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='deflateTune' version='ZLIB_1.2.2.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_crc_table' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzbuffer' version='ZLIB_1.2.3.5' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzclearerr' version='ZLIB_1.2.0.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzclose' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzclose_r' version='ZLIB_1.2.3.5' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzclose_w' version='ZLIB_1.2.3.5' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzdirect' version='ZLIB_1.2.2.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzdopen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzeof' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzerror' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzflush' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzfread' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzfwrite' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzgetc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzgetc_' version='ZLIB_1.2.5.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzgets' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzoffset64' version='ZLIB_1.2.3.5' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzoffset' version='ZLIB_1.2.3.5' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzopen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzopen64' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzputc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzputs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzrewind' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzseek' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzseek64' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzsetparams' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gztell' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gztell64' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzungetc' version='ZLIB_1.2.0.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzvprintf' version='ZLIB_1.2.7.1' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gzwrite' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateBack' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateBackEnd' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateBackInit_' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateCodesUsed' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateCopy' version='ZLIB_1.2.0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateGetDictionary' version='ZLIB_1.2.7.1' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateGetHeader' version='ZLIB_1.2.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateInit2_' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateInit_' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateMark' version='ZLIB_1.2.3.4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflatePrime' version='ZLIB_1.2.2.4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateReset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateReset2' version='ZLIB_1.2.3.4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateResetKeep' version='ZLIB_1.2.5.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateSetDictionary' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateSync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateSyncPoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateUndermine' version='ZLIB_1.2.3.3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='inflateValidate' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='uncompress' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='uncompress2' version='ZLIB_1.2.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zlibCompileFlags' version='ZLIB_1.2.0.2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zlibVersion' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr version='1.0' address-size='32' path='src.d/trees.c' comp-dir-path='/home/dank/src/zlib-ng/btmp1' language='LANG_C99'>
<type-decl name='unsigned char' size-in-bits='8' id='type-id-1'/>
<typedef-decl name='uch' type-id='type-id-1' filepath='src.d/zutil.h' line='43' column='1' id='type-id-2'/>
<qualified-type-def type-id='type-id-2' const='yes' id='type-id-3'/>
<array-type-def dimensions='1' type-id='type-id-3' size-in-bits='infinite' id='type-id-4'>
<subrange length='infinite' id='type-id-5'/>
</array-type-def>
<qualified-type-def type-id='type-id-4' const='yes' id='type-id-6'/>
<var-decl name='_dist_code' type-id='type-id-6' visibility='default' filepath='src.d/deflate.h' line='323' column='1'/>
<var-decl name='_length_code' type-id='type-id-6' visibility='default' filepath='src.d/deflate.h' line='322' column='1'/>
</abi-instr>
<abi-instr version='1.0' address-size='32' path='src.d/zutil.c' comp-dir-path='/home/dank/src/zlib-ng/btmp1' language='LANG_C99'>
<type-decl name='char' size-in-bits='8' id='type-id-7'/>
<pointer-type-def type-id='type-id-7' size-in-bits='32' id='type-id-8'/>
<qualified-type-def type-id='type-id-8' const='yes' id='type-id-9'/>
<type-decl name='unsigned int' size-in-bits='32' id='type-id-10'/>
<array-type-def dimensions='1' type-id='type-id-9' size-in-bits='320' id='type-id-11'>
<subrange length='10' type-id='type-id-10' id='type-id-12'/>
</array-type-def>
<qualified-type-def type-id='type-id-11' const='yes' id='type-id-13'/>
<var-decl name='z_errmsg' type-id='type-id-13' visibility='default' filepath='src.d/zutil.h' line='49' column='1'/>
</abi-instr>
</abi-corpus>
File diff suppressed because it is too large Load Diff
+59
View File
@@ -0,0 +1,59 @@
ABI Compatibility test
----------------------
abicheck.sh uses libabigail to check ABI stability.
It will abort if the current source
tree has a change that breaks binary compatibility.
This protects against the common scenario where:
- an app is compiled against the current zlib-ng
- the system package manager updates the zlib-ng shared library
- the app now crashes because some symbol is
missing or some public structure or parameter
has changed type or size
If run with --zlib-compat, it verifies that the
current source tree generates a library that
is ABI-compatible with the reference release
of classic zlib. This ensures that building
zlib-ng with --zlib-compat does what it says on the tin.
abicheck.sh is not perfect, but it can catch
many common compatibility issues.
Cached files test/abi/*.abi
---------------------------
Comparing to the old version of zlib (or zlib-ng)
means someone has to check out and build
the previous source tree and extract its .abi
using abidw. This can be slow.
If you don't mind the slowness, run abicheck.sh --refresh_if,
and it will download and build the reference version
and extract the .abi on the spot if needed.
(FIXME: should this be the default?)
On the next run, the reference .abi file will already be
present, and that step will be skipped.
It's stored in the tests/abi directory,
in a file with the architecture and git hash in the name.
If you're running continuous integration
which clear out the source tree on each run,
and you don't want your build machines
constantly downloading and building the old
version, you can check the .abi file into git.
To make this easier, a helper script could be written to automatically build
all the configurations tested by .github/worflows/abicheck.yml
Then they could be checked into git en masse by a maintainer
when a new platform is added or a new major version (which
intentionally breaks backwards compatibility) is being prepared.
Further reading
---------------
- https://sourceware.org/libabigail/manual/
- https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/
- https://developers.redhat.com/blog/2020/04/02/how-to-write-an-abi-compliance-checker-using-libabigail/
+164
View File
@@ -0,0 +1,164 @@
#!/bin/sh
set -ex
TESTDIR="$(cd $(dirname "$0"); pwd)"
usage() {
cat <<_EOF_
Usage: $0 [--zlib-compat][--refresh][--refresh-if]
Build shared library with -ggdb, then compare its ABI to the stable
ABI, and abort if differences found.
Options:
--zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng.
--refresh - build the reference library and extract its ABI rather than using a stored ABI file.
--refresh-if - refresh only if ABI file not present.
Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS.
Requires libabigail (on Ubuntu, install package abigail-tools).
_EOF_
}
# Print the multiarch tuple for the current (non-cross) machine,
# or the empty string if unavailable.
detect_chost() {
dpkg-architecture -qDEB_HOST_MULTIARCH ||
$CC -print-multiarch ||
$CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' ||
true
}
if ! test -f "configure"
then
echo "Please run from top of source tree"
exit 1
fi
suffix="-ng"
CONFIGURE_ARGS_NG="$CONFIGURE_ARGS"
refresh=false
refresh_if=false
for arg
do
case "$arg" in
--zlib-compat)
suffix=""
CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat"
;;
--refresh)
refresh=true
;;
--refresh_if)
refresh_if=true
;;
--help)
usage
exit 0
;;
*)
echo "Unknown arg '$arg'"
usage
exit 1
;;
esac
done
# Choose reference repo and commit
if test "$suffix" = ""
then
# Reference is zlib 1.2.11
ABI_GIT_REPO=https://github.com/madler/zlib.git
ABI_GIT_COMMIT=v1.2.11
else
# Reference should be the tag for zlib-ng 2.0
# but until that bright, shining day, use some
# random recent SHA. Annoyingly, can't shorten it.
ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git
ABI_GIT_COMMIT=56ce27343bf295ae9457f8e3d38ec96d2f949a1c
fi
# FIXME: even when using a tag, check the hash.
# Test compat build for ABI compatibility with zlib
if test "$CHOST" = ""
then
# Note: don't export CHOST here, as we don't want configure seeing it
# when it's just the name for the build machine.
# Leave it as a plain shell variable, not an environment variable.
CHOST=$(detect_chost)
# Support -m32 for non-cross builds.
case "$CFLAGS" in
*-m32*) M32="-m32";;
*) M32="";;
esac
fi
# Canonicalize CHOST to work around bug in original zlib's configure
export CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST)
if test "$CHOST" = ""
then
echo "abicheck: SKIP, as we don't know CHOST"
exit 0
fi
ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi"
if ! $refresh && $refresh_if && ! test -f "$ABIFILE"
then
refresh=true
fi
abidw --version
if $refresh
then
# Check out reference source
rm -rf btmp1
mkdir -p btmp1/src.d
cd btmp1/src.d
git init
git remote add origin $ABI_GIT_REPO
git fetch origin $ABI_GIT_COMMIT
git reset --hard FETCH_HEAD
cd ..
# Build unstripped, uninstalled, very debug shared library
CFLAGS="$CFLAGS -ggdb" sh src.d/configure $CONFIGURE_ARGS
make -j2
cd ..
# Find shared library, extract its abi
dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
abidw $dylib1 > "$ABIFILE"
# Maintainers may wish to check $ABIFILE into git when a new
# target is added, or when a major release happens that is
# intended to change the ABI. Alternately, this script could
# just always rebuild the reference source, and dispense with
# caching abi files in git (but that would slow builds down).
fi
if test -f "$ABIFILE"
then
ABIFILE="$ABIFILE"
else
echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh_if"
exit 0
fi
# Build unstripped, uninstalled, very debug shared library
rm -rf btmp2
mkdir btmp2
cd btmp2
CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG
make -j2
cd ..
# Find shared library, extract its abi
dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
abidw $dylib2 > btmp2/zlib${suffix}-built.abi
# Compare it to the reference
# FIXME: use --no-added-syms for now, but we probably want to be more strict.
if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi
then
echo "abicheck: PASS"
else
echo "abicheck: FAIL"
exit 1
fi
+365
View File
@@ -0,0 +1,365 @@
/* adler32_test.c -- unit test for adler32 in the zlib compression library
* Copyright (C) 2020 IBM Corporation
* Author: Rogerio Alves <rcardoso@linux.ibm.com>
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
typedef struct {
uint32_t line;
uint32_t adler;
const uint8_t *buf;
uint32_t len;
uint32_t expect;
} adler32_test;
void test_adler32(uint32_t adler, const uint8_t *buf, uint32_t len, uint32_t chk, uint32_t line) {
uint32_t res = PREFIX(adler32)(adler, buf, len);
if (res != chk) {
fprintf(stderr, "FAIL [%d]: adler32 returned 0x%08X expected 0x%08X\n",
line, res, chk);
exit(1);
}
}
static const uint8_t long_string[5552] = {
'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q',
'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k',
'A','x','N','Q','R','k','d','V','5','y','n','U','N','W','Q','Y','i','W','5','9','R','p','D','C','x','p','u','h','C','a','m','r',
'z','n','z','A','d','J','6','u','N','e','r','x','7','Q','3','v','V','h','H','S','H','S','f','K','f','e','E','T','9','J','f','K',
'w','t','x','J','2','y','7','B','x','X','X','p','G','b','T','g','3','k','U','6','E','Z','M','t','J','q','v','n','S','T','6','x',
'5','x','4','P','z','p','M','F','V','b','d','m','f','G','n','J','m','w','z','K','8','a','q','E','D','e','b','3','h','B','V','g',
'y','3','P','L','5','8','r','z','X','b','Q','g','H','7','L','c','Z','B','3','C','4','y','t','u','k','z','h','v','C','Y','p','p',
'8','H','v','5','X','w','4','L','R','V','V','4','U','C','8','4','T','E','a','N','Z','S','7','U','u','z','f','H','p','P','J','u',
'Y','Z','h','T','6','e','v','z','V','F','h','u','y','H','b','k','J','M','f','3','6','g','y','L','E','W','t','B','B','d','d','9',
'u','M','Z','k','F','G','f','h','q','k','5','k','f','r','M','7','c','M','7','y','n','u','8','b','d','7','Q','f','E','m','F','K',
'x','W','f','B','2','F','8','5','q','z','y','3','R','i','U','m','X','k','h','N','J','y','B','C','h','u','x','4','f','k','J','5',
'6','X','T','W','h','8','J','4','m','K','p','N','3','g','C','g','A','E','e','Z','x','A','P','2','E','4','t','Q','5','X','Y','j',
'6','m','b','h','G','a','v','6','t','v','6','C','M','G','P','u','B','C','A','V','b','2','9','d','2','c','5','a','b','X','w','V',
'G','6','a','7','c','8','G','6','K','U','Q','m','w','P','V','5','N','x','b','v','x','E','N','C','A','N','t','v','N','B','z','X',
'B','R','q','U','n','i','A','Q','d','m','a','D','7','Y','f','3','J','8','Y','m','w','Z','b','w','r','H','q','E','j','c','u','E',
'i','i','S','b','n','G','P','a','F','j','c','R','D','D','G','F','v','i','a','i','M','7','B','e','w','m','L','E','F','2','Y','4',
'4','7','Y','C','t','y','q','7','2','V','G','m','m','E','e','V','u','m','L','p','R','X','W','z','V','K','E','k','p','V','r','J',
'd','N','3','t','i','u','S','V','w','2','w','U','Q','3','F','q','4','h','q','k','B','7','R','X','B','F','Q','Z','b','b','4','E',
'K','v','T','B','w','k','V','C','x','d','K','g','N','S','u','k','p','9','z','w','c','y','U','M','V','E','2','Y','P','F','h','9',
'T','y','h','w','b','9','P','w','G','c','W','W','k','j','J','Q','N','B','U','G','6','9','U','b','v','a','N','9','N','C','G','n',
'x','R','6','9','Q','C','h','e','j','P','U','h','U','R','i','4','T','B','W','5','w','m','J','p','e','7','r','9','t','c','9','Z',
'j','p','r','F','C','e','U','P','x','T','A','N','7','6','a','i','y','e','w','F','C','X','H','Y','G','C','q','q','m','A','t','7',
'z','u','D','S','L','U','C','f','7','e','t','G','V','F','u','c','x','5','M','7','N','i','M','6','h','2','n','H','S','h','K','M',
'd','T','z','X','d','x','x','4','q','z','d','D','a','2','X','r','p','r','R','m','U','U','y','S','H','c','a','F','e','Z','a','U',
'P','9','V','J','e','q','j','Y','M','x','e','v','K','7','M','P','N','2','b','6','f','P','h','H','4','U','X','k','n','f','Q','M',
'9','9','a','J','N','e','w','y','f','F','P','p','a','F','Y','a','M','L','W','i','T','M','B','3','U','v','X','v','G','p','7','a',
'f','u','4','S','y','X','9','g','g','b','B','G','c','i','M','U','n','m','a','7','q','f','9','n','Q','2','V','L','6','e','T','R',
'2','4','9','d','6','Q','B','Y','q','2','4','9','G','Q','E','b','Y','5','u','2','T','Q','G','L','5','n','4','Y','2','y','G','F',
'j','c','8','M','G','L','e','3','a','N','v','A','A','W','t','R','S','2','i','D','R','8','j','d','Q','3','6','C','V','M','e','w',
'j','U','Z','w','M','4','b','m','8','J','P','Q','L','P','R','c','r','b','V','C','3','N','8','K','4','d','W','D','N','U','A','A',
'2','J','p','b','D','d','p','j','N','C','k','A','j','B','a','c','u','v','L','X','U','B','4','U','X','W','e','C','b','C','u','d',
'A','v','U','z','P','t','D','e','5','y','Y','c','x','K','4','7','j','e','e','D','M','5','K','B','Q','6','d','p','T','T','R','j',
'M','E','E','M','r','N','6','8','7','q','x','F','S','x','E','U','4','d','B','6','5','W','C','e','m','J','e','5','j','w','V','J',
'w','v','d','7','v','f','K','u','m','8','h','W','T','e','Q','j','M','8','R','Y','d','B','R','2','r','F','j','7','d','E','q','V',
'k','e','j','P','9','3','X','R','p','R','b','A','v','7','4','A','M','2','k','r','E','7','X','3','7','k','5','c','B','7','W','5',
'u','J','B','Q','R','2','V','7','h','Q','h','9','g','G','y','c','c','x','M','z','7','G','2','J','w','v','j','5','9','E','b','k',
'z','W','T','C','b','4','K','R','X','T','k','V','S','G','2','j','d','6','y','E','4','P','H','K','w','a','m','F','Z','x','9','j',
'i','2','d','X','u','a','4','a','M','z','8','p','p','z','g','t','H','5','Y','L','Q','c','R','F','m','E','n','G','X','d','f','7',
'x','8','j','g','J','z','D','S','a','S','h','y','5','h','Y','N','p','w','Y','W','h','E','N','v','8','Q','D','W','Z','k','f','e',
'r','Z','D','7','R','D','T','2','H','X','z','G','X','f','v','E','z','P','v','U','H','e','4','R','W','U','x','t','t','4','w','p',
'r','z','K','9','f','g','h','P','r','f','v','k','h','c','e','5','8','a','L','F','J','M','G','R','a','N','q','S','g','W','e','7',
'R','K','R','A','B','z','6','v','S','p','w','n','e','x','k','E','r','j','f','Y','x','8','9','z','e','T','6','E','G','v','9','f',
'D','A','N','v','y','U','7','D','M','2','E','5','W','G','6','b','9','q','g','Y','F','f','k','q','Q','E','x','Y','C','R','G','6',
'R','h','4','J','d','U','D','b','9','b','8','r','f','V','d','g','b','2','z','Z','d','m','X','v','j','Y','d','w','K','8','G','r',
'v','j','N','y','c','h','u','5','z','g','J','H','a','Z','b','z','G','C','r','P','f','y','P','6','F','P','h','7','9','w','7','y',
'R','3','n','E','h','G','D','4','m','Y','E','q','k','a','f','a','R','B','q','t','W','E','T','p','H','7','k','X','2','d','X','6',
'W','n','H','m','w','M','i','Y','M','E','F','5','R','p','p','y','c','b','q','R','9','Y','t','T','7','w','u','K','M','Q','z','n',
'P','7','g','x','6','R','4','x','N','v','w','M','6','j','K','v','7','a','Y','4','a','M','6','n','z','3','E','2','V','N','4','i',
'E','f','u','W','J','W','e','8','3','Q','e','a','F','P','c','3','P','k','i','z','d','q','m','q','M','a','d','8','D','3','F','M',
'e','d','E','j','z','V','e','d','z','H','D','J','8','X','g','E','i','u','c','7','A','w','S','J','2','A','e','8','r','q','C','m',
'9','9','a','g','2','y','y','P','M','e','8','3','T','r','m','8','j','v','r','p','M','Z','Y','g','a','9','2','d','H','B','m','9',
'4','6','a','Z','V','u','S','H','g','3','X','h','i','N','3','B','S','E','k','9','k','2','9','R','A','i','3','L','X','M','B','S',
'4','S','F','F','F','w','u','d','M','T','9','K','B','7','R','U','R','8','D','8','T','5','U','t','E','R','x','n','x','h','v','k',
'B','N','k','E','U','T','t','p','r','u','Z','h','t','E','4','i','P','z','f','z','q','M','p','f','A','K','2','D','t','j','f','c',
'Y','E','N','M','x','k','g','7','T','U','2','c','d','V','g','2','z','L','i','j','Y','q','b','T','A','y','v','a','t','N','5','t',
'Z','5','n','D','a','y','G','n','P','x','V','k','M','8','t','J','Z','G','g','5','9','R','h','P','P','J','N','X','p','G','J','p',
'2','y','A','v','d','G','U','z','3','V','M','y','q','U','N','M','Y','p','B','Z','U','h','j','q','z','q','x','w','7','d','J','Q',
'u','F','q','3','m','9','c','Q','W','d','6','7','b','V','M','7','P','j','r','k','9','h','R','z','m','b','i','B','u','E','L','9',
'k','v','h','h','W','2','K','e','M','U','Q','p','A','Q','Y','J','G','E','T','U','L','f','q','G','4','z','K','K','y','a','U','W',
'K','D','P','c','N','D','V','S','Y','6','T','p','R','y','y','J','a','T','J','W','Q','9','p','F','P','X','y','k','9','z','z','4',
'G','d','a','z','X','n','h','4','J','P','W','V','D','r','U','m','a','8','a','b','X','F','J','X','L','4','S','X','5','W','p','W',
'h','y','x','B','f','d','C','X','w','7','r','g','V','T','H','a','i','4','N','v','c','w','n','2','3','A','i','A','J','9','N','c',
'z','7','n','n','3','n','h','n','i','R','i','b','E','h','k','U','c','c','U','6','f','x','q','N','y','H','M','e','J','B','U','B',
'r','g','a','8','V','a','G','V','y','u','c','c','v','C','H','W','y','g','z','Q','2','4','k','S','m','f','e','G','H','v','Q','3',
'P','e','f','S','V','P','c','U','e','3','P','x','d','c','7','c','f','g','D','w','2','t','q','y','g','2','Q','V','4','K','a','Q',
'g','B','b','L','x','9','m','a','K','4','i','x','g','Q','M','9','W','N','2','w','p','v','2','k','B','y','9','k','A','c','f','Z',
'D','R','A','S','d','v','w','f','f','q','t','K','3','j','x','D','G','P','n','u','r','v','U','k','A','2','d','R','N','T','G','4',
'B','g','k','t','h','7','J','k','F','A','C','g','W','g','J','F','z','S','Q','c','v','M','b','D','e','H','Q','S','j','v','G','E',
'R','k','f','i','P','E','F','N','6','y','p','b','t','M','c','Q','B','7','g','w','J','7','3','d','V','E','m','z','6','6','P','P',
'd','i','r','J','H','D','H','J','r','b','n','v','z','W','e','u','g','B','u','Z','2','m','D','5','h','F','X','B','2','r','6','w',
'u','Y','4','N','X','K','a','v','V','3','j','B','r','r','C','c','w','R','g','S','8','V','b','F','2','N','M','c','K','8','Y','E',
'E','N','K','X','K','V','B','x','n','Q','p','a','q','f','k','t','z','Y','E','P','Z','y','n','a','c','B','V','a','x','b','d','X',
'r','d','8','P','H','F','v','r','V','5','g','J','w','6','i','h','d','d','p','J','c','c','Y','S','q','W','m','U','5','G','b','H',
'N','z','E','Z','K','E','y','M','c','G','i','d','w','Z','D','N','N','w','S','t','g','y','a','Y','b','H','e','M','N','f','Y','Y',
'7','a','9','b','M','U','k','a','V','k','C','n','a','k','U','H','A','M','i','v','k','t','a','d','i','3','F','d','5','2','A','p',
'U','c','J','U','R','h','G','d','A','Y','v','q','X','c','w','r','x','4','j','3','4','b','F','d','a','L','N','J','3','Z','g','6',
'W','Q','R','u','P','t','M','A','3','F','6','y','K','Y','G','2','t','v','u','p','w','b','G','S','K','5','p','4','d','E','w','6',
'g','t','V','4','b','2','n','b','Z','3','3','f','m','d','2','c','a','m','j','X','U','E','D','6','6','F','w','H','9','7','Z','Y',
'd','X','C','K','i','g','p','F','Y','n','2','b','F','4','R','u','V','k','f','d','J','i','a','b','X','H','7','v','K','a','Q','i',
'W','M','j','M','i','a','i','n','F','h','r','q','4','w','x','m','4','q','y','F','8','w','i','4','D','B','A','L','B','U','u','K',
'v','K','n','a','Q','i','e','k','v','Q','U','5','w','Q','c','r','A','6','M','w','y','g','n','e','v','K','7','W','u','2','y','f',
'Q','u','e','r','y','a','w','V','p','f','Q','z','C','u','i','i','9','S','P','q','L','r','C','H','S','3','E','p','8','S','m','Q',
'S','K','r','V','b','J','R','m','w','c','n','Q','N','Q','4','M','u','f','X','S','f','U','Z','x','U','4','j','K','4','G','z','X',
'7','Q','j','R','h','i','G','m','q','c','V','T','x','U','a','E','b','Q','q','E','i','F','K','7','K','i','R','J','5','Y','F','V',
'B','7','R','8','M','i','f','j','Z','w','j','b','B','u','p','N','Y','r','S','r','f','h','E','J','T','B','P','R','D','V','K','A',
'Z','A','R','j','z','f','B','i','Y','L','F','G','V','Y','w','R','C','P','G','m','9','7','C','5','e','y','w','N','K','N','a','Q',
'j','a','W','3','2','f','G','w','n','M','6','F','u','K','8','g','8','M','G','r','e','9','Z','z','y','2','G','U','k','G','6','m',
'A','D','4','n','b','8','a','q','S','m','S','6','5','R','5','D','5','S','B','g','X','T','8','Q','V','d','A','n','g','y','8','a',
'h','7','K','9','H','D','J','F','w','G','4','w','T','J','F','f','i','8','X','e','B','J','K','H','7','V','y','X','7','E','8','S',
'A','d','b','w','S','8','Y','a','J','d','j','E','V','J','T','E','U','R','5','7','V','M','E','v','D','3','z','5','r','k','z','v',
'e','m','A','7','P','8','j','X','E','f','Q','q','8','D','g','y','8','j','A','e','B','c','c','M','z','k','2','c','q','v','v','y',
'Q','y','h','g','p','v','M','m','m','C','G','D','k','8','u','T','n','Q','H','G','H','f','b','J','j','5','X','c','i','7','7','q',
'b','R','8','b','b','z','f','f','h','Y','Q','7','u','B','X','e','i','j','M','q','C','T','M','v','t','J','J','w','b','F','v','J',
'm','e','2','u','e','8','L','V','G','q','A','j','m','7','m','g','m','5','i','r','p','p','U','y','F','6','f','b','u','6','q','L',
'M','E','t','V','W','C','t','e','p','w','a','n','w','y','X','h','8','e','G','C','H','q','r','X','G','9','c','h','7','k','8','M',
'G','b','a','m','Y','Q','w','8','J','z','a','F','r','4','W','M','j','P','q','a','z','U','y','u','3','b','Z','f','Y','5','7','g',
'N','M','h','M','a','3','C','K','6','6','f','a','p','i','f','q','k','T','i','z','w','f','Z','c','H','L','X','g','6','m','g','r',
'w','Y','u','K','8','L','p','8','P','R','A','R','A','b','Z','V','a','x','V','c','G','A','H','t','Y','6','P','T','L','W','N','z',
'g','z','k','d','E','v','C','t','Z','M','Z','K','4','w','9','5','D','W','f','U','8','5','u','6','b','5','B','8','g','y','C','E',
'Q','z','e','9','p','N','S','P','D','D','f','x','k','Z','4','R','v','X','V','k','p','b','n','t','c','F','R','e','x','9','C','D',
'J','2','6','f','Z','D','w','J','R','j','j','9','b','w','N','N','p','R','f','Z','z','j','F','r','Q','e','F','x','f','t','V','V',
'A','y','J','G','W','Z','H','r','D','5','M','u','H','V','L','N','U','V','X','z','j','9','r','v','e','d','R','c','u','V','x','r',
'c','6','k','L','h','q','w','U','W','Q','g','G','F','C','t','E','a','D','h','x','9','5','P','R','Z','E','M','5','f','4','2','t',
'A','6','f','r','X','G','X','Y','B','8','G','E','n','B','v','x','f','M','R','f','B','z','Y','3','2','q','z','G','t','P','C','6',
'6','r','z','J','r','c','n','d','6','h','e','w','D','D','h','V','L','u','i','b','5','K','d','S','y','9','N','p','E','r','D','k',
'B','z','u','v','d','Q','p','K','5','m','J','r','b','Y','Z','7','p','M','J','F','E','q','x','f','E','K','U','U','4','f','a','6',
'g','5','a','q','D','U','8','F','y','R','a','P','5','5','x','z','6','V','T','P','D','m','y','7','U','5','C','A','7','Q','h','w',
'r','6','x','g','Q','i','b','K','F','p','B','X','Q','h','i','E','r','C','z','v','x','W','Q','6','p','6','b','M','K','V','x','u',
'k','d','R','S','k','Q','p','n','h','d','Q','Y','x','n','x','5','K','t','5','w','A','5','p','k','F','z','W','p','j','U','y','V',
'x','G','m','y','L','A','X','H','G','A','a','J','5','E','P','q','E','U','7','p','6','A','9','n','d','G','D','g','i','h','t','W',
'b','c','E','2','P','d','y','J','M','u','4','g','P','S','X','J','v','w','3','v','D','q','U','i','U','T','q','E','Y','5','2','t',
'b','j','P','2','j','D','9','y','i','B','5','Y','3','X','L','w','m','V','X','z','X','r','Z','d','H','L','A','H','k','R','X','5',
'i','L','m','q','3','p','a','G','P','j','g','h','R','P','Y','U','z','M','5','R','M','A','E','Q','V','c','w','r','4','M','S','k',
'N','D','i','R','R','x','t','q','T','i','u','N','K','R','x','Z','K','a','g','G','y','9','c','j','J','S','9','3','H','T','f','F',
'q','6','D','W','F','K','h','e','p','p','b','q','N','k','A','C','m','y','u','B','J','v','q','D','e','j','e','b','2','w','R','t',
'J','N','j','F','T','A','8','L','m','X','i','T','g','j','c','V','4','V','h','2','h','R','p','2','9','k','c','c','G','D','h','z',
't','i','h','t','W','R','n','Y','i','8','u','6','G','9','T','P','9','9','J','P','Y','R','h','X','K','z','h','L','W','r','C','U',
'2','L','T','k','2','m','6','W','L','P','T','Z','z','t','i','H','5','G','w','t','E','v','z','k','b','H','b','b','W','W','u','b',
'i','h','C','Q','n','H','N','u','5','u','K','X','r','M','W','U','3','Y','k','P','2','k','x','f','x','C','w','z','z','b','G','8',
'y','W','e','j','v','2','v','r','t','q','z','p','Y','d','w','6','Z','D','J','L','9','F','z','G','U','4','a','8','H','6','U','a',
'q','7','y','Q','J','v','m','D','P','S','j','q','v','t','n','t','g','j','3','t','8','f','K','K','7','b','W','d','F','i','N','K',
'a','R','V','V','V','v','m','A','Q','2','y','j','c','t','f','k','j','7','X','y','j','b','U','F','w','W','3','9','6','A','S','J',
'p','q','2','Z','7','L','p','b','7','b','5','i','p','r','r','h','P','M','h','j','c','y','e','u','h','B','d','9','9','u','f','d',
'g','u','p','w','u','9','S','c','L','U','g','A','y','V','F','V','6','D','D','X','i','V','m','u','Y','P','J','v','L','T','A','F',
'M','Q','H','Z','6','v','8','p','A','L','P','z','C','V','a','C','h','X','j','W','8','G','z','j','d','M','4','u','x','w','H','g',
'V','q','K','z','b','g','2','3','D','N','y','G','X','F','T','v','T','L','y','v','L','9','g','c','C','R','8','L','A','7','Y','N',
't','n','R','6','b','n','m','9','i','h','t','T','F','a','V','N','J','J','3','J','q','p','W','7','b','T','G','r','M','k','a','7',
'D','H','v','y','T','A','C','U','P','u','q','L','R','Y','4','q','h','y','f','F','J','x','K','7','N','B','v','3','a','Z','M','t',
'U','x','8','9','V','E','t','j','K','r','u','Y','Y','A','u','w','Y','2','y','Q','z','S','n','J','B','2','t','X','x','K','z','g',
'6','d','n','i','7','Z','N','F','Q','6','w','N','r','b','k','d','W','X','S','t','c','U','m','6','4','2','e','w','6','x','Z','a',
'Q','A','7','4','h','H','z','r','e','J','q','j','w','4','q','c','i','R','4','x','n','r','j','r','P','g','E','7','t','k','b','Z',
'r','A','b','d','g','i','G','V','D','E','U','L','b','J','U','q','2','S','K','m','A','U','L','k','Q','4','N','p','k','G','C','6',
'R','Z','B','y','B','B','j','y','x','L','d','h','L','G','6','x','H','z','T','5','d','Y','4','2','m','q','Q','y','H','6','c','N',
'u','m','U','v','i','Y','Z','7','4','L','K','F','b','v','2','Y','h','x','8','a','R','w','q','x','E','a','T','y','m','C','2','Q',
'U','T','D','Q','v','u','M','9','D','8','r','8','b','m','p','E','7','C','T','9','B','A','G','k','b','G','z','Z','G','L','N','k',
'h','3','k','J','e','f','d','x','F','8','W','K','7','T','6','h','H','V','C','h','P','u','H','e','v','w','z','P','K','r','D','G',
'X','Z','B','X','f','H','Q','4','e','D','y','W','Z','6','4','K','A','e','a','F','S','N','h','x','S','W','J','c','E','P','g','j',
'a','w','T','m','Z','X','E','P','Y','R','M','2','R','2','X','N','F','X','Y','W','x','z','p','J','g','n','D','4','i','p','6','N',
'r','9','G','k','E','h','T','h','U','h','x','B','Q','9','H','7','w','U','P','Q','d','G','6','q','p','j','j','v','C','a','X','J',
'N','G','Y','w','f','H','C','x','F','k','z','3','9','r','h','8','7','5','V','i','V','C','R','q','x','N','2','2','i','W','F','U',
'7','T','H','f','z','E','a','n','u','Q','t','U','Y','G','t','3','A','m','r','6','d','f','e','n','e','z','F','u','U','N','8','m',
'h','p','R','N','S','H','6','6','V','M','S','t','q','P','E','i','u','y','g','8','L','Q','Y','Y','G','e','W','W','C','G','y','b',
'y','t','u','P','R','P','5','m','N','K','B','Z','w','f','t','k','x','3','L','b','q','d','w','S','G','E','h','R','F','4','q','e',
'5','6','F','2','n','q','T','R','y','f','n','Y','h','2','F','u','x','M','i','i','h','w','G','C','Z','v','i','C','a','X','U','C',
'Y','8','d','h','R','x','V','n','v','G','i','D','a','U','p','U','a','e','b','F','w','P','d','X','n','K','h','9','H','r','b','g',
'2','f','m','X','k','m','q','6','n','5','b','G','H','d','R','9','D','U','c','r','Z','Y','W','S','Z','x','p','t','x','y','4','k',
'j','F','U','t','C','i','e','i','b','p','e','4','C','z','h','3','3','5','Q','P','n','G','i','A','8','c','Q','z','B','a','V','4',
'2','B','2','z','u','u','3','i','L','w','y','g','K','H','k','y','2','B','b','e','5','e','4','e','U','4','z','n','P','z','a','c',
'E','f','u','M','G','C','g','z','j','4','E','7','R','t','D','K','c','t','p','g','W','H','C','H','J','Q','J','c','F','5','4','W',
'K','7','j','h','A','T','K','z','t','S','f','f','j','C','c','8','n','7','c','T','U','R','Q','E','7','A','W','Z','z','K','5','j',
'2','H','k','a','j','g','g','W','w','4','T','A','9','J','U','e','S','N','P','K','d','k','L','Q','G','Z','e','W','i','H','u','j',
'C','z','4','E','2','v','5','L','u','9','Z','a','9','A','b','C','M','G','X','B','C','2','Y','Z','e','U','n','E','5','Y','n','y',
'F','h','H','p','9','j','Y','F','V','w','Y','r','8','Q','f','C','J','4','T','t','z','Q','N','M','e','7','4','3','y','E','M','m',
'b','S','c','h','w','a','X','E','d','E','z','t','h','9','k','p','A','k','K','H','x','q','K','Z','B','u','a','9','3','U','U','u',
'8','E','D','v','y','k','W','Y','X','k','r','R','D','X','n','Q','V','d','e','D','g','x','E','V','Y','w','k','m','K','r','H','D',
't','2','6','N','U','g','3','t','B','9','t','u','M','D','z','Y','K','z','K','r','V','5','i','e','p','M','d','t','w','6','a','f',
'f','W','k','L','i','g','M','V','M','Y','b','x','e','4','h','h','Y','g','w','Z','m','e','e','6','R','W','M','x','G','y','V','n',
'6','e','g','A','g','K','a','N','7','p','a','u','E','4','6','M','t','X','h','g','b','j','p','5','x','x','B','P','3','J','M','7',
'j','Z','P','y','e','Q','Z','e','t','j','3','t','F','V','x','m','b','b','B','y','J','L','L','9','3','R','a','5','j','S','V','t',
'e','2','6','m','H','w','r','w','r','6','Q','3','x','z','m','A','d','x','t','E','H','c','Z','x','c','P','j','r','u','U','W','k',
'6','g','X','g','n','f','n','7','H','M','B','t','v','6','v','x','g','M','f','e','2','w','m','y','d','H','S','q','c','K','U','H',
'2','X','h','d','p','Q','7','J','X','i','X','f','a','z','V','A','F','2','8','z','v','h','C','h','e','4','g','z','w','z','h','q',
'p','6','B','n','m','8','h','W','U','7','z','h','T','6','J','f','4','Z','n','Q','W','z','2','N','4','t','g','7','u','4','X','2',
'C','F','L','n','J','n','m','j','3','P','3','Y','e','J','R','A','H','e','R','D','z','7','u','X','Y','y','D','w','J','m','G','U',
'P','H','5','S','d','a','F','F','Y','c','M','f','3','3','L','v','V','B','U','C','A','d','N','H','Q','h','7','8','4','r','p','G',
'v','M','D','H','7','e','E','r','i','K','Q','i','B','D','M','Z','p','c','R','G','u','c','H','a','N','k','E','f','9','R','7','x',
'6','3','5','u','x','3','h','v','p','6','q','r','j','u','f','W','T','q','P','n','Y','L','B','6','U','w','P','2','T','W','R','g',
'2','3','3','e','N','V','a','j','b','e','4','T','u','J','u','u','F','B','D','G','H','x','x','k','5','G','e','3','4','B','m','L',
'S','b','i','t','T','p','M','D','Z','A','A','i','r','J','p','4','H','U','A','G','y','d','Q','5','U','R','F','8','q','a','S','H',
'n','5','z','9','g','3','u','R','H','m','G','m','b','p','c','L','Z','Y','u','m','i','K','A','Q','R','T','X','G','t','b','8','7',
'7','6','w','M','N','f','R','G','r','L','m','q','n','7','5','k','X','8','g','u','K','7','Y','w','K','q','U','e','W','A','r','i',
'Z','a','p','q','L','5','P','u','n','t','y','G','x','C','N','X','q','P','r','U','v','A','r','r','q','e','f','c','z','M','7','N',
'6','a','z','Z','a','t','f','p','4','v','J','Y','j','h','M','D','t','k','A','B','p','Q','A','y','x','X','7','p','S','8','m','M',
'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'};
static const adler32_test tests[] = {
{__LINE__, 0x1, (const uint8_t *)0x0, 0, 0x1},
{__LINE__, 0x1, (const uint8_t *)"", 1, 0x10001},
{__LINE__, 0x1, (const uint8_t *)"a", 1, 0x620062},
{__LINE__, 0x1, (const uint8_t *)"abacus", 6, 0x8400270},
{__LINE__, 0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4},
{__LINE__, 0x1, (const uint8_t *)"campfire", 8, 0xea10348},
{__LINE__, 0x1, (const uint8_t *)"delta", 5, 0x61a020b},
{__LINE__, 0x1, (const uint8_t *)"executable", 10, 0x16fa0423},
{__LINE__, 0x1, (const uint8_t *)"file", 4, 0x41401a1},
{__LINE__, 0x1, (const uint8_t *)"greatest", 8, 0xefa0360},
{__LINE__, 0x1, (const uint8_t *)"inverter", 8, 0xf6f0370},
{__LINE__, 0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286},
{__LINE__, 0x1, (const uint8_t *)"karate", 6, 0x8a50279},
{__LINE__, 0x1, (const uint8_t *)"landscape", 9, 0x126a03ac},
{__LINE__, 0x1, (const uint8_t *)"machine", 7, 0xb5302d6},
{__LINE__, 0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca},
{__LINE__, 0x1, (const uint8_t *)"oblivion", 8, 0xf220363},
{__LINE__, 0x1, (const uint8_t *)"panama", 6, 0x8a1026f},
{__LINE__, 0x1, (const uint8_t *)"quest", 5, 0x6970233},
{__LINE__, 0x1, (const uint8_t *)"resource", 8, 0xf8d0369},
{__LINE__, 0x1, (const uint8_t *)"secret", 6, 0x8d10287},
{__LINE__, 0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366},
{__LINE__, 0x1, (const uint8_t *)"vector", 6, 0x8fb0294},
{__LINE__, 0x1, (const uint8_t *)"walrus", 6, 0x918029f},
{__LINE__, 0x1, (const uint8_t *)"xeno", 4, 0x45e01bb},
{__LINE__, 0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5},
{__LINE__, 0x1, (const uint8_t *)"zero", 4, 0x46e01c1},
{__LINE__, 0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d},
{__LINE__, 0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f},
{__LINE__, 0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e},
{__LINE__, 0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650},
{__LINE__, 0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690},
{__LINE__, 0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609},
{__LINE__, 0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703},
{__LINE__, 0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7},
{__LINE__, 0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698},
{__LINE__, 0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6},
{__LINE__, 0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c},
{__LINE__, 0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9},
{__LINE__, 0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769},
{__LINE__, 0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5},
{__LINE__, 0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750},
{__LINE__, 0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414},
{__LINE__, 0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405},
{__LINE__, 0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423},
{__LINE__, 0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421},
{__LINE__, 0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b},
{__LINE__, 0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d},
{__LINE__, 0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a},
{__LINE__, 0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d},
{__LINE__, 0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417},
{__LINE__, 0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412},
{__LINE__, 0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420},
{__LINE__, 0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419},
{__LINE__, 0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f},
{__LINE__, 0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f},
{__LINE__, 0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417},
{__LINE__, 0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841},
{__LINE__, 0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751},
{__LINE__, 0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a},
{__LINE__, 0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815},
{__LINE__, 0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661},
{__LINE__, 0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3},
{__LINE__, 0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb},
{__LINE__, 0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680},
{__LINE__, 0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f},
{__LINE__, 0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee},
{__LINE__, 0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92},
{__LINE__, 0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96},
{__LINE__, 0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8},
{__LINE__, 0x1, (const uint8_t *)long_string, 5552, 0x8b81718f},
{__LINE__, 0x7a30360d, (const uint8_t *)0x0, 0, 0x1},
{__LINE__, 0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee},
{__LINE__, 0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea},
{__LINE__, 0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da},
{__LINE__, 0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5},
{__LINE__, 0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44},
{__LINE__, 0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521},
{__LINE__, 0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2},
{__LINE__, 0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a},
{__LINE__, 0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01},
{__LINE__, 0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9},
{__LINE__, 0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4},
{__LINE__, 0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d},
{__LINE__, 0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024},
{__LINE__, 0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b},
{__LINE__, 0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb},
{__LINE__, 0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb},
{__LINE__, 0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f},
{__LINE__, 0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92},
{__LINE__, 0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5},
{__LINE__, 0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390},
{__LINE__, 0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39},
{__LINE__, 0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c},
{__LINE__, 0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516},
{__LINE__, 0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b},
{__LINE__, 0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4},
{__LINE__, 0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00},
{__LINE__, 0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b},
{__LINE__, 0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8},
{__LINE__, 0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c},
{__LINE__, 0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f},
{__LINE__, 0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f},
{__LINE__, 0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd},
{__LINE__, 0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446},
{__LINE__, 0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148},
{__LINE__, 0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc},
{__LINE__, 0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284},
{__LINE__, 0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706},
{__LINE__, 0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a},
{__LINE__, 0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db},
{__LINE__, 0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8},
{__LINE__, 0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd},
{__LINE__, 0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4},
{__LINE__, 0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218},
{__LINE__, 0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38},
{__LINE__, 0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8},
{__LINE__, 0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af},
{__LINE__, 0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c},
{__LINE__, 0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda},
{__LINE__, 0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006},
{__LINE__, 0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c},
{__LINE__, 0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4},
{__LINE__, 0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b},
{__LINE__, 0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3},
{__LINE__, 0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3},
{__LINE__, 0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a},
{__LINE__, 0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0},
{__LINE__, 0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8},
{__LINE__, 0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8},
{__LINE__, 0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54},
{__LINE__, 0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e},
{__LINE__, 0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c},
{__LINE__, 0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c},
{__LINE__, 0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9},
{__LINE__, 0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652},
{__LINE__, 0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e},
{__LINE__, 0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664},
{__LINE__, 0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911},
{__LINE__, 0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73},
{__LINE__, 0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8},
{__LINE__, 0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2},
};
static const int test_size = sizeof(tests) / sizeof(tests[0]);
int main(void) {
int i;
for (i = 0; i < test_size; i++) {
test_adler32(tests[i].adler, tests[i].buf, tests[i].len, tests[i].expect, tests[i].line);
}
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.
+563 -48
View File
@@ -3,20 +3,20 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
#include "deflate.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdint.h>
#define TESTFILE "foo.gz"
@@ -40,7 +40,7 @@ void test_compress (unsigned char *compr, z_size_t comprLen,unsigned char *
void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen);
void test_deflate (unsigned char *compr, size_t comprLen);
void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params);
void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
void test_flush (unsigned char *compr, z_size_t *comprLen);
void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
@@ -55,8 +55,7 @@ static free_func zfree = NULL;
/* ===========================================================================
* Test compress() and uncompress()
*/
void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncompr, z_size_t uncomprLen)
{
void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncompr, z_size_t uncomprLen) {
int err;
size_t len = strlen(hello)+1;
@@ -79,21 +78,24 @@ void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncom
/* ===========================================================================
* Test read/write of .gz files
*/
void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen)
{
void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) {
#ifdef NO_GZCOMPRESS
fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
#else
int err;
int len = (int)strlen(hello)+1;
size_t read;
size_t len = strlen(hello)+1;
gzFile file;
z_off_t pos;
z_off64_t pos;
z_off64_t comprLen;
/* Write gz file with test data */
file = PREFIX(gzopen)(fname, "wb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
/* Write hello, hello! using gzputs and gzprintf */
PREFIX(gzputc)(file, 'h');
if (PREFIX(gzputs)(file, "ello") != 4) {
fprintf(stderr, "gzputs err: %s\n", PREFIX(gzerror)(file, &err));
@@ -103,17 +105,42 @@ void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen)
fprintf(stderr, "gzprintf err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
PREFIX(gzseek)(file, 1L, SEEK_CUR); /* add one zero byte */
/* Write string null-teriminator using gzseek */
if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0)
{
fprintf(stderr, "gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file));
exit(1);
}
/* Write hello, hello! using gzfwrite using best compression level */
if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) {
fprintf(stderr, "gzsetparams err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
if (PREFIX(gzfwrite)(hello, len, 1, file) == 0) {
fprintf(stderr, "gzfwrite err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
/* Flush compressed bytes to file */
if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK) {
fprintf(stderr, "gzflush err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
comprLen = PREFIX(gzoffset)(file);
if (comprLen <= 0) {
fprintf(stderr, "gzoffset err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
PREFIX(gzclose)(file);
/* Open gz file we previously wrote */
file = PREFIX(gzopen)(fname, "rb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
strcpy((char*)uncompr, "garbage");
if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != len) {
/* Read uncompressed data - hello, hello! string twice */
strcpy((char*)uncompr, "garbages");
if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len)) {
fprintf(stderr, "gzread err: %s\n", PREFIX(gzerror)(file, &err));
exit(1);
}
@@ -123,24 +150,28 @@ void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen)
} else {
printf("gzread(): %s\n", (char*)uncompr);
}
pos = PREFIX(gzseek)(file, -8L, SEEK_CUR);
/* Check position at the end of the gz file */
if (PREFIX(gzeof)(file) != 1) {
fprintf(stderr, "gzeof err: not reporting end of stream\n");
exit(1);
}
/* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
if (pos != 6 || PREFIX(gztell)(file) != pos) {
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
(long)pos, (long)PREFIX(gztell)(file));
exit(1);
}
if (PREFIX(gzgetc)(file) != ' ') {
fprintf(stderr, "gzgetc error\n");
exit(1);
}
if (PREFIX(gzungetc)(' ', file) != ' ') {
fprintf(stderr, "gzungetc error\n");
exit(1);
}
/* Read first hello, hello! string with gzgets */
strcpy((char*)uncompr, "garbages");
PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen);
if (strlen((char*)uncompr) != 7) { /* " hello!" */
fprintf(stderr, "gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err));
@@ -152,19 +183,63 @@ void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen)
} else {
printf("gzgets() after gzseek: %s\n", (char*)uncompr);
}
/* Seek to second hello, hello! string */
pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
if (pos != 14 || PREFIX(gztell)(file) != pos) {
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
(long)pos, (long)PREFIX(gztell)(file));
exit(1);
}
/* Check position not at end of file */
if (PREFIX(gzeof)(file) != 0) {
fprintf(stderr, "gzeof err: reporting end of stream\n");
exit(1);
}
/* Read first hello, hello! string with gzfread */
strcpy((char*)uncompr, "garbages");
read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file);
if (strcmp((const char *)uncompr, hello) != 0) {
fprintf(stderr, "bad gzgets\n");
exit(1);
} else {
printf("gzgets(): %s\n", (char*)uncompr);
}
pos = PREFIX(gzoffset)(file);
if (pos < 0 || pos != (comprLen + 10)) {
fprintf(stderr, "gzoffset err: wrong offset at end\n");
exit(1);
}
/* Trigger an error and clear it with gzclearerr */
PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
PREFIX(gzerror)(file, &err);
if (err == 0) {
fprintf(stderr, "gzerror err: no error returned\n");
exit(1);
}
PREFIX(gzclearerr)(file);
PREFIX(gzerror)(file, &err);
if (err != 0) {
fprintf(stderr, "gzclearerr err: not zero %d\n", err);
exit(1);
}
PREFIX(gzclose)(file);
if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR) {
fprintf(stderr, "gzclose unexpected return when handle null\n");
exit(1);
}
(void)read;
#endif
}
/* ===========================================================================
* Test deflate() with small buffers
*/
void test_deflate(unsigned char *compr, size_t comprLen)
{
void test_deflate(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned long len = (unsigned long)strlen(hello)+1;
size_t len = strlen(hello)+1;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
@@ -175,7 +250,7 @@ void test_deflate(unsigned char *compr, size_t comprLen)
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (const unsigned char *)hello;
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
@@ -198,8 +273,7 @@ void test_deflate(unsigned char *compr, size_t comprLen)
/* ===========================================================================
* Test inflate() with small buffers
*/
void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
@@ -241,10 +315,22 @@ static unsigned int diff;
/* ===========================================================================
* Test deflate() with large buffers and dynamic change of compression level
*/
void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
#ifndef ZLIB_COMPAT
int level = -1;
int strategy = -1;
zng_deflate_param_value params[2];
params[0].param = Z_DEFLATE_LEVEL;
params[0].buf = &level;
params[0].size = sizeof(level);
params[1].param = Z_DEFLATE_STRATEGY;
params[1].buf = &strategy;
params[1].size = sizeof(strategy);
#endif
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
@@ -269,7 +355,27 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
}
/* Feed in already compressed data and switch to no compression: */
PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
if (zng_params) {
#ifndef ZLIB_COMPAT
zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
if (level != Z_BEST_SPEED) {
fprintf(stderr, "Expected compression level Z_BEST_SPEED, got %d\n", level);
exit(1);
}
if (strategy != Z_DEFAULT_STRATEGY) {
fprintf(stderr, "Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
exit(1);
}
level = Z_NO_COMPRESSION;
strategy = Z_DEFAULT_STRATEGY;
zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
#else
fprintf(stderr, "test_large_deflate() called with zng_params=1 in compat mode\n");
exit(1);
#endif
} else {
PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
}
c_stream.next_in = compr;
diff = (unsigned int)(c_stream.next_out - compr);
c_stream.avail_in = diff;
@@ -277,7 +383,29 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
CHECK_ERR(err, "deflate");
/* Switch back to compressing mode: */
PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
if (zng_params) {
#ifndef ZLIB_COMPAT
level = -1;
strategy = -1;
zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
if (level != Z_NO_COMPRESSION) {
fprintf(stderr, "Expected compression level Z_NO_COMPRESSION, got %d\n", level);
exit(1);
}
if (strategy != Z_DEFAULT_STRATEGY) {
fprintf(stderr, "Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
exit(1);
}
level = Z_BEST_COMPRESSION;
strategy = Z_FILTERED;
zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
#else
fprintf(stderr, "test_large_deflate() called with zng_params=1 in compat mode\n");
exit(1);
#endif
} else {
PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
}
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
@@ -295,8 +423,7 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
/* ===========================================================================
* Test inflate() with large buffers
*/
void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
@@ -326,7 +453,7 @@ void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *un
CHECK_ERR(err, "inflateEnd");
if (d_stream.total_out != 2*uncomprLen + diff) {
fprintf(stderr, "bad large inflate: %zu\n", d_stream.total_out);
fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
exit(1);
} else {
printf("large_inflate(): OK\n");
@@ -336,8 +463,7 @@ void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *un
/* ===========================================================================
* Test deflate() with full flush
*/
void test_flush(unsigned char *compr, z_size_t *comprLen)
{
void test_flush(unsigned char *compr, z_size_t *comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned int len = (unsigned int)strlen(hello)+1;
@@ -349,7 +475,7 @@ void test_flush(unsigned char *compr, z_size_t *comprLen)
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (const unsigned char *)hello;
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (unsigned int)*comprLen;
@@ -372,8 +498,7 @@ void test_flush(unsigned char *compr, z_size_t *comprLen)
/* ===========================================================================
* Test inflateSync()
*/
void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
@@ -400,9 +525,8 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si
CHECK_ERR(err, "inflateSync");
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err != Z_DATA_ERROR) {
fprintf(stderr, "inflate should report DATA_ERROR\n");
/* Because of incorrect adler32 */
if (err != Z_STREAM_END) {
fprintf(stderr, "inflate should report Z_STREAM_END\n");
exit(1);
}
err = PREFIX(inflateEnd)(&d_stream);
@@ -414,8 +538,7 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si
/* ===========================================================================
* Test deflate() with preset dictionary
*/
void test_dict_deflate(unsigned char *compr, size_t comprLen)
{
void test_dict_deflate(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
@@ -435,7 +558,7 @@ void test_dict_deflate(unsigned char *compr, size_t comprLen)
c_stream.next_out = compr;
c_stream.avail_out = (unsigned int)comprLen;
c_stream.next_in = (const unsigned char *)hello;
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.avail_in = (unsigned int)strlen(hello)+1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
@@ -450,8 +573,7 @@ void test_dict_deflate(unsigned char *compr, size_t comprLen)
/* ===========================================================================
* Test inflate() with a preset dictionary
*/
void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
@@ -495,12 +617,392 @@ void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *unc
}
}
/* ===========================================================================
* Test deflateBound() with small buffers
*/
void test_deflate_bound(void) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned int len = (unsigned int)strlen(hello)+1;
int estimateLen = 0;
unsigned char *outBuf = NULL;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
c_stream.avail_in = len;
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.avail_out = 0;
c_stream.next_out = outBuf;
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
/* calculate actual output length and update structure */
estimateLen = PREFIX(deflateBound)(&c_stream, len);
outBuf = malloc(estimateLen);
if (outBuf != NULL) {
/* update zlib configuration */
c_stream.avail_out = estimateLen;
c_stream.next_out = outBuf;
/* do the compression */
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) {
printf("deflateBound(): OK\n");
} else {
CHECK_ERR(err, "deflate");
}
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
free(outBuf);
}
/* ===========================================================================
* Test deflateCopy() with small buffers
*/
void test_deflate_copy(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */
int err;
size_t len = strlen(hello)+1;
memset(&c_stream, 0, sizeof(c_stream));
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream);
CHECK_ERR(err, "deflate_copy");
if (c_stream.state->status == c_stream_copy.state->status) {
printf("deflate_copy(): OK\n");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd original");
err = PREFIX(deflateEnd)(&c_stream_copy);
CHECK_ERR(err, "deflateEnd copy");
}
/* ===========================================================================
* Test deflateGetDictionary() with small buffers
*/
void test_deflate_get_dict(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned char *dictNew = NULL;
unsigned int *dictLen;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.avail_in = (unsigned int)strlen(hello)+1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1);
}
dictNew = calloc(256, 1);
dictLen = (unsigned int *)calloc(4, 1);
err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen);
CHECK_ERR(err, "deflateGetDictionary");
if (err == Z_OK) {
printf("deflateGetDictionary(): %s\n", dictNew);
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
free(dictNew);
free(dictLen);
}
/* ===========================================================================
* Test deflatePending() with small buffers
*/
void test_deflate_pending(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
int *bits = calloc(256, 1);
unsigned *ped = calloc(256, 1);
size_t len = strlen(hello)+1;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
err = PREFIX(deflatePending)(&c_stream, ped, bits);
CHECK_ERR(err, "deflatePending");
if (*bits >= 0 && *bits <= 7) {
printf("deflatePending(): OK\n");
} else {
printf("deflatePending(): error\n");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
free(bits);
free(ped);
}
/* ===========================================================================
* Test deflatePrime() wrapping gzip around deflate stream
*/
void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
PREFIX3(stream) c_stream; /* compression stream */
PREFIX3(stream) d_stream; /* decompression stream */
int err;
size_t len = strlen(hello)+1;
uint32_t crc = 0;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
/* Raw deflate windowBits is -15 */
err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
CHECK_ERR(err, "deflateInit2");
/* Gzip magic number */
err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f);
CHECK_ERR(err, "deflatePrime");
/* Gzip compression method (deflate) */
err = PREFIX(deflatePrime)(&c_stream, 8, 0x08);
CHECK_ERR(err, "deflatePrime");
/* Gzip flags (one byte, using two odd bit calls) */
err = PREFIX(deflatePrime)(&c_stream, 3, 0x0);
CHECK_ERR(err, "deflatePrime");
err = PREFIX(deflatePrime)(&c_stream, 5, 0x0);
CHECK_ERR(err, "deflatePrime");
/* Gzip modified time */
err = PREFIX(deflatePrime)(&c_stream, 32, 0x0);
CHECK_ERR(err, "deflatePrime");
/* Gzip extra flags */
err = PREFIX(deflatePrime)(&c_stream, 8, 0x0);
CHECK_ERR(err, "deflatePrime");
/* Gzip operating system */
err = PREFIX(deflatePrime)(&c_stream, 8, 255);
CHECK_ERR(err, "deflatePrime");
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.avail_in = (uint32_t)len;
c_stream.next_out = compr;
c_stream.avail_out = (uint32_t)comprLen;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END)
CHECK_ERR(err, "deflate");
/* Gzip uncompressed data crc32 */
crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len);
err = PREFIX(deflatePrime)(&c_stream, 32, crc);
CHECK_ERR(err, "deflatePrime");
/* Gzip uncompressed data length */
err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)len);
CHECK_ERR(err, "deflatePrime");
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.next_in = compr;
d_stream.avail_in = (uint32_t)c_stream.total_out;
d_stream.next_out = uncompr;
d_stream.avail_out = (uint32_t)uncomprLen;
d_stream.total_in = 0;
d_stream.total_out = 0;
/* Inflate with gzip header */
err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32);
CHECK_ERR(err, "inflateInit");
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err != Z_BUF_ERROR) {
CHECK_ERR(err, "inflate");
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (strcmp((const char *)uncompr, hello) != 0) {
fprintf(stderr, "bad deflatePrime\n");
exit(1);
}
if (err == Z_OK) {
printf("deflatePrime(): OK\n");
}
}
/* ===========================================================================
* Test deflateSetHeader() with small buffers
*/
void test_deflate_set_header(unsigned char *compr, size_t comprLen) {
PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header)));
PREFIX3(stream) c_stream; /* compression stream */
int err;
size_t len = strlen(hello)+1;
if (head == NULL) {
printf("out of memory\n");
exit(1);
}
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
/* gzip */
err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
CHECK_ERR(err, "deflateInit2");
head->text = 1;
err = PREFIX(deflateSetHeader)(&c_stream, head);
CHECK_ERR(err, "deflateSetHeader");
if (err == Z_OK) {
printf("deflateSetHeader(): OK\n");
}
c_stream.next_in = (unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
free(head);
}
/* ===========================================================================
* Test deflateTune() with small buffers
*/
void test_deflate_tune(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
int good_length = 3;
int max_lazy = 5;
int nice_length = 18;
int max_chain = 6;
size_t len = strlen(hello)+1;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain);
CHECK_ERR(err, "deflateTune");
if (err == Z_OK) {
printf("deflateTune(): OK\n");
}
c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Usage: example [output.gz [input.gz]]
*/
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
unsigned char *compr, *uncompr;
z_size_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
z_size_t uncomprLen = comprLen;
@@ -535,9 +1037,14 @@ int main(int argc, char *argv[])
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
#ifndef ZLIB_COMPAT
test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
#endif
test_flush(compr, &comprLen);
test_sync(compr, comprLen, uncompr, uncomprLen);
comprLen = uncomprLen;
@@ -545,6 +1052,14 @@ int main(int argc, char *argv[])
test_dict_deflate(compr, comprLen);
test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
test_deflate_bound();
test_deflate_copy(compr, comprLen);
test_deflate_get_dict(compr, comprLen);
test_deflate_set_header(compr, comprLen);
test_deflate_tune(compr, comprLen);
test_deflate_pending(compr, comprLen);
test_deflate_prime(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
+67 -54
View File
@@ -14,60 +14,73 @@
#endif
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
uint32_t crc0 = PREFIX(crc32)(0L, NULL, 0);
uint32_t crc1 = crc0;
uint32_t crc2 = crc0;
uint32_t adler0 = PREFIX(adler32)(0L, NULL, 0);
uint32_t adler1 = adler0;
uint32_t adler2 = adler0;
/* Checksum with a buffer of size equal to the first byte in the input. */
uint32_t buffSize = data[0];
uint32_t offset = 0;
uint32_t op[32];
uint32_t crc0 = PREFIX(crc32)(0L, NULL, 0);
uint32_t crc1 = crc0;
uint32_t crc2 = crc0;
uint32_t adler0 = PREFIX(adler32)(0L, NULL, 0);
uint32_t adler1 = adler0;
uint32_t adler2 = adler0;
uint32_t combine1, combine2;
/* Checksum with a buffer of size equal to the first byte in the input. */
uint32_t buffSize = data[0];
uint32_t offset = 0;
uint32_t op[32];
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (dataLen < 1 || dataLen > kMaxSize)
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (dataLen < 1 || dataLen > kMaxSize)
return 0;
/* Make sure the buffer has at least a byte. */
if (buffSize == 0)
++buffSize;
/* CRC32 */
PREFIX(crc32_combine_gen)(op, buffSize);
for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) {
uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize);
uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op);
crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize);
assert(crc1 == crc4);
(void)crc1;
(void)crc4;
}
crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize);
crc2 = PREFIX(crc32_z)(crc2, data, dataLen);
assert(crc1 == crc2);
(void)crc1;
(void)crc2;
combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen);
combine2 = PREFIX(crc32_combine)(crc1, crc1, (z_off_t)dataLen);
assert(combine1 == combine2);
/* Fast CRC32 combine. */
PREFIX(crc32_combine_gen)(op, (z_off_t)dataLen);
combine1 = PREFIX(crc32_combine_op)(crc1, crc2, op);
combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op);
assert(combine1 == combine2);
combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen);
combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op);
assert(combine1 == combine2);
/* Adler32 */
for (offset = 0; offset + buffSize <= dataLen; offset += buffSize)
adler1 = PREFIX(adler32_z)(adler1, data + offset, buffSize);
adler1 = PREFIX(adler32_z)(adler1, data + offset, dataLen % buffSize);
adler2 = PREFIX(adler32_z)(adler2, data, dataLen);
assert(adler1 == adler2);
(void)adler1;
(void)adler2;
combine1 = PREFIX(adler32_combine)(adler1, adler2, (z_off_t)dataLen);
combine2 = PREFIX(adler32_combine)(adler1, adler1, (z_off_t)dataLen);
assert(combine1 == combine2);
(void)combine1;
(void)combine2;
/* This function must return 0. */
return 0;
/* Make sure the buffer has at least a byte. */
if (buffSize == 0)
++buffSize;
/* CRC32 */
PREFIX(crc32_combine_gen)(op, buffSize);
for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) {
uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize);
uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op);
crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize);
assert(crc1 == crc4);
}
crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize);
crc2 = PREFIX(crc32_z)(crc2, data, dataLen);
assert(crc1 == crc2);
assert(PREFIX(crc32_combine)(crc1, crc2, dataLen) ==
PREFIX(crc32_combine)(crc1, crc1, dataLen));
/* Fast CRC32 combine. */
PREFIX(crc32_combine_gen)(op, dataLen);
assert(PREFIX(crc32_combine_op)(crc1, crc2, op) ==
PREFIX(crc32_combine_op)(crc2, crc1, op));
assert(PREFIX(crc32_combine)(crc1, crc2, dataLen) ==
PREFIX(crc32_combine_op)(crc2, crc1, op));
/* Adler32 */
for (offset = 0; offset + buffSize <= dataLen; offset += buffSize)
adler1 = PREFIX(adler32_z)(adler1, data + offset, buffSize);
adler1 = PREFIX(adler32_z)(adler1, data + offset, dataLen % buffSize);
adler2 = PREFIX(adler32_z)(adler2, data, dataLen);
assert(adler1 == adler2);
assert(PREFIX(adler32_combine)(adler1, adler2, dataLen) ==
PREFIX(adler32_combine)(adler1, adler1, dataLen));
/* This function must return 0. */
return 0;
}
+49 -49
View File
@@ -16,72 +16,72 @@
static const uint8_t *data;
static size_t dataLen;
static void check_compress_level(uint8_t *compr, size_t comprLen,
uint8_t *uncompr, size_t uncomprLen,
static void check_compress_level(uint8_t *compr, z_size_t comprLen,
uint8_t *uncompr, z_size_t uncomprLen,
int level) {
PREFIX(compress2)(compr, &comprLen, data, dataLen, level);
PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen);
PREFIX(compress2)(compr, &comprLen, data, dataLen, level);
PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen);
/* Make sure compress + uncompress gives back the input data. */
assert(dataLen == uncomprLen);
assert(0 == memcmp(data, uncompr, dataLen));
/* Make sure compress + uncompress gives back the input data. */
assert(dataLen == uncomprLen);
assert(0 == memcmp(data, uncompr, dataLen));
}
#define put_byte(s, i, c) {s[i] = (unsigned char)(c);}
static void write_zlib_header(uint8_t *s) {
unsigned level_flags = 0; /* compression level (0..3) */
unsigned w_bits = 8; /* window size log2(w_size) (8..16) */
unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8;
header |= (level_flags << 6);
unsigned level_flags = 0; /* compression level (0..3) */
unsigned w_bits = 8; /* window size log2(w_size) (8..16) */
unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8;
header |= (level_flags << 6);
header += 31 - (header % 31);
header += 31 - (header % 31);
/* s is guaranteed to be longer than 2 bytes. */
put_byte(s, 0, (unsigned char)(header >> 8));
put_byte(s, 1, (unsigned char)(header & 0xff));
/* s is guaranteed to be longer than 2 bytes. */
put_byte(s, 0, (header >> 8));
put_byte(s, 1, (header & 0xff));
}
static void check_decompress(uint8_t *compr, size_t comprLen) {
/* We need to write a valid zlib header of size two bytes. Copy the input data
in a larger buffer. Do not modify the input data to avoid libFuzzer error:
fuzz target overwrites its const input. */
size_t copyLen = dataLen + 2;
uint8_t *copy = (uint8_t *)malloc(copyLen);
memcpy(copy + 2, data, dataLen);
write_zlib_header(copy);
/* We need to write a valid zlib header of size two bytes. Copy the input data
in a larger buffer. Do not modify the input data to avoid libFuzzer error:
fuzz target overwrites its const input. */
size_t copyLen = dataLen + 2;
uint8_t *copy = (uint8_t *)malloc(copyLen);
memcpy(copy + 2, data, dataLen);
write_zlib_header(copy);
PREFIX(uncompress)(compr, &comprLen, copy, copyLen);
free(copy);
PREFIX(uncompress)(compr, &comprLen, copy, copyLen);
free(copy);
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
/* compressBound does not provide enough space for low compression levels. */
size_t comprLen = 100 + 2 * PREFIX(compressBound)(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
/* compressBound does not provide enough space for low compression levels. */
z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size);
z_size_t uncomprLen = (z_size_t)size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (size < 1 || size > kMaxSize)
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 1);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 3);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 6);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 7);
check_decompress(compr, comprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 1);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 3);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 6);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 7);
check_decompress(compr, comprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
}
+62 -63
View File
@@ -24,14 +24,13 @@ static const uint8_t *data;
static size_t dataLen;
static alloc_func zalloc = NULL;
static free_func zfree = NULL;
static size_t dictionaryLen = 0;
static unsigned int dictionaryLen = 0;
static unsigned long dictId; /* Adler32 value of the dictionary */
/* ===========================================================================
* Test deflate() with preset dictionary
*/
void test_dict_deflate(unsigned char **compr, size_t *comprLen)
{
void test_dict_deflate(unsigned char **compr, size_t *comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
int level = data[0] % 11 - 1; /* [-1..9]
@@ -58,7 +57,7 @@ void test_dict_deflate(unsigned char **compr, size_t *comprLen)
/* deflate would fail for no-compression or for speed levels. */
if (level == 0 || level == 1)
level = -1;
level = -1;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
@@ -73,15 +72,15 @@ void test_dict_deflate(unsigned char **compr, size_t *comprLen)
CHECK_ERR(err, "deflateSetDictionary");
/* deflateBound does not provide enough space for low compression levels. */
*comprLen = 100 + 2 * PREFIX(deflateBound)(&c_stream, dataLen);
*comprLen = 100 + 2 * PREFIX(deflateBound)(&c_stream, (unsigned long)dataLen);
*compr = (uint8_t *)calloc(1, *comprLen);
dictId = c_stream.adler;
c_stream.next_out = *compr;
c_stream.avail_out = (unsigned int)(*comprLen);
c_stream.next_in = data;
c_stream.avail_in = dataLen;
c_stream.next_in = (z_const unsigned char *)data;
c_stream.avail_in = (uint32_t)dataLen;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
@@ -96,75 +95,75 @@ void test_dict_deflate(unsigned char **compr, size_t *comprLen)
* Test inflate() with a preset dictionary
*/
void test_dict_inflate(unsigned char *compr, size_t comprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
unsigned char *uncompr;
int err;
PREFIX3(stream) d_stream; /* decompression stream */
unsigned char *uncompr;
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.next_in = compr;
d_stream.avail_in = (unsigned int)comprLen;
d_stream.next_in = compr;
d_stream.avail_in = (unsigned int)comprLen;
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
uncompr = (uint8_t *)calloc(1, dataLen);
d_stream.next_out = uncompr;
d_stream.avail_out = (unsigned int)dataLen;
uncompr = (uint8_t *)calloc(1, dataLen);
d_stream.next_out = uncompr;
d_stream.avail_out = (unsigned int)dataLen;
for (;;) {
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
if (err == Z_NEED_DICT) {
if (d_stream.adler != dictId) {
fprintf(stderr, "unexpected dictionary");
exit(1);
}
err = PREFIX(inflateSetDictionary)(
&d_stream, (const unsigned char *)data, dictionaryLen);
for (;;) {
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
if (err == Z_NEED_DICT) {
if (d_stream.adler != dictId) {
fprintf(stderr, "unexpected dictionary");
exit(1);
}
err = PREFIX(inflateSetDictionary)(
&d_stream, (const unsigned char *)data, dictionaryLen);
}
CHECK_ERR(err, "inflate with dict");
}
CHECK_ERR(err, "inflate with dict");
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (memcmp(uncompr, data, dataLen)) {
fprintf(stderr, "bad inflate with dict\n");
exit(1);
}
if (memcmp(uncompr, data, dataLen)) {
fprintf(stderr, "bad inflate with dict\n");
exit(1);
}
free(uncompr);
free(uncompr);
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
size_t comprLen = 0;
uint8_t *compr;
size_t comprLen = 0;
uint8_t *compr;
/* Discard inputs larger than 100Kb. */
static size_t kMaxSize = 100 * 1024;
/* Discard inputs larger than 100Kb. */
static size_t kMaxSize = 100 * 1024;
if (size < 1 || size > kMaxSize)
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
/* Set up the contents of the dictionary. The size of the dictionary is
intentionally selected to be of unusual size. To help cover more corner
cases, the size of the dictionary is read from the input data. */
dictionaryLen = data[0];
if (dictionaryLen > dataLen)
dictionaryLen = (unsigned int)dataLen;
test_dict_deflate(&compr, &comprLen);
test_dict_inflate(compr, comprLen);
free(compr);
/* This function must return 0. */
return 0;
data = d;
dataLen = size;
/* Set up the contents of the dictionary. The size of the dictionary is
intentionally selected to be of unusual size. To help cover more corner
cases, the size of the dictionary is read from the input data. */
dictionaryLen = data[0];
if (dictionaryLen > dataLen)
dictionaryLen = dataLen;
test_dict_deflate(&compr, &comprLen);
test_dict_inflate(compr, comprLen);
free(compr);
/* This function must return 0. */
return 0;
}
+68 -70
View File
@@ -29,98 +29,96 @@ static free_func zfree = NULL;
* Test deflate() with full flush
*/
void test_flush(unsigned char *compr, z_size_t *comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned int len = dataLen;
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned int len = (unsigned int)dataLen;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (const unsigned char *)data;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (unsigned int)*comprLen;
err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate flush 1");
c_stream.next_in = (z_const unsigned char *)data;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (unsigned int)*comprLen;
err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate flush 1");
compr[3]++; /* force an error in first compressed block */
c_stream.avail_in = len - 3;
compr[3]++; /* force an error in first compressed block */
c_stream.avail_in = len - 3;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
CHECK_ERR(err, "deflate flush 2");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
CHECK_ERR(err, "deflate flush 2");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
*comprLen = (z_size_t)c_stream.total_out;
*comprLen = (z_size_t)c_stream.total_out;
}
/* ===========================================================================
* Test inflateSync()
*/
void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr,
size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.next_in = compr;
d_stream.avail_in = 2; /* just read the zlib header */
d_stream.next_in = compr;
d_stream.avail_in = 2; /* just read the zlib header */
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_out = uncompr;
d_stream.avail_out = (unsigned int)uncomprLen;
d_stream.next_out = uncompr;
d_stream.avail_out = (unsigned int)uncomprLen;
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
CHECK_ERR(err, "inflate");
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
CHECK_ERR(err, "inflate");
d_stream.avail_in = (unsigned int)comprLen - 2; /* read all compressed data */
err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */
CHECK_ERR(err, "inflateSync");
d_stream.avail_in = (unsigned int)comprLen - 2; /* read all compressed data */
err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */
CHECK_ERR(err, "inflateSync");
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err != Z_DATA_ERROR) {
fprintf(stderr, "inflate should report DATA_ERROR\n");
/* Because of incorrect adler32 */
exit(1);
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "inflate should report Z_STREAM_END\n");
exit(1);
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
size_t comprLen = 100 + 2 * PREFIX(compressBound)(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size);
z_size_t uncomprLen = (z_size_t)size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
// This test requires at least 3 bytes of input data.
if (size <= 3 || size > kMaxSize)
// This test requires at least 3 bytes of input data.
if (size <= 3 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_flush(compr, &comprLen);
test_sync(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_flush(compr, &comprLen);
test_sync(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
}
+85 -87
View File
@@ -29,115 +29,113 @@ static unsigned int diff;
/* ===========================================================================
* Test deflate() with large buffers and dynamic change of compression level
*/
void test_large_deflate(unsigned char *compr, size_t comprLen,
unsigned char *uncompr, size_t uncomprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_out = compr;
c_stream.avail_out = (unsigned int)comprLen;
c_stream.next_out = compr;
c_stream.avail_out = (unsigned int)comprLen;
/* At this point, uncompr is still mostly zeroes, so it should compress
* very well:
*/
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 1");
if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n");
exit(1);
}
/* At this point, uncompr is still mostly zeroes, so it should compress
* very well:
*/
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 1");
if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n");
exit(1);
}
/* Feed in already compressed data and switch to no compression: */
PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
c_stream.next_in = compr;
diff = (unsigned int)(c_stream.next_out - compr);
c_stream.avail_in = diff;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 2");
/* Feed in already compressed data and switch to no compression: */
PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
c_stream.next_in = compr;
diff = (unsigned int)(c_stream.next_out - compr);
c_stream.avail_in = diff;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 2");
/* Switch back to compressing mode: */
PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 3");
/* Switch back to compressing mode: */
PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 3");
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate large should report Z_STREAM_END\n");
exit(1);
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate large should report Z_STREAM_END\n");
exit(1);
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with large buffers
*/
void test_large_inflate(unsigned char *compr, size_t comprLen,
unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.next_in = compr;
d_stream.avail_in = (unsigned int)comprLen;
d_stream.next_in = compr;
d_stream.avail_in = (unsigned int)comprLen;
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (unsigned int)uncomprLen;
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "large inflate");
}
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (unsigned int)uncomprLen;
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "large inflate");
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (d_stream.total_out != 2 * uncomprLen + diff) {
fprintf(stderr, "bad large inflate: %zu\n", d_stream.total_out);
exit(1);
}
if (d_stream.total_out != 2 * uncomprLen + diff) {
fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
exit(1);
}
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
size_t comprLen = 100 + 3 * size;
size_t uncomprLen = comprLen;
uint8_t *compr, *uncompr;
size_t comprLen = 100 + 3 * size;
size_t uncomprLen = comprLen;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 512Kb. */
static size_t kMaxSize = 512 * 1024;
/* Discard inputs larger than 512Kb. */
static size_t kMaxSize = 512 * 1024;
if (size < 1 || size > kMaxSize)
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
}
+69 -70
View File
@@ -29,96 +29,95 @@ static free_func zfree = NULL;
* Test deflate() with small buffers
*/
void test_deflate(unsigned char *compr, size_t comprLen) {
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned long len = dataLen;
PREFIX3(stream) c_stream; /* compression stream */
int err;
unsigned long len = (unsigned long)dataLen;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (void *)0;
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (const unsigned char *)data;
c_stream.next_out = compr;
c_stream.next_in = (z_const unsigned char *)data;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate small 1");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "deflate small 2");
}
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate small 1");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "deflate small 2");
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with small buffers
*/
void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr,
size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
PREFIX3(stream) d_stream; /* decompression stream */
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = (void *)0;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
err = PREFIX(inflateInit)(&d_stream);
CHECK_ERR(err, "inflateInit");
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "inflate");
}
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "inflate");
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (memcmp(uncompr, data, dataLen)) {
fprintf(stderr, "bad inflate\n");
exit(1);
}
if (memcmp(uncompr, data, dataLen)) {
fprintf(stderr, "bad inflate\n");
exit(1);
}
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) {
size_t comprLen = PREFIX(compressBound)(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
size_t comprLen = PREFIX(compressBound)(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (size < 1 || size > kMaxSize)
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
data = d;
dataLen = size;
compr = (uint8_t *)calloc(1, comprLen);
uncompr = (uint8_t *)calloc(1, uncomprLen);
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
/* This function must return 0. */
return 0;
}
+87 -92
View File
@@ -12,13 +12,14 @@
* real thing.
*/
/* @(#) $Id$ */
#define _POSIX_SOURCE 1 /* This file needs POSIX for fileno(). */
#define _POSIX_C_SOURCE 200112 /* For snprintf(). */
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
# include "zlib.h"
#else
# include "zlib-ng.h"
# include "zlib-ng.h"
#endif
#include <stdio.h>
#include <assert.h>
@@ -35,7 +36,7 @@
# include <malloc.h>
#endif
#if defined(WIN32) || defined(__CYGWIN__)
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
@@ -48,8 +49,8 @@
#endif
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink (const char *);
#ifndef _WIN32 /* unlink already in stdio.h for Win32 */
extern int unlink (const char *);
#endif
#endif
@@ -62,23 +63,22 @@
#define BUFLENW (BUFLEN * 3) /* write buffer size */
#define MAX_NAME_LEN 1024
static char *prog;
static const char *prog = "minigzip_fuzzer";
void error (const char *msg);
void gz_compress (FILE *in, gzFile out);
void gz_compress (FILE *in, gzFile out);
#ifdef USE_MMAP
int gz_compress_mmap (FILE *in, gzFile out);
int gz_compress_mmap (FILE *in, gzFile out);
#endif
void gz_uncompress (gzFile in, FILE *out);
void file_compress (char *file, char *mode);
void file_uncompress (char *file);
void gz_uncompress (gzFile in, FILE *out);
void file_compress (char *file, char *mode);
void file_uncompress (char *file);
int main (int argc, char *argv[]);
/* ===========================================================================
* Display error message and exit
*/
void error(const char *msg)
{
void error(const char *msg) {
fprintf(stderr, "%s: %s\n", prog, msg);
exit(1);
}
@@ -87,8 +87,7 @@ void error(const char *msg)
* Compress input to output then close both files.
*/
void gz_compress(FILE *in, gzFile out)
{
void gz_compress(FILE *in, gzFile out) {
char buf[BUFLEN];
int len;
int err;
@@ -121,12 +120,11 @@ void gz_compress(FILE *in, gzFile out)
/* Try compressing the input file at once using mmap. Return Z_OK if
* if success, Z_ERRNO otherwise.
*/
int gz_compress_mmap(FILE *in, gzFile out)
{
int gz_compress_mmap(FILE *in, gzFile out) {
int len;
int err;
int ifd = fileno(in);
caddr_t buf; /* mmap'ed buffer for the entire input file */
char *buf; /* mmap'ed buffer for the entire input file */
off_t buf_len; /* length of the input file */
struct stat sb;
@@ -136,8 +134,8 @@ int gz_compress_mmap(FILE *in, gzFile out)
if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO;
buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (char *)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */
len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len);
@@ -154,8 +152,7 @@ int gz_compress_mmap(FILE *in, gzFile out)
/* ===========================================================================
* Uncompress input to output then close both files.
*/
void gz_uncompress(gzFile in, FILE *out)
{
void gz_uncompress(gzFile in, FILE *out) {
char buf[BUFLENW];
int len;
int err;
@@ -179,10 +176,9 @@ void gz_uncompress(gzFile in, FILE *out)
* Compress the given file: create a corresponding .gz file and remove the
* original.
*/
void file_compress(char *file, char *mode)
{
void file_compress(char *file, char *mode) {
char outfile[MAX_NAME_LEN];
FILE *in;
FILE *in;
gzFile out;
if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
@@ -211,11 +207,10 @@ void file_compress(char *file, char *mode)
/* ===========================================================================
* Uncompress the given file and remove the original.
*/
void file_uncompress(char *file)
{
void file_uncompress(char *file) {
char buf[MAX_NAME_LEN];
char *infile, *outfile;
FILE *out;
FILE *out;
gzFile in;
size_t len = strlen(file);
@@ -252,75 +247,75 @@ void file_uncompress(char *file)
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
char *inFileName = "/tmp/minigzip_fuzzer.out";
char *outFileName = "/tmp/minigzip_fuzzer.out.gz";
char outmode[20];
FILE *in;
char buf[BUFLEN];
uint32_t offset = 0;
char *inFileName = "minigzip_fuzzer.out";
char *outFileName = "minigzip_fuzzer.out.gz";
char outmode[20];
FILE *in;
char buf[BUFLEN];
uint32_t offset = 0;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (dataLen < 1 || dataLen > kMaxSize)
return 0;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (dataLen < 1 || dataLen > kMaxSize)
return 0;
in = fopen(inFileName, "w");
if (fwrite(data, 1, (unsigned)dataLen, in) != dataLen)
error("failed fwrite");
if (fclose(in))
error("failed fclose");
in = fopen(inFileName, "wb");
if (fwrite(data, 1, (unsigned)dataLen, in) != dataLen)
error("failed fwrite");
if (fclose(in))
error("failed fclose");
memset(outmode, 0, sizeof(outmode));
snprintf(outmode, sizeof(outmode), "%s", "wb");
memset(outmode, 0, sizeof(outmode));
snprintf(outmode, sizeof(outmode), "%s", "wb");
/* Compression level: [0..9]. */
outmode[2] = data[0] % 10;
/* Compression level: [0..9]. */
outmode[2] = data[0] % 10;
switch (data[0] % 4) {
default:
case 0:
outmode[3] = 0;
break;
case 1:
/* compress with Z_FILTERED */
outmode[3] = 'f';
break;
case 2:
/* compress with Z_HUFFMAN_ONLY */
outmode[3] = 'h';
break;
case 3:
/* compress with Z_RLE */
outmode[3] = 'R';
break;
}
file_compress(inFileName, outmode);
file_uncompress(outFileName);
/* Check that the uncompressed file matches the input data. */
in = fopen(inFileName, "rb");
if (in == NULL) {
perror(inFileName);
exit(1);
}
memset(buf, 0, sizeof(buf));
for (;;) {
int len = (int)fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
perror("fread");
exit(1);
switch (data[0] % 4) {
default:
case 0:
outmode[3] = 0;
break;
case 1:
/* compress with Z_FILTERED */
outmode[3] = 'f';
break;
case 2:
/* compress with Z_HUFFMAN_ONLY */
outmode[3] = 'h';
break;
case 3:
/* compress with Z_RLE */
outmode[3] = 'R';
break;
}
if (len == 0)
break;
assert(0 == memcmp(data + offset, buf, len));
offset += len;
}
if (fclose(in))
error("failed fclose");
file_compress(inFileName, outmode);
file_uncompress(outFileName);
/* This function must return 0. */
return 0;
/* Check that the uncompressed file matches the input data. */
in = fopen(inFileName, "rb");
if (in == NULL) {
perror(inFileName);
exit(1);
}
memset(buf, 0, sizeof(buf));
for (;;) {
int len = (int)fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
perror("fread");
exit(1);
}
if (len == 0)
break;
assert(0 == memcmp(data + offset, buf, len));
offset += len;
}
if (fclose(in))
error("failed fclose");
/* This function must return 0. */
return 0;
}
@@ -5,31 +5,32 @@
extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
int main(int argc, char **argv) {
int i;
fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
int i;
fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
for (i = 1; i < argc; i++) {
size_t len, n_read, err;
unsigned char *buf;
FILE *f = fopen(argv[i], "rb+");
if (!f) {
/* Failed to open this file: it may be a directory. */
fprintf(stderr, "Skipping: %s\n", argv[i]);
continue;
for (i = 1; i < argc; i++) {
size_t len, n_read, err;
unsigned char *buf;
FILE *f = fopen(argv[i], "rb+");
if (!f) {
/* Failed to open this file: it may be a directory. */
fprintf(stderr, "Skipping: %s\n", argv[i]);
continue;
}
fprintf(stderr, "Running: %s %s\n", argv[0], argv[i]);
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = (unsigned char *)malloc(len);
n_read = fread(buf, 1, len, f);
assert(n_read == len);
LLVMFuzzerTestOneInput(buf, len);
free(buf);
err = fclose(f);
assert(err == 0);
(void)err;
fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read);
}
fprintf(stderr, "Running: %s %s\n", argv[0], argv[i]);
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = (unsigned char *)malloc(len);
n_read = fread(buf, 1, len, f);
assert(n_read == len);
LLVMFuzzerTestOneInput(buf, len);
free(buf);
err = fclose(f);
assert(err == 0);
fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read);
}
return 0;
return 0;
}
+121 -108
View File
@@ -8,13 +8,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#undef NDEBUG
#include <assert.h>
#include "zlib.h"
#include <inttypes.h>
#include <stdint.h>
/* get definition of internal structure so we can mess with it (see pull()),
and so we can call inflate_trees() (see cover5()) */
#define ZLIB_INTERNAL
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
#include "inftrees.h"
#include "inflate.h"
@@ -28,7 +35,7 @@
They are used as follows:
z_stream strm;
PREFIX3(stream) strm;
mem_setup(&strm) initializes the memory tracking and sets the
zalloc, zfree, and opaque members of strm to use
memory tracking for all zlib operations on strm
@@ -67,8 +74,7 @@ struct mem_zone {
};
/* memory allocation routine to pass to zlib */
static void *mem_alloc(void *mem, unsigned count, unsigned size)
{
static void *mem_alloc(void *mem, unsigned count, unsigned size) {
void *ptr;
struct mem_item *item;
struct mem_zone *zone = mem;
@@ -108,8 +114,7 @@ static void *mem_alloc(void *mem, unsigned count, unsigned size)
}
/* memory free routine to pass to zlib */
static void mem_free(void *mem, void *ptr)
{
static void mem_free(void *mem, void *ptr) {
struct mem_item *item, *next;
struct mem_zone *zone = mem;
@@ -154,8 +159,7 @@ static void mem_free(void *mem, void *ptr)
/* set up a controlled memory allocation space for monitoring, set the stream
parameters to the controlled routines, with opaque pointing to the space */
static void mem_setup(z_stream *strm)
{
static void mem_setup(PREFIX3(stream) *strm) {
struct mem_zone *zone;
zone = malloc(sizeof(struct mem_zone));
@@ -172,32 +176,28 @@ static void mem_setup(z_stream *strm)
}
/* set a limit on the total memory allocation, or 0 to remove the limit */
static void mem_limit(z_stream *strm, size_t limit)
{
static void mem_limit(PREFIX3(stream) *strm, size_t limit) {
struct mem_zone *zone = strm->opaque;
zone->limit = limit;
}
/* show the current total requested allocations in bytes */
static void mem_used(z_stream *strm, char *prefix)
{
static void mem_used(PREFIX3(stream) *strm, char *prefix) {
struct mem_zone *zone = strm->opaque;
fprintf(stderr, "%s: %zu allocated\n", prefix, zone->total);
fprintf(stderr, "%s: %" PRIu64 " allocated\n", prefix, (uint64_t)zone->total);
}
/* show the high water allocation in bytes */
static void mem_high(z_stream *strm, char *prefix)
{
static void mem_high(PREFIX3(stream) *strm, char *prefix) {
struct mem_zone *zone = strm->opaque;
fprintf(stderr, "%s: %zu high water mark\n", prefix, zone->highwater);
fprintf(stderr, "%s: %" PRIu64 " high water mark\n", prefix, (uint64_t)zone->highwater);
}
/* release the memory allocation zone -- if there are any surprises, notify */
static void mem_done(z_stream *strm, char *prefix)
{
static void mem_done(PREFIX3(stream) *strm, char *prefix) {
int count = 0;
struct mem_item *item, *next;
struct mem_zone *zone = strm->opaque;
@@ -217,8 +217,8 @@ static void mem_done(z_stream *strm, char *prefix)
/* issue alerts about anything unexpected */
if (count || zone->total)
fprintf(stderr, "** %s: %zu bytes in %d blocks not freed\n",
prefix, zone->total, count);
fprintf(stderr, "** %s: %" PRIu64 " bytes in %d blocks not freed\n",
prefix, (uint64_t)zone->total, count);
if (zone->notlifo)
fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
if (zone->rogue)
@@ -241,12 +241,14 @@ static void mem_done(z_stream *strm, char *prefix)
by a delimiter, where that single digit writes a byte. The returned data is
allocated and must eventually be freed. NULL is returned if out of memory.
If the length is not needed, then len can be NULL. */
static unsigned char *h2b(const char *hex, unsigned *len)
{
static unsigned char *h2b(const char *hex, unsigned *len) {
unsigned char *in, *re;
unsigned next, val;
size_t inlen;
in = malloc((strlen(hex) + 1) >> 1);
inlen = (strlen(hex) + 1) >> 1;
assert(inlen != 0); /* tell static analyzer we won't call malloc(0) */
in = malloc(inlen);
if (in == NULL)
return NULL;
next = 0;
@@ -267,6 +269,7 @@ static unsigned char *h2b(const char *hex, unsigned *len)
} while (*hex++); /* go through the loop with the terminating null */
if (len != NULL)
*len = next;
assert(next != 0); /* tell static analyzer we won't call realloc(in, 0) */
re = realloc(in, next);
return re == NULL ? in : re;
}
@@ -280,18 +283,17 @@ static unsigned char *h2b(const char *hex, unsigned *len)
header information is collected with inflateGetHeader(). If a zlib stream
is looking for a dictionary, then an empty dictionary is provided.
inflate() is run until all of the input data is consumed. */
static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err)
{
static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err) {
int ret;
unsigned have;
unsigned char *in, *out;
z_stream strm, copy;
gz_header head;
PREFIX3(stream) strm, copy;
PREFIX(gz_header) head;
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit2(&strm, win);
ret = PREFIX(inflateInit2)(&strm, win);
if (ret != Z_OK) {
mem_done(&strm, what);
return;
@@ -304,7 +306,8 @@ static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int
head.name_max = len;
head.comment = out;
head.comm_max = len;
ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
ret = PREFIX(inflateGetHeader)(&strm, &head);
assert(ret == Z_OK);
}
in = h2b(hex, &have); assert(in != NULL);
if (step == 0 || step > have)
@@ -315,23 +318,26 @@ static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int
do {
strm.avail_out = len;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
assert(err == 9 || ret == err);
if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
break;
if (ret == Z_NEED_DICT) {
ret = inflateSetDictionary(&strm, in, 1);
ret = PREFIX(inflateSetDictionary)(&strm, in, 1);
assert(ret == Z_DATA_ERROR);
mem_limit(&strm, 1);
ret = inflateSetDictionary(&strm, out, 0);
ret = PREFIX(inflateSetDictionary)(&strm, out, 0);
assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
((struct inflate_state *)strm.state)->mode = DICT;
ret = inflateSetDictionary(&strm, out, 0);
ret = PREFIX(inflateSetDictionary)(&strm, out, 0);
assert(ret == Z_OK);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
assert(ret == Z_BUF_ERROR);
}
ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
ret = inflateEnd(&copy); assert(ret == Z_OK);
ret = PREFIX(inflateCopy)(&copy, &strm);
assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&copy); assert(ret == Z_OK);
err = 9; /* don't care next time around */
have += strm.avail_in;
strm.avail_in = step > have ? have : step;
@@ -339,27 +345,27 @@ static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int
} while (strm.avail_in);
free(in);
free(out);
ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
ret = inflateEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateReset2)(&strm, -8); assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
mem_done(&strm, what);
(void)err;
}
/* cover all of the lines in inflate.c up to inflate() */
static void cover_support(void)
{
static void cover_support(void) {
int ret;
z_stream strm;
PREFIX3(stream) strm;
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK);
mem_used(&strm, "inflate init");
ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
ret = inflateSetDictionary(&strm, NULL, 0);
ret = PREFIX(inflatePrime)(&strm, 5, 31); assert(ret == Z_OK);
ret = PREFIX(inflatePrime)(&strm, -1, 0); assert(ret == Z_OK);
ret = PREFIX(inflateSetDictionary)(&strm, NULL, 0);
assert(ret == Z_STREAM_ERROR);
ret = inflateEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
mem_done(&strm, "prime");
inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
@@ -371,27 +377,27 @@ static void cover_support(void)
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit_(&strm, ZLIB_VERSION + 1, (int)sizeof(z_stream));
ret = PREFIX(inflateInit_)(&strm, &PREFIX2(VERSION)[1], (int)sizeof(PREFIX3(stream)));
assert(ret == Z_VERSION_ERROR);
mem_done(&strm, "wrong version");
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit(&strm); assert(ret == Z_OK);
ret = inflateEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
fputs("inflate built-in memory routines\n", stderr);
(void)ret;
}
/* cover all inflate() header and trailer cases and code after inflate() */
static void cover_wrap(void)
{
static void cover_wrap(void) {
int ret;
z_stream strm, copy;
PREFIX3(stream) strm, copy;
unsigned char dict[257];
ret = inflate(NULL, 0); assert(ret == Z_STREAM_ERROR);
ret = inflateEnd(NULL); assert(ret == Z_STREAM_ERROR);
ret = inflateCopy(NULL, NULL); assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflate)(NULL, 0); assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflateEnd)(NULL); assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflateCopy)(NULL, NULL); assert(ret == Z_STREAM_ERROR);
fputs("inflate bad parameters\n", stderr);
inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
@@ -411,39 +417,43 @@ static void cover_wrap(void)
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit2(&strm, -8);
ret = PREFIX(inflateInit2)(&strm, -8);
strm.avail_in = 2;
strm.next_in = (void *)"\x63";
strm.avail_out = 1;
strm.next_out = (void *)&ret;
mem_limit(&strm, 1);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
memset(dict, 0, 257);
ret = inflateSetDictionary(&strm, dict, 257);
ret = PREFIX(inflateSetDictionary)(&strm, dict, 257);
assert(ret == Z_OK);
mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
ret = PREFIX(inflatePrime)(&strm, 16, 0); assert(ret == Z_OK);
strm.avail_in = 2;
strm.next_in = (void *)"\x80";
ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflateSync)(&strm); assert(ret == Z_DATA_ERROR);
ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
strm.avail_in = 4;
strm.next_in = (void *)"\0\0\xff\xff";
ret = inflateSync(&strm); assert(ret == Z_OK);
(void)inflateSyncPoint(&strm);
ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
ret = PREFIX(inflateSync)(&strm); assert(ret == Z_OK);
(void)PREFIX(inflateSyncPoint)(&strm);
ret = PREFIX(inflateCopy)(&copy, &strm); assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
(void)inflateMark(&strm);
ret = inflateEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateUndermine)(&strm, 1);
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
assert(ret == Z_OK);
#else
assert(ret == Z_DATA_ERROR);
#endif
(void)PREFIX(inflateMark)(&strm);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
mem_done(&strm, "miscellaneous, force memory errors");
}
/* input and output functions for inflateBack() */
static unsigned pull(void *desc, const unsigned char **buf)
{
static unsigned pull(void *desc, z_const unsigned char **buf) {
static unsigned int next = 0;
static unsigned char dat[] = {0x63, 0, 2, 0};
struct inflate_state *state;
@@ -452,63 +462,65 @@ static unsigned pull(void *desc, const unsigned char **buf)
next = 0;
return 0; /* no input (already provided at next_in) */
}
state = (void *)((z_stream *)desc)->state;
state = (void *)((PREFIX3(stream) *)desc)->state;
if (state != NULL)
state->mode = SYNC; /* force an otherwise impossible situation */
return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
}
static int push(void *desc, unsigned char *buf, unsigned len)
{
static int push(void *desc, unsigned char *buf, unsigned len) {
buf += len;
(void)buf;
return desc != NULL; /* force error if desc not null */
}
/* cover inflateBack() up to common deflate data cases and after those */
static void cover_back(void)
{
static void cover_back(void) {
int ret;
z_stream strm;
PREFIX3(stream) strm;
unsigned char win[32768];
ret = inflateBackInit_(NULL, 0, win, 0, 0);
ret = PREFIX(inflateBackInit_)(NULL, 0, win, 0, 0);
assert(ret == Z_VERSION_ERROR);
ret = inflateBackInit(NULL, 0, win); assert(ret == Z_STREAM_ERROR);
ret = inflateBack(NULL, NULL, NULL, NULL, NULL);
ret = PREFIX(inflateBackInit)(NULL, 0, win);
assert(ret == Z_STREAM_ERROR);
ret = inflateBackEnd(NULL); assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflateBack)(NULL, NULL, NULL, NULL, NULL);
assert(ret == Z_STREAM_ERROR);
ret = PREFIX(inflateBackEnd)(NULL); assert(ret == Z_STREAM_ERROR);
fputs("inflateBack bad parameters\n", stderr);
mem_setup(&strm);
ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
ret = PREFIX(inflateBackInit)(&strm, 15, win);
assert(ret == Z_OK);
strm.avail_in = 2;
strm.next_in = (void *)"\x03";
ret = inflateBack(&strm, pull, NULL, push, NULL);
ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL);
assert(ret == Z_STREAM_END);
/* force output error */
strm.avail_in = 3;
strm.next_in = (void *)"\x63\x00";
ret = inflateBack(&strm, pull, NULL, push, &strm);
ret = PREFIX(inflateBack)(&strm, pull, NULL, push, &strm);
assert(ret == Z_BUF_ERROR);
/* force mode error by mucking with state */
ret = inflateBack(&strm, pull, &strm, push, NULL);
ret = PREFIX(inflateBack)(&strm, pull, &strm, push, NULL);
assert(ret == Z_STREAM_ERROR);
ret = inflateBackEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK);
mem_done(&strm, "inflateBack bad state");
ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
ret = inflateBackEnd(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateBackInit)(&strm, 15, win);
assert(ret == Z_OK);
ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK);
fputs("inflateBack built-in memory routines\n", stderr);
(void)ret;
}
/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
static int try(char *hex, char *id, int err)
{
static int try(char *hex, char *id, int err) {
int ret;
unsigned len, size;
unsigned char *in, *out, *win;
char *prefix;
z_stream strm;
PREFIX3(stream) strm;
/* convert to hex */
in = h2b(hex, &len);
@@ -529,14 +541,14 @@ static int try(char *hex, char *id, int err)
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = NULL;
ret = inflateInit2(&strm, err < 0 ? 47 : -15);
ret = PREFIX(inflateInit2)(&strm, err < 0 ? 47 : -15);
assert(ret == Z_OK);
strm.avail_in = len;
strm.next_in = in;
do {
strm.avail_out = size;
strm.next_out = out;
ret = inflate(&strm, Z_TREES);
ret = PREFIX(inflate)(&strm, Z_TREES);
assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
break;
@@ -545,7 +557,7 @@ static int try(char *hex, char *id, int err)
assert(ret == Z_DATA_ERROR);
assert(strcmp(id, strm.msg) == 0);
}
inflateEnd(&strm);
PREFIX(inflateEnd)(&strm);
mem_done(&strm, prefix);
/* then with inflateBack */
@@ -553,17 +565,17 @@ static int try(char *hex, char *id, int err)
strcpy(prefix, id);
strcat(prefix, "-back");
mem_setup(&strm);
ret = inflateBackInit(&strm, 15, win);
ret = PREFIX(inflateBackInit)(&strm, 15, win);
assert(ret == Z_OK);
strm.avail_in = len;
strm.next_in = in;
ret = inflateBack(&strm, pull, NULL, push, NULL);
ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL);
assert(ret != Z_STREAM_ERROR);
if (err) {
if (err && ret != Z_BUF_ERROR) {
assert(ret == Z_DATA_ERROR);
assert(strcmp(id, strm.msg) == 0);
}
inflateBackEnd(&strm);
PREFIX(inflateBackEnd)(&strm);
mem_done(&strm, prefix);
}
@@ -576,8 +588,7 @@ static int try(char *hex, char *id, int err)
}
/* cover deflate data cases in both inflate() and inflateBack() */
static void cover_inflate(void)
{
static void cover_inflate(void) {
try("0 0 0 0 0", "invalid stored block lengths", 1);
try("3 0", "fixed", 0);
try("6", "invalid block type", 1);
@@ -592,7 +603,11 @@ static void cover_inflate(void)
try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
try("2 7e ff ff", "invalid distance code", 1);
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 0);
#else
try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
#endif
/* also trailer mismatch just in inflate() */
try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
@@ -612,8 +627,7 @@ static void cover_inflate(void)
}
/* cover remaining lines in inftrees.c */
static void cover_trees(void)
{
static void cover_trees(void) {
int ret;
unsigned bits;
uint16_t lens[16], work[16];
@@ -626,18 +640,18 @@ static void cover_trees(void)
lens[15] = 15;
next = table;
bits = 15;
ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work);
assert(ret == 1);
next = table;
bits = 1;
ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work);
assert(ret == 1);
fputs("inflate_table not enough errors\n", stderr);
(void)ret;
}
/* cover remaining inffast.c decoding and window copying */
static void cover_fast(void)
{
static void cover_fast(void) {
inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
" ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
@@ -656,9 +670,8 @@ static void cover_fast(void)
Z_STREAM_END);
}
int main(void)
{
fprintf(stderr, "%s\n", zlibVersion());
int main(void) {
fprintf(stderr, "%s\n", zVersion());
cover_support();
cover_wrap();
cover_back();
+307
View File
@@ -0,0 +1,307 @@
/* minideflate.c -- test deflate/inflate under specific conditions
* Copyright (C) 2020 Nathan Moinvaziri
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \
} \
}
/* ===========================================================================
* deflate() using specialized parameters
*/
void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t level,
int32_t window_bits, int32_t mem_level, int32_t strategy, int32_t flush) {
PREFIX3(stream) c_stream; /* compression stream */
uint8_t *read_buf;
uint8_t *write_buf;
int32_t read;
int err;
read_buf = (uint8_t *)malloc(read_buf_size);
if (read_buf == NULL) {
fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size);
return;
}
write_buf = (uint8_t *)malloc(write_buf_size);
if (write_buf == NULL) {
fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size);
free(read_buf);
return;
}
c_stream.zalloc = NULL;
c_stream.zfree = NULL;
c_stream.opaque = (void *)0;
c_stream.total_in = 0;
c_stream.total_out = 0;
err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy);
CHECK_ERR(err, "deflateInit2");
/* Process input using our read buffer and flush type,
* output to stdout only once write buffer is full */
do {
read = (int32_t)fread(read_buf, 1, read_buf_size, fin);
if (read <= 0)
break;
c_stream.next_in = (z_const uint8_t *)read_buf;
c_stream.next_out = write_buf;
c_stream.avail_in = read;
do {
c_stream.avail_out = write_buf_size;
err = PREFIX(deflate)(&c_stream, flush);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
if (c_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
c_stream.next_out = write_buf;
}
} while (c_stream.next_in < read_buf + read);
} while (err == Z_OK);
/* Finish the stream if necessary */
if (flush != Z_FINISH) {
c_stream.avail_in = 0;
do {
if (c_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
c_stream.next_out = write_buf;
}
c_stream.avail_out = write_buf_size;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
} while (err == Z_OK);
}
/* Output remaining data in write buffer */
if (c_stream.next_out != write_buf) {
fwrite(write_buf, 1, c_stream.next_out - write_buf, fout);
}
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
free(read_buf);
free(write_buf);
}
/* ===========================================================================
* inflate() using specialized parameters
*/
void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t window_bits,
int32_t flush) {
PREFIX3(stream) d_stream; /* decompression stream */
uint8_t *read_buf;
uint8_t *write_buf;
int32_t read;
int err;
read_buf = (uint8_t *)malloc(read_buf_size);
if (read_buf == NULL) {
fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size);
return;
}
write_buf = (uint8_t *)malloc(write_buf_size);
if (write_buf == NULL) {
fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size);
free(read_buf);
return;
}
d_stream.zalloc = NULL;
d_stream.zfree = NULL;
d_stream.opaque = (void *)0;
d_stream.total_in = 0;
d_stream.total_out = 0;
err = PREFIX(inflateInit2)(&d_stream, window_bits);
CHECK_ERR(err, "inflateInit2");
/* Process input using our read buffer and flush type,
* output to stdout only once write buffer is full */
do {
read = (int32_t)fread(read_buf, 1, read_buf_size, fin);
if (read <= 0)
break;
d_stream.next_in = (z_const uint8_t *)read_buf;
d_stream.next_out = write_buf;
d_stream.avail_in = read;
do {
d_stream.avail_out = write_buf_size;
err = PREFIX(inflate)(&d_stream, flush);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
if (d_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
d_stream.next_out = write_buf;
}
} while (d_stream.next_in < read_buf + read);
} while (err == Z_OK);
/* Finish the stream if necessary */
if (flush != Z_FINISH) {
d_stream.avail_in = 0;
do {
if (d_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
d_stream.next_out = write_buf;
}
d_stream.avail_out = write_buf_size;
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "inflate");
} while (err == Z_OK);
}
/* Output remaining data in write buffer */
if (d_stream.next_out != write_buf) {
fwrite(write_buf, 1, d_stream.next_out - write_buf, fout);
}
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
free(read_buf);
free(write_buf);
}
void show_help(void) {
printf("Usage: minideflate [-c] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \
" -c : write to standard output\n" \
" -d : decompress\n" \
" -f : compress with Z_FILTERED\n" \
" -h : compress with Z_HUFFMAN_ONLY\n" \
" -R : compress with Z_RLE\n" \
" -F : compress with Z_FIXED\n" \
" -m : memory level (1 to 8)\n" \
" -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n" \
" -s : flush type (0 to 5)\n" \
" -r : read buffer size\n" \
" -t : write buffer size\n" \
" -0 to -9 : compression level\n\n");
}
int main(int argc, char **argv) {
int32_t i;
int32_t mem_level = DEF_MEM_LEVEL;
int32_t window_bits = MAX_WBITS;
int32_t strategy = Z_DEFAULT_STRATEGY;
int32_t level = Z_DEFAULT_COMPRESSION;
int32_t read_buf_size = 4096;
int32_t write_buf_size = 4096;
int32_t flush = Z_NO_FLUSH;
uint8_t copyout = 0;
uint8_t uncompr = 0;
char out_file[320];
FILE *fin = stdin;
FILE *fout = stdout;
for (i = 1; i < argc; i++) {
if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc))
mem_level = atoi(argv[++i]);
else if ((strcmp(argv[i], "-w") == 0) && (i + 1 < argc))
window_bits = atoi(argv[++i]);
else if ((strcmp(argv[i], "-r") == 0) && (i + 1 < argc))
read_buf_size = atoi(argv[++i]);
else if ((strcmp(argv[i], "-t") == 0) && (i + 1 < argc))
write_buf_size = atoi(argv[++i]);
else if ((strcmp(argv[i], "-s") == 0) && (i + 1 < argc))
flush = atoi(argv[++i]);
else if (strcmp(argv[i], "-c") == 0)
copyout = 1;
else if (strcmp(argv[i], "-d") == 0)
uncompr = 1;
else if (strcmp(argv[i], "-f") == 0)
strategy = Z_FILTERED;
else if (strcmp(argv[i], "-h") == 0)
strategy = Z_HUFFMAN_ONLY;
else if (strcmp(argv[i], "-R") == 0)
strategy = Z_RLE;
else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0)
level = argv[i][1] - '0';
else if (strcmp(argv[i], "--help") == 0) {
show_help();
return 0;
} else if (argv[i][0] == '-') {
show_help();
return 64; /* EX_USAGE */
} else
break;
}
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
if (i != argc) {
fin = fopen(argv[i], "rb+");
if (fin == NULL) {
fprintf(stderr, "Failed to open file: %s\n", argv[i]);
exit(1);
}
if (!copyout) {
snprintf(out_file, sizeof(out_file), "%s%s", argv[i], (window_bits < 0) ? ".zz" : ".gz");
fout = fopen(out_file, "wb");
if (fout == NULL) {
fprintf(stderr, "Failed to open file: %s\n", out_file);
exit(1);
}
}
}
if (uncompr) {
inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush);
} else {
deflate_params(fin, fout, read_buf_size, write_buf_size, level, window_bits, mem_level, strategy, flush);
}
if (fin != stdin) {
fclose(fin);
}
if (fout != stdout) {
fclose(fout);
}
return 0;
}
+108 -93
View File
@@ -12,16 +12,14 @@
* real thing.
*/
/* @(#) $Id$ */
#define _POSIX_SOURCE 1 /* This file needs POSIX for fdopen(). */
#define _POSIX_C_SOURCE 200112 /* For snprintf(). */
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
# include "zlib.h"
#else
# include "zlib-ng.h"
# include "zlib-ng.h"
#endif
#include <stdio.h>
@@ -38,7 +36,7 @@
# include <malloc.h>
#endif
#if defined(WIN32) || defined(__CYGWIN__)
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
@@ -51,8 +49,8 @@
#endif
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink (const char *);
#ifndef _WIN32 /* unlink already in stdio.h for Win32 */
extern int unlink (const char *);
#endif
#endif
@@ -61,10 +59,8 @@
#endif
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
#if defined(S390_DFLTCC_DEFLATE) || defined(S390_DFLTCC_INFLATE)
#define BUFLEN 262144 /* DFLTCC works faster with larger buffers */
#else
#define BUFLEN 16384 /* read buffer size */
#ifndef BUFLEN
# define BUFLEN 16384 /* read buffer size */
#endif
#define BUFLENW (BUFLEN * 3) /* write buffer size */
#define MAX_NAME_LEN 1024
@@ -72,20 +68,19 @@
static char *prog;
void error (const char *msg);
void gz_compress (FILE *in, gzFile out);
void gz_compress (FILE *in, gzFile out);
#ifdef USE_MMAP
int gz_compress_mmap (FILE *in, gzFile out);
int gz_compress_mmap (FILE *in, gzFile out);
#endif
void gz_uncompress (gzFile in, FILE *out);
void file_compress (char *file, char *mode);
void file_uncompress (char *file);
void gz_uncompress (gzFile in, FILE *out);
void file_compress (char *file, char *mode, int keep);
void file_uncompress (char *file, int keep);
int main (int argc, char *argv[]);
/* ===========================================================================
* Display error message and exit
*/
void error(const char *msg)
{
void error(const char *msg) {
fprintf(stderr, "%s: %s\n", prog, msg);
exit(1);
}
@@ -94,9 +89,8 @@ void error(const char *msg)
* Compress input to output then close both files.
*/
void gz_compress(FILE *in, gzFile out)
{
char buf[BUFLEN];
void gz_compress(FILE *in, gzFile out) {
char *buf;
int len;
int err;
@@ -106,12 +100,16 @@ void gz_compress(FILE *in, gzFile out)
*/
if (gz_compress_mmap(in, out) == Z_OK) return;
#endif
/* Clear out the contents of buf before reading from the file to avoid
MemorySanitizer: use-of-uninitialized-value warnings. */
memset(buf, 0, sizeof(buf));
buf = (char *)calloc(BUFLEN, 1);
if (buf == NULL) {
perror("out of memory");
exit(1);
}
for (;;) {
len = (int)fread(buf, 1, sizeof(buf), in);
len = (int)fread(buf, 1, BUFLEN, in);
if (ferror(in)) {
free(buf);
perror("fread");
exit(1);
}
@@ -119,6 +117,7 @@ void gz_compress(FILE *in, gzFile out)
if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) error(PREFIX(gzerror)(out, &err));
}
free(buf);
fclose(in);
if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose");
}
@@ -128,12 +127,11 @@ void gz_compress(FILE *in, gzFile out)
/* Try compressing the input file at once using mmap. Return Z_OK if
* if success, Z_ERRNO otherwise.
*/
int gz_compress_mmap(FILE *in, gzFile out)
{
int gz_compress_mmap(FILE *in, gzFile out) {
int len;
int err;
int ifd = fileno(in);
caddr_t buf; /* mmap'ed buffer for the entire input file */
char *buf; /* mmap'ed buffer for the entire input file */
off_t buf_len; /* length of the input file */
struct stat sb;
@@ -143,11 +141,11 @@ int gz_compress_mmap(FILE *in, gzFile out)
if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO;
buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (char *)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */
len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len);
len = PREFIX(gzwrite)(out, buf, (unsigned)buf_len);
if (len != (int)buf_len) error(PREFIX(gzerror)(out, &err));
@@ -161,21 +159,27 @@ int gz_compress_mmap(FILE *in, gzFile out)
/* ===========================================================================
* Uncompress input to output then close both files.
*/
void gz_uncompress(gzFile in, FILE *out)
{
char buf[BUFLENW];
void gz_uncompress(gzFile in, FILE *out) {
char *buf = (char *)malloc(BUFLENW);
int len;
int err;
if (buf == NULL) error("out of memory");
for (;;) {
len = PREFIX(gzread)(in, buf, sizeof(buf));
if (len < 0) error (PREFIX(gzerror)(in, &err));
len = PREFIX(gzread)(in, buf, BUFLENW);
if (len < 0) {
free(buf);
error(PREFIX(gzerror)(in, &err));
}
if (len == 0) break;
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
free(buf);
error("failed fwrite");
}
}
free(buf);
if (fclose(out)) error("failed fclose");
if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose");
@@ -186,10 +190,9 @@ void gz_uncompress(gzFile in, FILE *out)
* Compress the given file: create a corresponding .gz file and remove the
* original.
*/
void file_compress(char *file, char *mode)
{
void file_compress(char *file, char *mode, int keep) {
char outfile[MAX_NAME_LEN];
FILE *in;
FILE *in;
gzFile out;
if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
@@ -211,18 +214,18 @@ void file_compress(char *file, char *mode)
}
gz_compress(in, out);
unlink(file);
if (!keep)
unlink(file);
}
/* ===========================================================================
* Uncompress the given file and remove the original.
*/
void file_uncompress(char *file)
{
void file_uncompress(char *file, int keep) {
char buf[MAX_NAME_LEN];
char *infile, *outfile;
FILE *out;
FILE *out;
gzFile in;
size_t len = strlen(file);
@@ -255,63 +258,75 @@ void file_uncompress(char *file)
gz_uncompress(in, out);
unlink(infile);
if (!keep)
unlink(infile);
}
void show_help(void) {
printf("Usage: minigzip [-c] [-d] [-k] [-f|-h|-R|-F|-T] [-A] [-0 to -9] [files...]\n\n" \
" -c : write to standard output\n" \
" -d : decompress\n" \
" -k : keep input files\n" \
" -f : compress with Z_FILTERED\n" \
" -h : compress with Z_HUFFMAN_ONLY\n" \
" -R : compress with Z_RLE\n" \
" -F : compress with Z_FIXED\n" \
" -T : stored raw\n" \
" -A : auto detect type\n" \
" -0 to -9 : compression level\n\n");
}
/* ===========================================================================
* Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
* -c : write to standard output
* -d : decompress
* -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY
* -r : compress with Z_RLE
* -0 to -9 : compression level
*/
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int copyout = 0;
int uncompr = 0;
int keep = 0;
int i = 0;
gzFile file;
char *bname, outmode[20];
char *strategy = "";
char *level = "6";
char *type = "b";
snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
prog = argv[0];
bname = strrchr(argv[0], '/');
prog = argv[i];
bname = strrchr(argv[i], '/');
if (bname)
bname++;
bname++;
else
bname = argv[0];
argc--, argv++;
bname = argv[i];
if (!strcmp(bname, "gunzip"))
uncompr = 1;
else if (!strcmp(bname, "zcat"))
copyout = uncompr = 1;
while (argc > 0) {
if (strcmp(*argv, "-c") == 0)
copyout = 1;
else if (strcmp(*argv, "-d") == 0)
uncompr = 1;
else if (strcmp(*argv, "-f") == 0)
outmode[3] = 'f';
else if (strcmp(*argv, "-h") == 0)
outmode[3] = 'h';
else if (strcmp(*argv, "-r") == 0)
outmode[3] = 'R';
else if ((*argv)[0] == '-' && (*argv)[1] >= '0' && (*argv)[1] <= '9' &&
(*argv)[2] == 0)
outmode[2] = (*argv)[1];
else
break;
argc--, argv++;
else if (!strcmp(bname, "zcat"))
copyout = uncompr = 1;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0)
copyout = 1;
else if (strcmp(argv[i], "-d") == 0)
uncompr = 1;
else if (strcmp(argv[i], "-k") == 0)
keep = 1;
else if (strcmp(argv[i], "-A") == 0)
type = "";
else if (argv[i][0] == '-' && (argv[i][1] == 'f' || argv[i][1] == 'h' ||
argv[i][1] == 'R' || argv[i][1] == 'F' || argv[i][1] == 'T') && argv[i][2] == 0)
strategy = argv[i] + 1;
else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0)
level = argv[i] + 1;
else if (strcmp(argv[i], "--help") == 0) {
show_help();
return 0;
} else if (argv[i][0] == '-') {
show_help();
return 64; /* EX_USAGE */
} else {
break;
}
}
if (outmode[3] == ' ')
outmode[3] = 0;
if (argc == 0) {
snprintf(outmode, sizeof(outmode), "w%s%s%s", type, strategy, level);
if (i == argc) {
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
if (uncompr) {
@@ -330,20 +345,20 @@ int main(int argc, char *argv[])
do {
if (uncompr) {
if (copyout) {
file = PREFIX(gzopen)(*argv, "rb");
file = PREFIX(gzopen)(argv[i], "rb");
if (file == NULL)
fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
fprintf(stderr, "%s: can't gzopen %s\n", prog, argv[i]);
else
gz_uncompress(file, stdout);
} else {
file_uncompress(*argv);
file_uncompress(argv[i], keep);
}
} else {
if (copyout) {
FILE * in = fopen(*argv, "rb");
FILE * in = fopen(argv[i], "rb");
if (in == NULL) {
perror(*argv);
perror(argv[i]);
} else {
file = PREFIX(gzdopen)(fileno(stdout), outmode);
if (file == NULL) error("can't gzdopen stdout");
@@ -352,10 +367,10 @@ int main(int argc, char *argv[])
}
} else {
file_compress(*argv, outmode);
file_compress(argv[i], outmode, keep);
}
}
} while (argv++, --argc);
} while (++i < argc);
}
return 0;
}
+176
View File
@@ -0,0 +1,176 @@
#!/bin/sh
usage() {
cat <<"_EOF_"
Usage: sh test/pkgcheck.sh [--zlib-compat]
Verifies that the various build systems produce identical results on a Unixlike system.
If --zlib-compat, tests with zlib compatible builds.
To build the 32 bit version for the current 64 bit arch:
$ sudo apt install ninja-build diffoscope gcc-multilib
$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-m32" CFLAGS=-m32 LDFLAGS=-m32
$ sh test/pkgcheck.sh
To cross-build, install the appropriate qemu and gcc packages,
and set the environment variables used by configure or cmake.
On Ubuntu, for example (values taken from .github/workflows/pkgconf.yml):
arm HF:
$ sudo apt install ninja-build diffoscope qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
$ export CHOST=arm-linux-gnueabihf
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}"
aarch64:
$ sudo apt install ninja-build diffoscope qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross
$ export CHOST=aarch64-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}"
ppc (32 bit big endian):
$ sudo apt install ninja-build diffoscope qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross
$ export CHOST=powerpc-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake"
ppc64le:
$ sudo apt install ninja-build diffoscope qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross
$ export CHOST=powerpc64le-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake"
then:
$ export CC=${CHOST}-gcc
$ sh test/pkgcheck.sh [--zlib-compat]
Note: on Mac, you may also need to do 'sudo xcode-select -r' to get cmake to match configure/make's behavior (i.e. omit -isysroot).
_EOF_
}
set -ex
# Caller can also set CMAKE_ARGS or CONFIGURE_ARGS if desired
CMAKE_ARGS=${CMAKE_ARGS}
CONFIGURE_ARGS=${CONFIGURE_ARGS}
case "$1" in
--zlib-compat)
suffix=""
CMAKE_ARGS="$CMAKE_ARGS -DZLIB_COMPAT=ON"
CONFIGURE_ARGS="$CONFIGURE_ARGS --zlib-compat"
;;
"")
suffix="-ng"
;;
*)
echo "Unknown arg '$1'"
usage
exit 1
;;
esac
if ! test -f "configure"
then
echo "Please run from top of source tree"
exit 1
fi
# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps
# Probably only needed on older systems (ubuntu 14.04, BSD?)
export SOURCE_DATE_EPOCH=0
case $(uname) in
Darwin)
# Tell Apple's ar etc. to use zero timestamps
export ZERO_AR_DATE=1
# What CPU are we running on, exactly?
sysctl -n machdep.cpu.brand_string
sysctl -n machdep.cpu.features
sysctl -n machdep.cpu.leaf7_features
sysctl -n machdep.cpu.extfeatures
;;
esac
# Use same compiler for make and cmake builds
if test "$CC"x = ""x
then
if clang --version
then
export CC=clang
elif gcc --version
then
export CC=gcc
fi
fi
# New build system
# Happens to delete top-level zconf.h
# (which itself is a bug, https://github.com/madler/zlib/issues/162 )
# which triggers another bug later in configure,
# https://github.com/madler/zlib/issues/499
rm -rf btmp2 pkgtmp2
mkdir btmp2 pkgtmp2
export DESTDIR=$(pwd)/pkgtmp2
cd btmp2
cmake -G Ninja ${CMAKE_ARGS} ..
ninja -v
ninja install
cd ..
# Original build system
rm -rf btmp1 pkgtmp1
mkdir btmp1 pkgtmp1
export DESTDIR=$(pwd)/pkgtmp1
cd btmp1
case $(uname) in
Darwin)
export LDFLAGS="-Wl,-headerpad_max_install_names"
;;
esac
../configure $CONFIGURE_ARGS
make
make install
cd ..
repack_ar() {
if ! cmp --silent pkgtmp1/usr/local/lib/libz$suffix.a pkgtmp2/usr/local/lib/libz$suffix.a
then
echo "libz$suffix.a does not match. Probably filenames differ (.o vs .c.o). Unpacking and renaming..."
# Note: %% is posix shell syntax meaning "Remove Largest Suffix Pattern", see
# https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
cd pkgtmp1; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; cd ..
cd pkgtmp2; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; for a in *.c.o; do mv $a ${a%%.c.o}.o; done; cd ..
# Also, remove __.SYMDEF SORTED if present, as it has those funky .c.o names embedded in it.
rm -f pkgtmp[12]/__.SYMDEF\ SORTED
fi
}
case $(uname) in
Darwin)
# Remove the build uuid.
dylib1=$(find pkgtmp1 -type f -name '*.dylib*')
dylib2=$(find pkgtmp2 -type f -name '*.dylib*')
strip -x -no_uuid "$dylib1"
strip -x -no_uuid "$dylib2"
;;
esac
# The ar on newer systems defaults to -D (i.e. deterministic),
# but FreeBSD 12.1, Debian 8, and Ubuntu 14.04 seem to not do that.
# I had trouble passing -D safely to the ar inside CMakeLists.txt,
# so punt and unpack the archive if needed before comparing.
# Also, cmake uses different .o suffix anyway...
repack_ar
if diff -Nur pkgtmp1 pkgtmp2
then
echo pkgcheck-cmake-bits-identical PASS
else
echo pkgcheck-cmake-bits-identical FAIL
dylib1=$(find pkgtmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
dylib2=$(find pkgtmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
diffoscope $dylib1 $dylib2 | cat
exit 1
fi
rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2
# any failure would have caused an early exit already
echo "pkgcheck: PASS"
+169
View File
@@ -0,0 +1,169 @@
/* Compresses a user-specified number of chunks from stdin into stdout as a single gzip stream.
* Each chunk is compressed with a user-specified level.
*/
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
static int read_all(unsigned char *buf, size_t size) {
size_t total_read = 0;
while (total_read < size) {
size_t n_read = fread(buf + total_read, 1, size - total_read, stdin);
if (ferror(stdin)) {
perror("fread\n");
return 1;
}
if (n_read == 0) {
fprintf(stderr, "Premature EOF\n");
return 1;
}
total_read += n_read;
}
return 0;
}
static int write_all(unsigned char *buf, size_t size) {
size_t total_written = 0;
while (total_written < size) {
size_t n_written = fwrite(buf + total_written, 1, size - total_written, stdout);
if (ferror(stdout)) {
perror("fwrite\n");
return 1;
}
total_written += n_written;
}
return 0;
}
static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last) {
int ret = 1;
int err = 0;
unsigned long compsize;
unsigned char *buf;
if (size <= 0) {
fprintf(stderr, "compress_chunk() invalid size %d\n", size);
goto done;
}
if (level < 0 || level > 9) {
fprintf(stderr, "compress_chunk() invalid level %d\n", level);
goto done;
}
compsize = 100 + 2 * PREFIX(deflateBound)(strm, size);
buf = malloc(size + compsize);
if (buf == NULL) {
fprintf(stderr, "Out of memory\n");
goto done;
}
if (read_all(buf, size) != 0) {
goto free_buf;
}
/* Provide only output buffer to deflateParams(). It might need some space to flush the leftovers from the last
* deflate(), but we don't want it to compress anything new. */
strm->next_in = NULL;
strm->avail_in = 0;
strm->next_out = buf + size;
strm->avail_out = compsize;
err = PREFIX(deflateParams)(strm, level, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
fprintf(stderr, "deflateParams() failed with code %d\n", err);
goto free_buf;
}
/* Provide input buffer to deflate(). */
strm->next_in = buf;
strm->avail_in = size;
err = PREFIX(deflate)(strm, last ? Z_FINISH : Z_SYNC_FLUSH);
if ((!last && err != Z_OK) || (last && err != Z_STREAM_END)) {
fprintf(stderr, "deflate() failed with code %d\n", err);
goto free_buf;
}
if (strm->avail_in != 0) {
fprintf(stderr, "deflate() did not consume %d bytes of input\n", strm->avail_in);
goto free_buf;
}
if (write_all(buf + size, compsize - strm->avail_out) != 0) {
goto free_buf;
}
ret = 0;
free_buf:
free(buf);
done:
return ret;
}
void show_help(void)
{
printf("Usage: switchlevels [-w bits] level1 size1 [level2 size2 ...]\n\n" \
" -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n\n");
}
int main(int argc, char **argv) {
int ret = EXIT_FAILURE;
int err = 0;
int size = 0;
int level = Z_DEFAULT_COMPRESSION;
int level_arg = 1;
int window_bits = MAX_WBITS + 16;
PREFIX3(stream) strm;
if ((argc == 1) || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
show_help();
return 0;
}
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
memset(&strm, 0, sizeof(strm));
for (int i = 1; i < argc - 1; i++) {
if (strcmp(argv[i], "-w") == 0 && i+1 < argc) {
window_bits = atoi(argv[++i]);
} else {
level_arg = i;
level = atoi(argv[i]);
break;
}
}
err = PREFIX(deflateInit2)(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
fprintf(stderr, "deflateInit() failed with code %d\n", err);
goto done;
}
for (int i = level_arg; i < argc - 1; i += 2) {
level = atoi(argv[i]);
size = atoi(argv[i + 1]);
if (compress_chunk(&strm, level, size, i + 2 >= argc - 1) != 0) {
goto deflate_end;
}
}
ret = EXIT_SUCCESS;
deflate_end:
PREFIX(deflateEnd)(&strm);
done:
return ret;
}
+8 -9
View File
@@ -15,17 +15,16 @@ CVEs="CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096"
for CVE in $CVEs; do
fail=0
for testcase in ${TESTDIR}/${CVE}/*.gz; do
${QEMU_RUN} ../minigzip${EXE} -d < "$testcase"
# we expect that a 1 error code is OK
# for a vulnerable failure we'd expect 134 or similar
if [ $? -ne 1 ] && [ $? -ne 0 ]; then
fail=1
fi
${QEMU_RUN} ../minigzip${EXE} -d < "$testcase"
# we expect that a 1 error code is OK
# for a vulnerable failure we'd expect 134 or similar
if [ $? -ne 1 ] && [ $? -ne 0 ]; then
fail=1
fi
done
if [ $fail -eq 0 ]; then
echo " --- zlib not vulnerable to $CVE ---";
echo " --- zlib not vulnerable to $CVE ---";
else
echo " --- zlib VULNERABLE to $CVE ---"; exit 1;
echo " --- zlib VULNERABLE to $CVE ---"; exit 1;
fi
done