Update zlib to 1.2.12

This commit is contained in:
Miku AuahDark
2022-08-25 19:13:08 +08:00
parent 2f06b85a2c
commit 7fcddc790b
74 changed files with 12237 additions and 1733 deletions
+1 -1
View File
@@ -165,7 +165,7 @@ if(MSVC)
endif() endif()
set(MEGA_ZLIB_VER "1.2.11") set(MEGA_ZLIB_VER "1.2.12")
set(MEGA_LUA51_VER "5.1.5") set(MEGA_LUA51_VER "5.1.5")
set(MEGA_LUAJIT_VER "2.1.0-7306ba7") set(MEGA_LUAJIT_VER "2.1.0-7306ba7")
set(MEGA_LIBOGG_VER "1.3.2") set(MEGA_LIBOGG_VER "1.3.2")
+26
View File
@@ -0,0 +1,26 @@
*.diff
*.patch
*.orig
*.rej
*~
*.a
*.lo
*.o
*.dylib
*.gcda
*.gcno
*.gcov
/example
/example64
/examplesh
/libz.so*
/minigzip
/minigzip64
/minigzipsh
/zlib.pc
/configure.log
.DS_Store
+1 -7
View File
@@ -3,7 +3,7 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
project(zlib C) project(zlib C)
set(VERSION "1.2.11") set(VERSION "1.2.12")
option(ASM686 "Enable building i686 assembly implementation") option(ASM686 "Enable building i686 assembly implementation")
option(AMD64 "Enable building amd64 assembly implementation") option(AMD64 "Enable building amd64 assembly implementation")
@@ -187,10 +187,6 @@ add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
set_target_properties(zlib PROPERTIES SOVERSION 1) set_target_properties(zlib PROPERTIES SOVERSION 1)
target_include_directories(zlib PUBLIC .)
target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(zlibstatic PUBLIC .)
target_include_directories(zlibstatic PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
if(NOT CYGWIN) if(NOT CYGWIN)
# This property causes shared libraries on Linux to have the full version # This property causes shared libraries on Linux to have the full version
@@ -234,8 +230,6 @@ endif()
# Example binaries # Example binaries
#============================================================================ #============================================================================
return()
add_executable(example test/example.c) add_executable(example test/example.c)
target_link_libraries(example zlib) target_link_libraries(example zlib)
add_test(example example) add_test(example example)
+112 -49
View File
@@ -1,6 +1,69 @@
ChangeLog file for zlib ChangeLog file for zlib
Changes in 1.2.12 (27 Mar 2022)
- Cygwin does not have _wopen(), so do not create gzopen_w() there
- Permit a deflateParams() parameter change as soon as possible
- Limit hash table inserts after switch from stored deflate
- Fix bug when window full in deflate_stored()
- Fix CLEAR_HASH macro to be usable as a single statement
- Avoid a conversion error in gzseek when off_t type too small
- Have Makefile return non-zero error code on test failure
- Avoid some conversion warnings in gzread.c and gzwrite.c
- Update use of errno for newer Windows CE versions
- Small speedup to inflate [psumbera]
- Return an error if the gzputs string length can't fit in an int
- Add address checking in clang to -w option of configure
- Don't compute check value for raw inflate if asked to validate
- Handle case where inflateSync used when header never processed
- Avoid the use of ptrdiff_t
- Avoid an undefined behavior of memcpy() in gzappend()
- Avoid undefined behaviors of memcpy() in gz*printf()
- Avoid an undefined behavior of memcpy() in _tr_stored_block()
- Make the names in functions declarations identical to definitions
- Remove old assembler code in which bugs have manifested
- Fix deflateEnd() to not report an error at start of raw deflate
- Add legal disclaimer to README
- Emphasize the need to continue decompressing gzip members
- Correct the initialization requirements for deflateInit2()
- Fix a bug that can crash deflate on some input when using Z_FIXED
- Assure that the number of bits for deflatePrime() is valid
- Use a structure to make globals in enough.c evident
- Use a macro for the printf format of big_t in enough.c
- Clean up code style in enough.c, update version
- Use inline function instead of macro for index in enough.c
- Clarify that prefix codes are counted in enough.c
- Show all the codes for the maximum tables size in enough.c
- Add gznorm.c example, which normalizes gzip files
- Fix the zran.c example to work on a multiple-member gzip file
- Add tables for crc32_combine(), to speed it up by a factor of 200
- Add crc32_combine_gen() and crc32_combine_op() for fast combines
- Speed up software CRC-32 computation by a factor of 1.5 to 3
- Use atomic test and set, if available, for dynamic CRC tables
- Don't bother computing check value after successful inflateSync()
- Correct comment in crc32.c
- Add use of the ARMv8 crc32 instructions when requested
- Use ARM crc32 instructions if the ARM architecture has them
- Explicitly note that the 32-bit check values are 32 bits
- Avoid adding empty gzip member after gzflush with Z_FINISH
- Fix memory leak on error in gzlog.c
- Fix error in comment on the polynomial representation of a byte
- Clarify gz* function interfaces, referring to parameter names
- Change macro name in inflate.c to avoid collision in VxWorks
- Correct typo in blast.c
- Improve portability of contrib/minizip
- Fix indentation in minizip's zip.c
- Replace black/white with allow/block. (theresa-m)
- minizip warning fix if MAXU32 already defined. (gvollant)
- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner)
- Clean up minizip to reduce warnings for testing
- Add fallthrough comments for gcc
- Eliminate use of ULL constants
- Separate out address sanitizing from warnings in configure
- Remove destructive aspects of make distclean
- Check for cc masquerading as gcc or clang in configure
- Fix crc32.c to compile local functions only if used
Changes in 1.2.11 (15 Jan 2017) Changes in 1.2.11 (15 Jan 2017)
- Fix deflate stored bug when pulling last block from window - Fix deflate stored bug when pulling last block from window
- Permit immediate deflateParams changes before any deflate input - Permit immediate deflateParams changes before any deflate input
@@ -511,7 +574,7 @@ Changes in 1.2.3.5 (8 Jan 2010)
- Don't use _vsnprintf on later versions of MSVC [Lowman] - Don't use _vsnprintf on later versions of MSVC [Lowman]
- Add CMake build script and input file [Lowman] - Add CMake build script and input file [Lowman]
- Update contrib/minizip to 1.1 [Svensson, Vollant] - Update contrib/minizip to 1.1 [Svensson, Vollant]
- Moved nintendods directory from contrib to . - Moved nintendods directory from contrib to root
- Replace gzio.c with a new set of routines with the same functionality - Replace gzio.c with a new set of routines with the same functionality
- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above - Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
- Update contrib/minizip to 1.1b - Update contrib/minizip to 1.1b
@@ -685,7 +748,7 @@ Changes in 1.2.2.4 (11 July 2005)
- Be more strict on incomplete code sets in inflate_table() and increase - Be more strict on incomplete code sets in inflate_table() and increase
ENOUGH and MAXD -- this repairs a possible security vulnerability for ENOUGH and MAXD -- this repairs a possible security vulnerability for
invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
discovering the vulnerability and providing test cases. discovering the vulnerability and providing test cases
- Add ia64 support to configure for HP-UX [Smith] - Add ia64 support to configure for HP-UX [Smith]
- Add error return to gzread() for format or i/o error [Levin] - Add error return to gzread() for format or i/o error [Levin]
- Use malloc.h for OS/2 [Necasek] - Use malloc.h for OS/2 [Necasek]
@@ -721,7 +784,7 @@ Changes in 1.2.2.2 (30 December 2004)
- Add Z_FIXED strategy option to deflateInit2() to force fixed trees - Add Z_FIXED strategy option to deflateInit2() to force fixed trees
- Add updated make_vms.com [Coghlan], update README - Add updated make_vms.com [Coghlan], update README
- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - Create a new "examples" directory, move gzappend.c there, add zpipe.c,
fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html
- Add FAQ entry and comments in deflate.c on uninitialized memory access - Add FAQ entry and comments in deflate.c on uninitialized memory access
- Add Solaris 9 make options in configure [Gilbert] - Add Solaris 9 make options in configure [Gilbert]
- Allow strerror() usage in gzio.c for STDC - Allow strerror() usage in gzio.c for STDC
@@ -792,7 +855,7 @@ Changes in 1.2.1.1 (9 January 2004)
- Fix a big fat bug in inftrees.c that prevented decoding valid - Fix a big fat bug in inftrees.c that prevented decoding valid
dynamic blocks with only literals and no distance codes -- dynamic blocks with only literals and no distance codes --
Thanks to "Hot Emu" for the bug report and sample file Thanks to "Hot Emu" for the bug report and sample file
- Add a note to puff.c on no distance codes case. - Add a note to puff.c on no distance codes case
Changes in 1.2.1 (17 November 2003) Changes in 1.2.1 (17 November 2003)
- Remove a tab in contrib/gzappend/gzappend.c - Remove a tab in contrib/gzappend/gzappend.c
@@ -1036,14 +1099,14 @@ Changes in 1.2.0 (9 March 2003)
- Add contrib/puff/ simple inflate for deflate format description - Add contrib/puff/ simple inflate for deflate format description
Changes in 1.1.4 (11 March 2002) Changes in 1.1.4 (11 March 2002)
- ZFREE was repeated on same allocation on some error conditions. - ZFREE was repeated on same allocation on some error conditions
This creates a security problem described in This creates a security problem described in
http://www.zlib.org/advisory-2002-03-11.txt http://www.zlib.org/advisory-2002-03-11.txt
- Returned incorrect error (Z_MEM_ERROR) on some invalid data - Returned incorrect error (Z_MEM_ERROR) on some invalid data
- Avoid accesses before window for invalid distances with inflate window - Avoid accesses before window for invalid distances with inflate window
less than 32K. less than 32K
- force windowBits > 8 to avoid a bug in the encoder for a window size - force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5). of 256 bytes. (A complete fix will be available in 1.1.5)
Changes in 1.1.3 (9 July 1998) Changes in 1.1.3 (9 July 1998)
- fix "an inflate input buffer bug that shows up on rare but persistent - fix "an inflate input buffer bug that shows up on rare but persistent
@@ -1117,7 +1180,7 @@ Changes in 1.1.1 (27 Feb 98)
- remove block truncation heuristic which had very marginal effect for zlib - remove block truncation heuristic which had very marginal effect for zlib
(smaller lit_bufsize than in gzip 1.2.4) and degraded a little the (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
compression ratio on some files. This also allows inlining _tr_tally for compression ratio on some files. This also allows inlining _tr_tally for
matches in deflate_slow. matches in deflate_slow
- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
Changes in 1.1.0 (24 Feb 98) Changes in 1.1.0 (24 Feb 98)
@@ -1162,7 +1225,7 @@ Changes in 1.0.8 (27 Jan 1998)
- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) - include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
- use constant arrays for the static trees in trees.c instead of computing - use constant arrays for the static trees in trees.c instead of computing
them at run time (thanks to Ken Raeburn for this suggestion). To create them at run time (thanks to Ken Raeburn for this suggestion). To create
trees.h, compile with GEN_TREES_H and run "make test". trees.h, compile with GEN_TREES_H and run "make test"
- check return code of example in "make test" and display result - check return code of example in "make test" and display result
- pass minigzip command line options to file_compress - pass minigzip command line options to file_compress
- simplifying code of inflateSync to avoid gcc 2.8 bug - simplifying code of inflateSync to avoid gcc 2.8 bug
@@ -1201,12 +1264,12 @@ Changes in 1.0.6 (19 Jan 1998)
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
- Fix a deflate bug occurring only with compression level 0 (thanks to - Fix a deflate bug occurring only with compression level 0 (thanks to
Andy Buckler for finding this one). Andy Buckler for finding this one)
- In minigzip, pass transparently also the first byte for .Z files. - In minigzip, pass transparently also the first byte for .Z files
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() - return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
- check Z_FINISH in inflate (thanks to Marc Schluper) - check Z_FINISH in inflate (thanks to Marc Schluper)
- Implement deflateCopy (thanks to Adam Costello) - Implement deflateCopy (thanks to Adam Costello)
- make static libraries by default in configure, add --shared option. - make static libraries by default in configure, add --shared option
- move MSDOS or Windows specific files to directory msdos - move MSDOS or Windows specific files to directory msdos
- suppress the notion of partial flush to simplify the interface - suppress the notion of partial flush to simplify the interface
(but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
@@ -1218,7 +1281,7 @@ Changes in 1.0.6 (19 Jan 1998)
- added Makefile.nt (thanks to Stephen Williams) - added Makefile.nt (thanks to Stephen Williams)
- added the unsupported "contrib" directory: - added the unsupported "contrib" directory:
contrib/asm386/ by Gilles Vollant <info@winimage.com> contrib/asm386/ by Gilles Vollant <info@winimage.com>
386 asm code replacing longest_match(). 386 asm code replacing longest_match()
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu> contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
A C++ I/O streams interface to the zlib gz* functions A C++ I/O streams interface to the zlib gz* functions
contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no> contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
@@ -1226,7 +1289,7 @@ Changes in 1.0.6 (19 Jan 1998)
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es> contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
A very simple tar.gz file extractor using zlib A very simple tar.gz file extractor using zlib
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl> contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
How to use compress(), uncompress() and the gz* functions from VB. How to use compress(), uncompress() and the gz* functions from VB
- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
level) in minigzip (thanks to Tom Lane) level) in minigzip (thanks to Tom Lane)
@@ -1235,8 +1298,8 @@ Changes in 1.0.6 (19 Jan 1998)
- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) - add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
- add undocumented function zError to convert error code to string - add undocumented function zError to convert error code to string
(for Tim Smithers) (for Tim Smithers)
- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. - Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code
- Use default memcpy for Symantec MSDOS compiler. - Use default memcpy for Symantec MSDOS compiler
- Add EXPORT keyword for check_func (needed for Windows DLL) - Add EXPORT keyword for check_func (needed for Windows DLL)
- add current directory to LD_LIBRARY_PATH for "make test" - add current directory to LD_LIBRARY_PATH for "make test"
- create also a link for libz.so.1 - create also a link for libz.so.1
@@ -1249,7 +1312,7 @@ Changes in 1.0.6 (19 Jan 1998)
- allow compilation with ANSI keywords only enabled for TurboC in large model - allow compilation with ANSI keywords only enabled for TurboC in large model
- avoid "versionString"[0] (Borland bug) - avoid "versionString"[0] (Borland bug)
- add NEED_DUMMY_RETURN for Borland - add NEED_DUMMY_RETURN for Borland
- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). - use variable z_verbose for tracing in debug mode (L. Peter Deutsch)
- allow compilation with CC - allow compilation with CC
- defined STDC for OS/2 (David Charlap) - defined STDC for OS/2 (David Charlap)
- limit external names to 8 chars for MVS (Thomas Lund) - limit external names to 8 chars for MVS (Thomas Lund)
@@ -1259,7 +1322,7 @@ Changes in 1.0.6 (19 Jan 1998)
- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
- added makelcc.bat for lcc-win32 (Tom St Denis) - added makelcc.bat for lcc-win32 (Tom St Denis)
- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. - Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion
- check for unistd.h in configure (for off_t) - check for unistd.h in configure (for off_t)
- remove useless check parameter in inflate_blocks_free - remove useless check parameter in inflate_blocks_free
- avoid useless assignment of s->check to itself in inflate_blocks_new - avoid useless assignment of s->check to itself in inflate_blocks_new
@@ -1280,7 +1343,7 @@ Changes in 1.0.5 (3 Jan 98)
Changes in 1.0.4 (24 Jul 96) Changes in 1.0.4 (24 Jul 96)
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
bit, so the decompressor could decompress all the correct data but went bit, so the decompressor could decompress all the correct data but went
on to attempt decompressing extra garbage data. This affected minigzip too. on to attempt decompressing extra garbage data. This affected minigzip too
- zlibVersion and gzerror return const char* (needed for DLL) - zlibVersion and gzerror return const char* (needed for DLL)
- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
- use z_error only for DEBUG (avoid problem with DLLs) - use z_error only for DEBUG (avoid problem with DLLs)
@@ -1310,7 +1373,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
- fix array overlay in deflate.c which sometimes caused bad compressed data - fix array overlay in deflate.c which sometimes caused bad compressed data
- fix inflate bug with empty stored block - fix inflate bug with empty stored block
- fix MSDOS medium model which was broken in 0.99 - fix MSDOS medium model which was broken in 0.99
- fix deflateParams() which could generate bad compressed data. - fix deflateParams() which could generate bad compressed data
- Bytef is define'd instead of typedef'ed (work around Borland bug) - Bytef is define'd instead of typedef'ed (work around Borland bug)
- added an INDEX file - added an INDEX file
- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
@@ -1331,7 +1394,7 @@ Changes in 0.99 (27 Jan 96)
- allow preset dictionary shared between compressor and decompressor - allow preset dictionary shared between compressor and decompressor
- allow compression level 0 (no compression) - allow compression level 0 (no compression)
- add deflateParams in zlib.h: allow dynamic change of compression level - add deflateParams in zlib.h: allow dynamic change of compression level
and compression strategy. and compression strategy
- test large buffers and deflateParams in example.c - test large buffers and deflateParams in example.c
- add optional "configure" to build zlib as a shared library - add optional "configure" to build zlib as a shared library
- suppress Makefile.qnx, use configure instead - suppress Makefile.qnx, use configure instead
@@ -1373,30 +1436,30 @@ Changes in 0.99 (27 Jan 96)
- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... - use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
- use Z_BINARY instead of BINARY - use Z_BINARY instead of BINARY
- document that gzclose after gzdopen will close the file - document that gzclose after gzdopen will close the file
- allow "a" as mode in gzopen. - allow "a" as mode in gzopen
- fix error checking in gzread - fix error checking in gzread
- allow skipping .gz extra-field on pipes - allow skipping .gz extra-field on pipes
- added reference to Perl interface in README - added reference to Perl interface in README
- put the crc table in FAR data (I dislike more and more the medium model :) - put the crc table in FAR data (I dislike more and more the medium model :)
- added get_crc_table - added get_crc_table
- added a dimension to all arrays (Borland C can't count). - added a dimension to all arrays (Borland C can't count)
- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast - workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
- guard against multiple inclusion of *.h (for precompiled header on Mac) - guard against multiple inclusion of *.h (for precompiled header on Mac)
- Watcom C pretends to be Microsoft C small model even in 32 bit mode. - Watcom C pretends to be Microsoft C small model even in 32 bit mode
- don't use unsized arrays to avoid silly warnings by Visual C++: - don't use unsized arrays to avoid silly warnings by Visual C++:
warning C4746: 'inflate_mask' : unsized array treated as '__far' warning C4746: 'inflate_mask' : unsized array treated as '__far'
(what's wrong with far data in far model?). (what's wrong with far data in far model?)
- define enum out of inflate_blocks_state to allow compilation with C++ - define enum out of inflate_blocks_state to allow compilation with C++
Changes in 0.95 (16 Aug 95) Changes in 0.95 (16 Aug 95)
- fix MSDOS small and medium model (now easier to adapt to any compiler) - fix MSDOS small and medium model (now easier to adapt to any compiler)
- inlined send_bits - inlined send_bits
- fix the final (:-) bug for deflate with flush (output was correct but - fix the final (:-) bug for deflate with flush (output was correct but
not completely flushed in rare occasions). not completely flushed in rare occasions)
- default window size is same for compression and decompression - default window size is same for compression and decompression
(it's now sufficient to set MAX_WBITS in zconf.h). (it's now sufficient to set MAX_WBITS in zconf.h)
- voidp -> voidpf and voidnp -> voidp (for consistency with other - voidp -> voidpf and voidnp -> voidp (for consistency with other
typedefs and because voidnp was not near in large model). typedefs and because voidnp was not near in large model)
Changes in 0.94 (13 Aug 95) Changes in 0.94 (13 Aug 95)
- support MSDOS medium model - support MSDOS medium model
@@ -1405,12 +1468,12 @@ Changes in 0.94 (13 Aug 95)
- added support for VMS - added support for VMS
- allow a compression level in gzopen() - allow a compression level in gzopen()
- gzflush now calls fflush - gzflush now calls fflush
- For deflate with flush, flush even if no more input is provided. - For deflate with flush, flush even if no more input is provided
- rename libgz.a as libz.a - rename libgz.a as libz.a
- avoid complex expression in infcodes.c triggering Turbo C bug - avoid complex expression in infcodes.c triggering Turbo C bug
- work around a problem with gcc on Alpha (in INSERT_STRING) - work around a problem with gcc on Alpha (in INSERT_STRING)
- don't use inline functions (problem with some gcc versions) - don't use inline functions (problem with some gcc versions)
- allow renaming of Byte, uInt, etc... with #define. - allow renaming of Byte, uInt, etc... with #define
- avoid warning about (unused) pointer before start of array in deflate.c - avoid warning about (unused) pointer before start of array in deflate.c
- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c - avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
- avoid reserved word 'new' in trees.c - avoid reserved word 'new' in trees.c
@@ -1429,7 +1492,7 @@ Changes in 0.92 (3 May 95)
- no memcpy on Pyramid - no memcpy on Pyramid
- suppressed inftest.c - suppressed inftest.c
- optimized fill_window, put longest_match inline for gcc - optimized fill_window, put longest_match inline for gcc
- optimized inflate on stored blocks. - optimized inflate on stored blocks
- untabify all sources to simplify patches - untabify all sources to simplify patches
Changes in 0.91 (2 May 95) Changes in 0.91 (2 May 95)
@@ -1447,7 +1510,7 @@ Changes in 0.9 (1 May 95)
- let again gzread copy uncompressed data unchanged (was working in 0.71) - let again gzread copy uncompressed data unchanged (was working in 0.71)
- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented - deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
- added a test of inflateSync in example.c - added a test of inflateSync in example.c
- moved MAX_WBITS to zconf.h because users might want to change that. - moved MAX_WBITS to zconf.h because users might want to change that
- document explicitly that zalloc(64K) on MSDOS must return a normalized - document explicitly that zalloc(64K) on MSDOS must return a normalized
pointer (zero offset) pointer (zero offset)
- added Makefiles for Microsoft C, Turbo C, Borland C++ - added Makefiles for Microsoft C, Turbo C, Borland C++
@@ -1456,7 +1519,7 @@ Changes in 0.9 (1 May 95)
Changes in 0.8 (29 April 95) Changes in 0.8 (29 April 95)
- added fast inflate (inffast.c) - added fast inflate (inffast.c)
- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
is incompatible with previous versions of zlib which returned Z_OK. is incompatible with previous versions of zlib which returned Z_OK
- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
(actually that was not a compiler bug, see 0.81 above) (actually that was not a compiler bug, see 0.81 above)
- gzread no longer reads one extra byte in certain cases - gzread no longer reads one extra byte in certain cases
@@ -1466,50 +1529,50 @@ Changes in 0.8 (29 April 95)
Changes in 0.71 (14 April 95) Changes in 0.71 (14 April 95)
- Fixed more MSDOS compilation problems :( There is still a bug with - Fixed more MSDOS compilation problems :( There is still a bug with
TurboC large model. TurboC large model
Changes in 0.7 (14 April 95) Changes in 0.7 (14 April 95)
- Added full inflate support. - Added full inflate support
- Simplified the crc32() interface. The pre- and post-conditioning - Simplified the crc32() interface. The pre- and post-conditioning
(one's complement) is now done inside crc32(). WARNING: this is (one's complement) is now done inside crc32(). WARNING: this is
incompatible with previous versions; see zlib.h for the new usage. incompatible with previous versions; see zlib.h for the new usage
Changes in 0.61 (12 April 95) Changes in 0.61 (12 April 95)
- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - workaround for a bug in TurboC. example and minigzip now work on MSDOS
Changes in 0.6 (11 April 95) Changes in 0.6 (11 April 95)
- added minigzip.c - added minigzip.c
- added gzdopen to reopen a file descriptor as gzFile - added gzdopen to reopen a file descriptor as gzFile
- added transparent reading of non-gziped files in gzread. - added transparent reading of non-gziped files in gzread
- fixed bug in gzread (don't read crc as data) - fixed bug in gzread (don't read crc as data)
- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). - fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose)
- don't allocate big arrays in the stack (for MSDOS) - don't allocate big arrays in the stack (for MSDOS)
- fix some MSDOS compilation problems - fix some MSDOS compilation problems
Changes in 0.5: Changes in 0.5:
- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
not yet Z_FULL_FLUSH. not yet Z_FULL_FLUSH
- support decompression but only in a single step (forced Z_FINISH) - support decompression but only in a single step (forced Z_FINISH)
- added opaque object for zalloc and zfree. - added opaque object for zalloc and zfree
- added deflateReset and inflateReset - added deflateReset and inflateReset
- added a variable zlib_version for consistency checking. - added a variable zlib_version for consistency checking
- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - renamed the 'filter' parameter of deflateInit2 as 'strategy'
Added Z_FILTERED and Z_HUFFMAN_ONLY constants. Added Z_FILTERED and Z_HUFFMAN_ONLY constants
Changes in 0.4: Changes in 0.4:
- avoid "zip" everywhere, use zlib instead of ziplib. - avoid "zip" everywhere, use zlib instead of ziplib
- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
if compression method == 8. if compression method == 8
- added adler32 and crc32 - added adler32 and crc32
- renamed deflateOptions as deflateInit2, call one or the other but not both - renamed deflateOptions as deflateInit2, call one or the other but not both
- added the method parameter for deflateInit2. - added the method parameter for deflateInit2
- added inflateInit2 - added inflateInit2
- simplied considerably deflateInit and inflateInit by not supporting - simplied considerably deflateInit and inflateInit by not supporting
user-provided history buffer. This is supported only in deflateInit2 user-provided history buffer. This is supported only in deflateInit2
and inflateInit2. and inflateInit2
Changes in 0.3: Changes in 0.3:
- prefix all macro names with Z_ - prefix all macro names with Z_
- use Z_FINISH instead of deflateEnd to finish compression. - use Z_FINISH instead of deflateEnd to finish compression
- added Z_HUFFMAN_ONLY - added Z_HUFFMAN_ONLY
- added gzerror() - added gzerror()
+8 -10
View File
@@ -32,7 +32,7 @@ CPP=$(CC) -E
STATICLIB=libz.a STATICLIB=libz.a
SHAREDLIB=libz.so SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.11 SHAREDLIBV=libz.so.1.2.12
SHAREDLIBM=libz.so.1 SHAREDLIBM=libz.so.1
LIBS=$(STATICLIB) $(SHAREDLIBV) LIBS=$(STATICLIB) $(SHAREDLIBV)
@@ -91,8 +91,8 @@ teststatic: static
echo ' *** zlib test OK ***'; \ echo ' *** zlib test OK ***'; \
else \ else \
echo ' *** zlib test FAILED ***'; false; \ echo ' *** zlib test FAILED ***'; false; \
fi; \ fi
rm -f $$TMPST @rm -f tmpst_$$
testshared: shared testshared: shared
@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
@@ -104,8 +104,8 @@ testshared: shared
echo ' *** zlib shared test OK ***'; \ echo ' *** zlib shared test OK ***'; \
else \ else \
echo ' *** zlib shared test FAILED ***'; false; \ echo ' *** zlib shared test FAILED ***'; false; \
fi; \ fi
rm -f $$TMPSH @rm -f tmpsh_$$
test64: all64 test64: all64
@TMP64=tmp64_$$; \ @TMP64=tmp64_$$; \
@@ -113,8 +113,8 @@ test64: all64
echo ' *** zlib 64-bit test OK ***'; \ echo ' *** zlib 64-bit test OK ***'; \
else \ else \
echo ' *** zlib 64-bit test FAILED ***'; false; \ echo ' *** zlib 64-bit test FAILED ***'; false; \
fi; \ fi
rm -f $$TMP64 @rm -f tmp64_$$
infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
@@ -376,15 +376,13 @@ clean:
rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
maintainer-clean: distclean maintainer-clean: distclean
distclean: clean zconf zconf.h.cmakein docs distclean: clean zconf zconf.h.cmakein
rm -f Makefile zlib.pc configure.log rm -f Makefile zlib.pc configure.log
-@rm -f .DS_Store -@rm -f .DS_Store
@if [ -f Makefile.in ]; then \ @if [ -f Makefile.in ]; then \
printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \
printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \
touch -r $(SRCDIR)Makefile.in Makefile ; fi touch -r $(SRCDIR)Makefile.in Makefile ; fi
@if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi
@if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi
tags: tags:
etags $(SRCDIR)*.[ch] etags $(SRCDIR)*.[ch]
+7 -4
View File
@@ -1,6 +1,6 @@
ZLIB DATA COMPRESSION LIBRARY ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.11 is a general purpose data compression library. All the code is zlib 1.2.12 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files (Request for Comments) 1950 to 1952 in the files
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
@@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available at issue of Dr. Dobb's Journal; a copy of the article is available at
http://marknelson.us/1997/01/01/zlib-engine/ . http://marknelson.us/1997/01/01/zlib-engine/ .
The changes made in version 1.2.11 are documented in the file ChangeLog. The changes made in version 1.2.12 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory contrib/ . Unsupported third party contributions are provided in directory contrib/ .
@@ -84,7 +84,7 @@ Acknowledgments:
Copyright notice: Copyright notice:
(C) 1995-2017 Jean-loup Gailly and Mark Adler (C) 1995-2022 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@@ -108,7 +108,10 @@ Copyright notice:
If you use the zlib library in a product, we would appreciate *not* receiving If you use the zlib library in a product, we would appreciate *not* receiving
lengthy legal documents to sign. The sources are provided for free but without lengthy legal documents to sign. The sources are provided for free but without
warranty of any kind. The library has been entirely written by Jean-loup warranty of any kind. The library has been entirely written by Jean-loup
Gailly and Mark Adler; it does not include third-party code. Gailly and Mark Adler; it does not include third-party code. We make all
contributions to and distributions of this project solely in our personal
capacity, and are not conveying any rights to any intellectual property of
any third parties.
If you redistribute modified sources, we would appreciate that you include in If you redistribute modified sources, we would appreciate that you include in
the file ChangeLog history information documenting your changes. Please read the file ChangeLog history information documenting your changes. Please read
+27 -21
View File
@@ -87,6 +87,7 @@ build64=0
gcc=0 gcc=0
warn=0 warn=0
debug=0 debug=0
sanitize=0
old_cc="$CC" old_cc="$CC"
old_cflags="$CFLAGS" old_cflags="$CFLAGS"
OBJC='$(OBJZ) $(OBJG)' OBJC='$(OBJZ) $(OBJG)'
@@ -137,6 +138,7 @@ case "$1" in
-c* | --const) zconst=1; shift ;; -c* | --const) zconst=1; shift ;;
-w* | --warn) warn=1; shift ;; -w* | --warn) warn=1; shift ;;
-d* | --debug) debug=1; shift ;; -d* | --debug) debug=1; shift ;;
--sanitize) sanitize=1; shift ;;
*) *)
echo "unknown option: $1" | tee -a configure.log echo "unknown option: $1" | tee -a configure.log
echo "$0 --help for help" | tee -a configure.log echo "$0 --help for help" | tee -a configure.log
@@ -165,8 +167,14 @@ extern int getchar();
int hello() {return getchar();} int hello() {return getchar();}
EOF EOF
test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log if test -z "$CC"; then
cc=${CC-${CROSS_PREFIX}gcc} echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
if ${CROSS_PREFIX}gcc -v >/dev/null 2>&1; then
cc=${CROSS_PREFIX}gcc
else
cc=${CROSS_PREFIX}cc
fi
fi
cflags=${CFLAGS-"-O3"} cflags=${CFLAGS-"-O3"}
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure # to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
case "$cc" in case "$cc" in
@@ -199,6 +207,9 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
fi fi
fi fi
if test $sanitize -eq 1; then
CFLAGS="${CFLAGS} -fsanitize=address"
fi
if test $debug -eq 1; then if test $debug -eq 1; then
CFLAGS="${CFLAGS} -DZLIB_DEBUG" CFLAGS="${CFLAGS} -DZLIB_DEBUG"
SFLAGS="${SFLAGS} -DZLIB_DEBUG" SFLAGS="${SFLAGS} -DZLIB_DEBUG"
@@ -367,8 +378,11 @@ else
try() try()
{ {
show $* show $*
( $* ) >> configure.log 2>&1 got=`( $* ) 2>&1`
ret=$? ret=$?
if test "$got" != ""; then
printf "%s\n" "$got" >> configure.log
fi
if test $ret -ne 0; then if test $ret -ne 0; then
echo "(exit code "$ret")" >> configure.log echo "(exit code "$ret")" >> configure.log
fi fi
@@ -381,8 +395,11 @@ tryboth()
show $* show $*
got=`( $* ) 2>&1` got=`( $* ) 2>&1`
ret=$? ret=$?
printf %s "$got" >> configure.log if test "$got" != ""; then
printf "%s\n" "$got" >> configure.log
fi
if test $ret -ne 0; then if test $ret -ne 0; then
echo "(exit code "$ret")" >> configure.log
return $ret return $ret
fi fi
test "$got" = "" test "$got" = ""
@@ -457,17 +474,11 @@ size_t dummy = 0;
EOF EOF
if try $CC -c $CFLAGS $test.c; then if try $CC -c $CFLAGS $test.c; then
echo "Checking for size_t... Yes." | tee -a configure.log echo "Checking for size_t... Yes." | tee -a configure.log
need_sizet=0
else else
echo "Checking for size_t... No." | tee -a configure.log echo "Checking for size_t... No." | tee -a configure.log
need_sizet=1 # find a size_t integer type
fi # check for long long
cat > $test.c << EOF
echo >> configure.log
# find the size_t integer type, if needed
if test $need_sizet -eq 1; then
cat > $test.c <<EOF
long long dummy = 0; long long dummy = 0;
EOF EOF
if try $CC -c $CFLAGS $test.c; then if try $CC -c $CFLAGS $test.c; then
@@ -495,17 +506,13 @@ EOF
if try $CC $CFLAGS -o $test $test.c; then if try $CC $CFLAGS -o $test $test.c; then
sizet=`./$test` sizet=`./$test`
echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log
CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
else else
echo "Failed to find a pointer-size integer type." | tee -a configure.log echo "Checking for a pointer-size integer type... not found." | tee -a configure.log
leave 1
fi fi
fi fi
if test $need_sizet -eq 1; then
CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
fi
echo >> configure.log echo >> configure.log
# check for large file support, and if none, check for fseeko() # check for large file support, and if none, check for fseeko()
@@ -849,7 +856,6 @@ echo SHAREDLIBV = $SHAREDLIBV >> configure.log
echo STATICLIB = $STATICLIB >> configure.log echo STATICLIB = $STATICLIB >> configure.log
echo TEST = $TEST >> configure.log echo TEST = $TEST >> configure.log
echo VER = $VER >> configure.log echo VER = $VER >> configure.log
echo Z_U4 = $Z_U4 >> configure.log
echo SRCDIR = $SRCDIR >> configure.log echo SRCDIR = $SRCDIR >> configure.log
echo exec_prefix = $exec_prefix >> configure.log echo exec_prefix = $exec_prefix >> configure.log
echo includedir = $includedir >> configure.log echo includedir = $includedir >> configure.log
-21
View File
@@ -8,14 +8,6 @@ ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
Support for Ada Support for Ada
See http://zlib-ada.sourceforge.net/ See http://zlib-ada.sourceforge.net/
amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
asm code for AMD64
See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
asm686/ by Brian Raiter <breadbox@muppetlabs.com>
asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
See http://www.muppetlabs.com/~breadbox/software/assembly.html
blast/ by Mark Adler <madler@alumni.caltech.edu> blast/ by Mark Adler <madler@alumni.caltech.edu>
Decompressor for output of PKWare Data Compression Library (DCL) Decompressor for output of PKWare Data Compression Library (DCL)
@@ -32,9 +24,6 @@ gcc_gvmat64/by Gilles Vollant <info@winimage.com>
infback9/ by Mark Adler <madler@alumni.caltech.edu> infback9/ by Mark Adler <madler@alumni.caltech.edu>
Unsupported diffs to infback to decode the deflate64 format Unsupported diffs to infback to decode the deflate64 format
inflate86/ by Chris Anderson <christop@charm.net>
Tuned x86 gcc asm code to replace inflate_fast()
iostream/ by Kevin Ruland <kevin@rodin.wustl.edu> iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
A C++ I/O streams interface to the zlib gz* functions A C++ I/O streams interface to the zlib gz* functions
@@ -45,16 +34,6 @@ iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
and Kevin Ruland <kevin@rodin.wustl.edu> and Kevin Ruland <kevin@rodin.wustl.edu>
Yet another C++ I/O streams interface Yet another C++ I/O streams interface
masmx64/ by Gilles Vollant <info@winimage.com>
x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
replace longest_match() and inflate_fast(), also masm x86
64-bits translation of Chris Anderson inflate_fast()
masmx86/ by Gilles Vollant <info@winimage.com>
x86 asm code to replace longest_match() and inflate_fast(),
for Visual C++ and MASM (32 bits).
Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
minizip/ by Gilles Vollant <info@winimage.com> minizip/ by Gilles Vollant <info@winimage.com>
Mini zip and unzip based on zlib Mini zip and unzip based on zlib
Includes Zip64 support by Mathias Svensson <mathias@result42.com> Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+1 -1
View File
@@ -57,7 +57,7 @@ int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
* use by the application to pass an input descriptor to infun(), if desired. * use by the application to pass an input descriptor to infun(), if desired.
* *
* If left and in are not NULL and *left is not zero when blast() is called, * If left and in are not NULL and *left is not zero when blast() is called,
* then the *left bytes are *in are consumed for input before infun() is used. * then the *left bytes at *in are consumed for input before infun() is used.
* *
* The output function is invoked: err = outfun(how, buf, len), where the bytes * The output function is invoked: err = outfun(how, buf, len), where the bytes
* to be written are buf[0..len-1]. If err is not zero, then blast() returns * to be written are buf[0..len-1]. If err is not zero, then blast() returns
+1 -1
View File
@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
const OutBuf: Pointer; BufSize: Integer); const OutBuf: Pointer; BufSize: Integer);
const const
zlib_version = '1.2.11'; zlib_version = '1.2.12';
type type
EZlibError = class(Exception); EZlibError = class(Exception);
@@ -156,7 +156,7 @@ namespace DotZLibTests
public void Info_Version() public void Info_Version()
{ {
Info info = new Info(); Info info = new Info();
Assert.AreEqual("1.2.11", Info.Version); Assert.AreEqual("1.2.12", Info.Version);
Assert.AreEqual(32, info.SizeOfUInt); Assert.AreEqual(32, info.SizeOfUInt);
Assert.AreEqual(32, info.SizeOfULong); Assert.AreEqual(32, info.SizeOfULong);
Assert.AreEqual(32, info.SizeOfPointer); Assert.AreEqual(32, info.SizeOfPointer);
+3 -3
View File
@@ -1,5 +1,5 @@
/* inftree9.c -- generate Huffman trees for efficient decoding /* inftree9.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2017 Mark Adler * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate9_copyright[] = const char inflate9_copyright[] =
" inflate9 1.2.11 Copyright 1995-2017 Mark Adler "; " inflate9 1.2.12 Copyright 1995-2022 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
133, 133, 133, 133, 144, 77, 202}; 133, 133, 133, 133, 144, 199, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
+8 -4
View File
@@ -1,5 +1,5 @@
CC=cc CC=cc
CFLAGS=-O -I../.. CFLAGS := $(CFLAGS) -O -I../..
UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
@@ -16,10 +16,14 @@ minizip: $(ZIP_OBJS)
$(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
test: miniunz minizip test: miniunz minizip
./minizip test readme.txt @rm -f test.*
@echo hello hello hello > test.txt
./minizip test test.txt
./miniunz -l test.zip ./miniunz -l test.zip
mv readme.txt readme.old @mv test.txt test.old
./miniunz test.zip ./miniunz test.zip
@cmp test.txt test.old
@rm -f test.*
clean: clean:
/bin/rm -f *.o *~ minizip miniunz /bin/rm -f *.o *~ minizip miniunz test.*
@@ -1,7 +1,7 @@
# -*- Autoconf -*- # -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_INIT([minizip], [1.2.11], [bugzilla.redhat.com]) AC_INIT([minizip], [1.2.12], [bugzilla.redhat.com])
AC_CONFIG_SRCDIR([minizip.c]) AC_CONFIG_SRCDIR([minizip.c])
AM_INIT_AUTOMAKE([foreign]) AM_INIT_AUTOMAKE([foreign])
LT_INIT LT_INIT
+10 -9
View File
@@ -38,6 +38,7 @@ static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
* unpredictable manner on 16-bit systems; not a problem * unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */ * with any known compiler so far, though */
(void)pcrc_32_tab;
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
} }
@@ -77,24 +78,24 @@ static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcr
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
#define zencode(pkeys,pcrc_32_tab,c,t) \ #define zencode(pkeys,pcrc_32_tab,c,t) \
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
#define RAND_HEAD_LEN 12 #define RAND_HEAD_LEN 12
/* "last resort" source for second part of crypt seed pattern */ /* "last resort" source for second part of crypt seed pattern */
# ifndef ZCR_SEED2 # ifndef ZCR_SEED2
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ # define ZCR_SEED2 3141592654L /* use PI as default pattern */
# endif # endif
static int crypthead(const char* passwd, /* password string */ static unsigned crypthead(const char* passwd, /* password string */
unsigned char* buf, /* where to write header */ unsigned char* buf, /* where to write header */
int bufSize, int bufSize,
unsigned long* pkeys, unsigned long* pkeys,
const z_crc_t* pcrc_32_tab, const z_crc_t* pcrc_32_tab,
unsigned long crcForCrypting) unsigned long crcForCrypting)
{ {
int n; /* index in random header */ unsigned n; /* index in random header */
int t; /* temporary */ int t; /* temporary */
int c; /* random byte */ int c; /* random byte */
unsigned char header[RAND_HEAD_LEN-2]; /* random header */ unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+14 -4
View File
@@ -58,7 +58,7 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
else else
{ {
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); uLong tell_uLong = (uLong)(*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
if ((tell_uLong) == MAXU32) if ((tell_uLong) == MAXU32)
return (ZPOS64_T)-1; return (ZPOS64_T)-1;
else else
@@ -94,6 +94,7 @@ static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
{ {
(void)opaque;
FILE* file = NULL; FILE* file = NULL;
const char* mode_fopen = NULL; const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
@@ -112,6 +113,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
{ {
(void)opaque;
FILE* file = NULL; FILE* file = NULL;
const char* mode_fopen = NULL; const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
@@ -131,6 +133,7 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
{ {
(void)opaque;
uLong ret; uLong ret;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
@@ -138,6 +141,7 @@ static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf,
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
{ {
(void)opaque;
uLong ret; uLong ret;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
@@ -145,6 +149,7 @@ static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const voi
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
{ {
(void)opaque;
long ret; long ret;
ret = ftell((FILE *)stream); ret = ftell((FILE *)stream);
return ret; return ret;
@@ -153,13 +158,15 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
{ {
(void)opaque;
ZPOS64_T ret; ZPOS64_T ret;
ret = FTELLO_FUNC((FILE *)stream); ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream);
return ret; return ret;
} }
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
{ {
(void)opaque;
int fseek_origin=0; int fseek_origin=0;
long ret; long ret;
switch (origin) switch (origin)
@@ -176,13 +183,14 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs
default: return -1; default: return -1;
} }
ret = 0; ret = 0;
if (fseek((FILE *)stream, offset, fseek_origin) != 0) if (fseek((FILE *)stream, (long)offset, fseek_origin) != 0)
ret = -1; ret = -1;
return ret; return ret;
} }
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{ {
(void)opaque;
int fseek_origin=0; int fseek_origin=0;
long ret; long ret;
switch (origin) switch (origin)
@@ -200,7 +208,7 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
} }
ret = 0; ret = 0;
if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) if(FSEEKO_FUNC((FILE *)stream, (long)offset, fseek_origin) != 0)
ret = -1; ret = -1;
return ret; return ret;
@@ -209,6 +217,7 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
{ {
(void)opaque;
int ret; int ret;
ret = fclose((FILE *)stream); ret = fclose((FILE *)stream);
return ret; return ret;
@@ -216,6 +225,7 @@ static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
{ {
(void)opaque;
int ret; int ret;
ret = ferror((FILE *)stream); ret = ferror((FILE *)stream);
return ret; return ret;
+5 -3
View File
@@ -91,8 +91,7 @@ typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
typedef uint64_t ZPOS64_T; typedef uint64_t ZPOS64_T;
#else #else
/* Maximum unsigned 32-bit value used as placeholder for zip64 */
#define MAXU32 0xffffffff
#if defined(_MSC_VER) || defined(__BORLANDC__) #if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ZPOS64_T; typedef unsigned __int64 ZPOS64_T;
@@ -102,7 +101,10 @@ typedef unsigned long long int ZPOS64_T;
#endif #endif
#endif #endif
/* Maximum unsigned 32-bit value used as placeholder for zip64 */
#ifndef MAXU32
#define MAXU32 (0xffffffff)
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
+17 -18
View File
@@ -45,6 +45,7 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h>
#ifdef _WIN32 #ifdef _WIN32
# include <direct.h> # include <direct.h>
@@ -80,7 +81,7 @@
filename : the filename of the file where date/time must be modified filename : the filename of the file where date/time must be modified
dosdate : the new date at the MSDos format (4 bytes) dosdate : the new date at the MSDos format (4 bytes)
tmu_date : the SAME new date at the tm_unz format */ tmu_date : the SAME new date at the tm_unz format */
void change_file_date(filename,dosdate,tmu_date) static void change_file_date(filename,dosdate,tmu_date)
const char *filename; const char *filename;
uLong dosdate; uLong dosdate;
tm_unz tmu_date; tm_unz tmu_date;
@@ -97,7 +98,8 @@ void change_file_date(filename,dosdate,tmu_date)
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile); CloseHandle(hFile);
#else #else
#ifdef unix || __APPLE__ #if defined(unix) || defined(__APPLE__)
(void)dosdate;
struct utimbuf ut; struct utimbuf ut;
struct tm newdate; struct tm newdate;
newdate.tm_sec = tmu_date.tm_sec; newdate.tm_sec = tmu_date.tm_sec;
@@ -121,7 +123,7 @@ void change_file_date(filename,dosdate,tmu_date)
/* mymkdir and change_file_date are not 100 % portable /* mymkdir and change_file_date are not 100 % portable
As I don't know well Unix, I wait feedback for the unix portion */ As I don't know well Unix, I wait feedback for the unix portion */
int mymkdir(dirname) static int mymkdir(dirname)
const char* dirname; const char* dirname;
{ {
int ret=0; int ret=0;
@@ -135,14 +137,14 @@ int mymkdir(dirname)
return ret; return ret;
} }
int makedir (newdir) static int makedir (newdir)
char *newdir; const char *newdir;
{ {
char *buffer ; char *buffer ;
char *p; char *p;
int len = (int)strlen(newdir); size_t len = strlen(newdir);
if (len <= 0) if (len == 0)
return 0; return 0;
buffer = (char*)malloc(len+1); buffer = (char*)malloc(len+1);
@@ -185,13 +187,13 @@ int makedir (newdir)
return 1; return 1;
} }
void do_banner() static void do_banner()
{ {
printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
} }
void do_help() static void do_help()
{ {
printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
" -e Extract without pathname (junk paths)\n" \ " -e Extract without pathname (junk paths)\n" \
@@ -203,7 +205,7 @@ void do_help()
" -p extract crypted file using password\n\n"); " -p extract crypted file using password\n\n");
} }
void Display64BitsSize(ZPOS64_T n, int size_char) static void Display64BitsSize(ZPOS64_T n, int size_char)
{ {
/* to avoid compatibility problem , we do here the conversion */ /* to avoid compatibility problem , we do here the conversion */
char number[21]; char number[21];
@@ -231,7 +233,7 @@ void Display64BitsSize(ZPOS64_T n, int size_char)
printf("%s",&number[pos_string]); printf("%s",&number[pos_string]);
} }
int do_list(uf) static int do_list(uf)
unzFile uf; unzFile uf;
{ {
uLong i; uLong i;
@@ -309,7 +311,7 @@ int do_list(uf)
} }
int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password) static int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
unzFile uf; unzFile uf;
const int* popt_extract_without_path; const int* popt_extract_without_path;
int* popt_overwrite; int* popt_overwrite;
@@ -324,7 +326,6 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
uInt size_buf; uInt size_buf;
unz_file_info64 file_info; unz_file_info64 file_info;
uLong ratio=0;
err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
if (err!=UNZ_OK) if (err!=UNZ_OK)
@@ -439,7 +440,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
break; break;
} }
if (err>0) if (err>0)
if (fwrite(buf,err,1,fout)!=1) if (fwrite(buf,(unsigned)err,1,fout)!=1)
{ {
printf("error in writing extracted file\n"); printf("error in writing extracted file\n");
err=UNZ_ERRNO; err=UNZ_ERRNO;
@@ -472,7 +473,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
} }
int do_extract(uf,opt_extract_without_path,opt_overwrite,password) static int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
unzFile uf; unzFile uf;
int opt_extract_without_path; int opt_extract_without_path;
int opt_overwrite; int opt_overwrite;
@@ -481,7 +482,6 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
uLong i; uLong i;
unz_global_info64 gi; unz_global_info64 gi;
int err; int err;
FILE* fout=NULL;
err = unzGetGlobalInfo64(uf,&gi); err = unzGetGlobalInfo64(uf,&gi);
if (err!=UNZ_OK) if (err!=UNZ_OK)
@@ -508,14 +508,13 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
return 0; return 0;
} }
int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password) static int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
unzFile uf; unzFile uf;
const char* filename; const char* filename;
int opt_extract_without_path; int opt_extract_without_path;
int opt_overwrite; int opt_overwrite;
const char* password; const char* password;
{ {
int err = UNZ_OK;
if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK) if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
{ {
printf("file %s not found in the zipfile\n",filename); printf("file %s not found in the zipfile\n",filename);
+21 -20
View File
@@ -71,8 +71,8 @@
#define MAXFILENAME (256) #define MAXFILENAME (256)
#ifdef _WIN32 #ifdef _WIN32
uLong filetime(f, tmzip, dt) static int filetime(f, tmzip, dt)
char *f; /* name of file to get info on */ const char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */ tm_zip *tmzip; /* return value: access, modific. and creation times */
uLong *dt; /* dostime */ uLong *dt; /* dostime */
{ {
@@ -94,12 +94,13 @@ uLong filetime(f, tmzip, dt)
return ret; return ret;
} }
#else #else
#ifdef unix || __APPLE__ #if defined(unix) || defined(__APPLE__)
uLong filetime(f, tmzip, dt) static int filetime(f, tmzip, dt)
char *f; /* name of file to get info on */ const char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */ tm_zip *tmzip; /* return value: access, modific. and creation times */
uLong *dt; /* dostime */ uLong *dt; /* dostime */
{ {
(void)dt;
int ret=0; int ret=0;
struct stat s; /* results of stat() */ struct stat s; /* results of stat() */
struct tm* filedate; struct tm* filedate;
@@ -108,7 +109,7 @@ uLong filetime(f, tmzip, dt)
if (strcmp(f,"-")!=0) if (strcmp(f,"-")!=0)
{ {
char name[MAXFILENAME+1]; char name[MAXFILENAME+1];
int len = strlen(f); size_t len = strlen(f);
if (len > MAXFILENAME) if (len > MAXFILENAME)
len = MAXFILENAME; len = MAXFILENAME;
@@ -138,7 +139,7 @@ uLong filetime(f, tmzip, dt)
} }
#else #else
uLong filetime(f, tmzip, dt) uLong filetime(f, tmzip, dt)
char *f; /* name of file to get info on */ const char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */ tm_zip *tmzip; /* return value: access, modific. and creation times */
uLong *dt; /* dostime */ uLong *dt; /* dostime */
{ {
@@ -150,7 +151,7 @@ uLong filetime(f, tmzip, dt)
int check_exist_file(filename) static int check_exist_file(filename)
const char* filename; const char* filename;
{ {
FILE* ftestexist; FILE* ftestexist;
@@ -163,13 +164,13 @@ int check_exist_file(filename)
return ret; return ret;
} }
void do_banner() static void do_banner()
{ {
printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n"); printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n"); printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
} }
void do_help() static void do_help()
{ {
printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
" -o Overwrite existing file.zip\n" \ " -o Overwrite existing file.zip\n" \
@@ -182,7 +183,7 @@ void do_help()
/* calculate the CRC32 of a file, /* calculate the CRC32 of a file,
because to encrypt a file, we need known the CRC32 of the file before */ because to encrypt a file, we need known the CRC32 of the file before */
int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) static int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
{ {
unsigned long calculate_crc=0; unsigned long calculate_crc=0;
int err=ZIP_OK; int err=ZIP_OK;
@@ -199,7 +200,7 @@ int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigne
do do
{ {
err = ZIP_OK; err = ZIP_OK;
size_read = (int)fread(buf,1,size_buf,fin); size_read = fread(buf,1,size_buf,fin);
if (size_read < size_buf) if (size_read < size_buf)
if (feof(fin)==0) if (feof(fin)==0)
{ {
@@ -208,7 +209,7 @@ int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigne
} }
if (size_read>0) if (size_read>0)
calculate_crc = crc32(calculate_crc,buf,size_read); calculate_crc = crc32_z(calculate_crc,buf,size_read);
total_read += size_read; total_read += size_read;
} while ((err == ZIP_OK) && (size_read>0)); } while ((err == ZIP_OK) && (size_read>0));
@@ -221,7 +222,7 @@ int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigne
return err; return err;
} }
int isLargeFile(const char* filename) static int isLargeFile(const char* filename)
{ {
int largeFile = 0; int largeFile = 0;
ZPOS64_T pos = 0; ZPOS64_T pos = 0;
@@ -229,8 +230,8 @@ int isLargeFile(const char* filename)
if(pFile != NULL) if(pFile != NULL)
{ {
int n = FSEEKO_FUNC(pFile, 0, SEEK_END); FSEEKO_FUNC(pFile, 0, SEEK_END);
pos = FTELLO_FUNC(pFile); pos = (ZPOS64_T)FTELLO_FUNC(pFile);
printf("File : %s is %lld bytes\n", filename, pos); printf("File : %s is %lld bytes\n", filename, pos);
@@ -255,7 +256,7 @@ int main(argc,argv)
char filename_try[MAXFILENAME+16]; char filename_try[MAXFILENAME+16];
int zipok; int zipok;
int err=0; int err=0;
int size_buf=0; size_t size_buf=0;
void* buf=NULL; void* buf=NULL;
const char* password=NULL; const char* password=NULL;
@@ -396,7 +397,7 @@ int main(argc,argv)
(strlen(argv[i]) == 2))) (strlen(argv[i]) == 2)))
{ {
FILE * fin; FILE * fin;
int size_read; size_t size_read;
const char* filenameinzip = argv[i]; const char* filenameinzip = argv[i];
const char *savefilenameinzip; const char *savefilenameinzip;
zip_fileinfo zi; zip_fileinfo zi;
@@ -472,7 +473,7 @@ int main(argc,argv)
do do
{ {
err = ZIP_OK; err = ZIP_OK;
size_read = (int)fread(buf,1,size_buf,fin); size_read = fread(buf,1,size_buf,fin);
if (size_read < size_buf) if (size_read < size_buf)
if (feof(fin)==0) if (feof(fin)==0)
{ {
@@ -482,7 +483,7 @@ int main(argc,argv)
if (size_read>0) if (size_read>0)
{ {
err = zipWriteInFileInZip (zf,buf,size_read); err = zipWriteInFileInZip (zf,buf,(unsigned)size_read);
if (err<0) if (err<0)
{ {
printf("error in writing %s in the zipfile\n", printf("error in writing %s in the zipfile\n",
+17 -14
View File
@@ -455,7 +455,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
{ {
uPosFound = uReadPos+i; uPosFound = uReadPos+(unsigned)i;
break; break;
} }
@@ -523,7 +523,7 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
{ {
uPosFound = uReadPos+i; uPosFound = uReadPos+(unsigned)i;
break; break;
} }
@@ -853,13 +853,13 @@ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
{ {
ZPOS64_T uDate; ZPOS64_T uDate;
uDate = (ZPOS64_T)(ulDosDate>>16); uDate = (ZPOS64_T)(ulDosDate>>16);
ptm->tm_mday = (uInt)(uDate&0x1f) ; ptm->tm_mday = (int)(uDate&0x1f) ;
ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ptm->tm_mon = (int)((((uDate)&0x1E0)/0x20)-1) ;
ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ptm->tm_year = (int)(((uDate&0x0FE00)/0x0200)+1980) ;
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ptm->tm_hour = (int) ((ulDosDate &0xF800)/0x800);
ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ptm->tm_min = (int) ((ulDosDate&0x7E0)/0x20) ;
ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; ptm->tm_sec = (int) (2*(ulDosDate&0x1f)) ;
} }
/* /*
@@ -993,7 +993,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
if (lSeek!=0) if (lSeek!=0)
{ {
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0; lSeek=0;
else else
err=UNZ_ERRNO; err=UNZ_ERRNO;
@@ -1018,7 +1018,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
if (lSeek!=0) if (lSeek!=0)
{ {
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0; lSeek=0;
else else
err=UNZ_ERRNO; err=UNZ_ERRNO;
@@ -1090,7 +1090,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
if (lSeek!=0) if (lSeek!=0)
{ {
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0; lSeek=0;
else else
err=UNZ_ERRNO; err=UNZ_ERRNO;
@@ -1767,7 +1767,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
if ((pfile_in_zip_read_info->stream.avail_in == 0) && if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
(pfile_in_zip_read_info->rest_read_compressed == 0)) (pfile_in_zip_read_info->rest_read_compressed == 0))
return (iRead==0) ? UNZ_EOF : iRead; return (iRead==0) ? UNZ_EOF : (int)iRead;
if (pfile_in_zip_read_info->stream.avail_out < if (pfile_in_zip_read_info->stream.avail_out <
pfile_in_zip_read_info->stream.avail_in) pfile_in_zip_read_info->stream.avail_in)
@@ -1857,6 +1857,9 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
err = Z_DATA_ERROR; err = Z_DATA_ERROR;
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
/* Detect overflow, because z_stream.total_out is uLong (32 bits) */
if (uTotalOutAfter<uTotalOutBefore)
uTotalOutAfter += 1LL << 32; /* Add maximum value of uLong + 1 */
uOutThis = uTotalOutAfter-uTotalOutBefore; uOutThis = uTotalOutAfter-uTotalOutBefore;
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
@@ -1871,14 +1874,14 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
if (err==Z_STREAM_END) if (err==Z_STREAM_END)
return (iRead==0) ? UNZ_EOF : iRead; return (iRead==0) ? UNZ_EOF : (int)iRead;
if (err!=Z_OK) if (err!=Z_OK)
break; break;
} }
} }
if (err==Z_OK) if (err==Z_OK)
return iRead; return (int)iRead;
return err; return err;
} }
+6 -6
View File
@@ -83,12 +83,12 @@ typedef voidp unzFile;
/* tm_unz contain date/time info */ /* tm_unz contain date/time info */
typedef struct tm_unz_s typedef struct tm_unz_s
{ {
uInt tm_sec; /* seconds after the minute - [0,59] */ int tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */ int tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */ int tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */ int tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */ int tm_year; /* years - [1980..2044] */
} tm_unz; } tm_unz;
/* unz_global_info structure contain global data about the ZIPfile /* unz_global_info structure contain global data about the ZIPfile
+18 -18
View File
@@ -158,7 +158,7 @@ typedef struct
#ifndef NOCRYPT #ifndef NOCRYPT
unsigned long keys[3]; /* keys defining the pseudo-random sequence */ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
const z_crc_t* pcrc_32_tab; const z_crc_t* pcrc_32_tab;
int crypt_header_size; unsigned crypt_header_size;
#endif #endif
} curfile64_info; } curfile64_info;
@@ -301,7 +301,7 @@ local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def,
} }
} }
if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte)
return ZIP_ERRNO; return ZIP_ERRNO;
else else
return ZIP_OK; return ZIP_OK;
@@ -337,8 +337,8 @@ local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
else if (year>=80) else if (year>=80)
year-=80; year-=80;
return return
(uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon+1)) + (512 * year)) << 16) |
((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); (((uLong)ptm->tm_sec/2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
} }
@@ -522,12 +522,12 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
{ {
uPosFound = uReadPos+i; uPosFound = uReadPos+(unsigned)i;
break; break;
} }
if (uPosFound!=0) if (uPosFound!=0)
break; break;
} }
TRYFREE(buf); TRYFREE(buf);
return uPosFound; return uPosFound;
@@ -586,7 +586,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
// Signature "0x07064b50" Zip64 end of central directory locater // Signature "0x07064b50" Zip64 end of central directory locater
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
{ {
uPosFound = uReadPos+i; uPosFound = uReadPos+(unsigned)i;
break; break;
} }
} }
@@ -637,7 +637,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
return relativeOffset; return relativeOffset;
} }
int LoadCentralDirectoryRecord(zip64_internal* pziinit) local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
{ {
int err=ZIP_OK; int err=ZIP_OK;
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
@@ -955,7 +955,7 @@ extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
return zipOpen3(pathname,append,NULL,NULL); return zipOpen3(pathname,append,NULL,NULL);
} }
int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
{ {
/* write the local header */ /* write the local header */
int err; int err;
@@ -1034,8 +1034,8 @@ int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_ex
// Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2);
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2);
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
@@ -1516,7 +1516,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
zip64_internal* zi; zip64_internal* zi;
ZPOS64_T compressed_size; ZPOS64_T compressed_size;
uLong invalidValue = 0xffffffff; uLong invalidValue = 0xffffffff;
short datasize = 0; unsigned datasize = 0;
int err=ZIP_OK; int err=ZIP_OK;
if (file == NULL) if (file == NULL)
@@ -1752,7 +1752,7 @@ extern int ZEXPORT zipCloseFileInZip (zipFile file)
return zipCloseFileInZipRaw (file,0,0); return zipCloseFileInZipRaw (file,0,0);
} }
int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
{ {
int err = ZIP_OK; int err = ZIP_OK;
ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
@@ -1774,7 +1774,7 @@ int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo
return err; return err;
} }
int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
{ {
int err = ZIP_OK; int err = ZIP_OK;
@@ -1813,7 +1813,7 @@ int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centra
} }
return err; return err;
} }
int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
{ {
int err = ZIP_OK; int err = ZIP_OK;
@@ -1861,7 +1861,7 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
return err; return err;
} }
int Write_GlobalComment(zip64_internal* zi, const char* global_comment) local int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
{ {
int err = ZIP_OK; int err = ZIP_OK;
uInt size_global_comment = 0; uInt size_global_comment = 0;
@@ -1962,7 +1962,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe
if(pData == NULL || *dataLen < 4) if(pData == NULL || *dataLen < 4)
return ZIP_PARAMERROR; return ZIP_PARAMERROR;
pNewHeader = (char*)ALLOC(*dataLen); pNewHeader = (char*)ALLOC((unsigned)*dataLen);
pTmp = pNewHeader; pTmp = pNewHeader;
while(p < (pData + *dataLen)) while(p < (pData + *dataLen))
+11 -6
View File
@@ -88,12 +88,12 @@ typedef voidp zipFile;
/* tm_zip contain date/time info */ /* tm_zip contain date/time info */
typedef struct tm_zip_s typedef struct tm_zip_s
{ {
uInt tm_sec; /* seconds after the minute - [0,59] */ int tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */ int tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */ int tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */ int tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */ int tm_year; /* years - [1980..2044] */
} tm_zip; } tm_zip;
typedef struct typedef struct
@@ -144,6 +144,11 @@ extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
zipcharpc* globalcomment, zipcharpc* globalcomment,
zlib_filefunc64_def* pzlib_filefunc_def)); zlib_filefunc64_def* pzlib_filefunc_def));
extern zipFile ZEXPORT zipOpen3 OF((const void *pathname,
int append,
zipcharpc* globalcomment,
zlib_filefunc64_32_def* pzlib_filefunc64_32_def));
extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
const char* filename, const char* filename,
const zip_fileinfo* zipfi, const zip_fileinfo* zipfi,
+1 -1
View File
@@ -10,7 +10,7 @@ unit zlibpas;
interface interface
const const
ZLIB_VERSION = '1.2.11'; ZLIB_VERSION = '1.2.12';
ZLIB_VERNUM = $12a0; ZLIB_VERNUM = $12a0;
type type
+1 -1
View File
@@ -1,4 +1,4 @@
Building instructions for the DLL versions of Zlib 1.2.11 Building instructions for the DLL versions of Zlib 1.2.12
======================================================== ========================================================
This directory contains projects that build zlib and minizip using This directory contains projects that build zlib and minizip using
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1, 2, 11, 0 FILEVERSION 1, 2, 12, 0
PRODUCTVERSION 1, 2, 11, 0 PRODUCTVERSION 1, 2, 12, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
VALUE "FileVersion", "1.2.11\0" VALUE "FileVersion", "1.2.12\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -151,3 +151,8 @@ EXPORTS
deflateGetDictionary @173 deflateGetDictionary @173
adler32_z @174 adler32_z @174
crc32_z @175 crc32_z @175
; zlib1 v1.2.12 added:
crc32_combine_gen @176
crc32_combine_gen64 @177
crc32_combine_op @178
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1, 2, 11, 0 FILEVERSION 1, 2, 12, 0
PRODUCTVERSION 1, 2, 11, 0 PRODUCTVERSION 1, 2, 12, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
VALUE "FileVersion", "1.2.11\0" VALUE "FileVersion", "1.2.12\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -151,3 +151,8 @@ EXPORTS
deflateGetDictionary @173 deflateGetDictionary @173
adler32_z @174 adler32_z @174
crc32_z @175 crc32_z @175
; zlib1 v1.2.12 added:
crc32_combine_gen @176
crc32_combine_gen64 @177
crc32_combine_op @178
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1, 2, 11, 0 FILEVERSION 1, 2, 12, 0
PRODUCTVERSION 1, 2, 11, 0 PRODUCTVERSION 1, 2, 12, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
VALUE "FileVersion", "1.2.11\0" VALUE "FileVersion", "1.2.12\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -151,3 +151,8 @@ EXPORTS
deflateGetDictionary @173 deflateGetDictionary @173
adler32_z @174 adler32_z @174
crc32_z @175 crc32_z @175
; zlib1 v1.2.12 added:
crc32_combine_gen @176
crc32_combine_gen64 @177
crc32_combine_op @178
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1, 2, 11, 0 FILEVERSION 1, 2, 12, 0
PRODUCTVERSION 1, 2, 11, 0 PRODUCTVERSION 1, 2, 12, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
VALUE "FileVersion", "1.2.11\0" VALUE "FileVersion", "1.2.12\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -151,3 +151,8 @@ EXPORTS
deflateGetDictionary @173 deflateGetDictionary @173
adler32_z @174 adler32_z @174
crc32_z @175 crc32_z @175
; zlib1 v1.2.12 added:
crc32_combine_gen @176
crc32_combine_gen64 @177
crc32_combine_op @178
+4 -4
View File
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1, 2, 11, 0 FILEVERSION 1, 2, 12, 0
PRODUCTVERSION 1, 2, 11, 0 PRODUCTVERSION 1, 2, 12, 0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
VALUE "FileVersion", "1.2.11\0" VALUE "FileVersion", "1.2.12\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@@ -151,3 +151,8 @@ EXPORTS
deflateGetDictionary @173 deflateGetDictionary @173
adler32_z @174 adler32_z @174
crc32_z @175 crc32_z @175
; zlib1 v1.2.12 added:
crc32_combine_gen @176
crc32_combine_gen64 @177
crc32_combine_op @178
+984 -310
View File
File diff suppressed because it is too large Load Diff
+9441 -436
View File
File diff suppressed because it is too large Load Diff
+78 -30
View File
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm /* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -52,7 +52,7 @@
#include "deflate.h" #include "deflate.h"
const char deflate_copyright[] = const char deflate_copyright[] =
" deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; " deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -190,8 +190,11 @@ local const config configuration_table[10] = {
* prev[] will be initialized on the fly. * prev[] will be initialized on the fly.
*/ */
#define CLEAR_HASH(s) \ #define CLEAR_HASH(s) \
s->head[s->hash_size-1] = NIL; \ do { \
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); s->head[s->hash_size-1] = NIL; \
zmemzero((Bytef *)s->head, \
(unsigned)(s->hash_size-1)*sizeof(*s->head)); \
} while (0)
/* =========================================================================== /* ===========================================================================
* Slide the hash table when sliding the window down (could be avoided with 32 * Slide the hash table when sliding the window down (could be avoided with 32
@@ -252,11 +255,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
int wrap = 1; int wrap = 1;
static const char my_version[] = ZLIB_VERSION; static const char my_version[] = ZLIB_VERSION;
ushf *overlay;
/* We overlay pending_buf and d_buf+l_buf. This works since the average
* output size for (length,distance) codes is <= 24 bits.
*/
if (version == Z_NULL || version[0] != my_version[0] || if (version == Z_NULL || version[0] != my_version[0] ||
stream_size != sizeof(z_stream)) { stream_size != sizeof(z_stream)) {
return Z_VERSION_ERROR; return Z_VERSION_ERROR;
@@ -326,9 +324,47 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); /* We overlay pending_buf and sym_buf. This works since the average size
s->pending_buf = (uchf *) overlay; * for length/distance pairs over any compressed block is assured to be 31
s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); * bits or less.
*
* Analysis: The longest fixed codes are a length code of 8 bits plus 5
* extra bits, for lengths 131 to 257. The longest fixed distance codes are
* 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
* possible fixed-codes length/distance pair is then 31 bits total.
*
* sym_buf starts one-fourth of the way into pending_buf. So there are
* three bytes in sym_buf for every four bytes in pending_buf. Each symbol
* in sym_buf is three bytes -- two for the distance and one for the
* literal/length. As each symbol is consumed, the pointer to the next
* sym_buf value to read moves forward three bytes. From that symbol, up to
* 31 bits are written to pending_buf. The closest the written pending_buf
* bits gets to the next sym_buf symbol to read is just before the last
* code is written. At that time, 31*(n-2) bits have been written, just
* after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
* symbols are written.) The closest the writing gets to what is unread is
* then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
* can range from 128 to 32768.
*
* Therefore, at a minimum, there are 142 bits of space between what is
* written and what is read in the overlain buffers, so the symbols cannot
* be overwritten by the compressed data. That space is actually 139 bits,
* due to the three-bit fixed-code block header.
*
* That covers the case where either Z_FIXED is specified, forcing fixed
* codes, or when the use of fixed codes is chosen, because that choice
* results in a smaller compressed block than dynamic codes. That latter
* condition then assures that the above analysis also covers all dynamic
* blocks. A dynamic-code block will only be chosen to be emitted if it has
* fewer bits than a fixed-code block would for the same set of symbols.
* Therefore its average symbol length is assured to be less than 31. So
* the compressed data for a dynamic block also cannot overwrite the
* symbols from which it is being constructed.
*/
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
s->pending_buf_size = (ulg)s->lit_bufsize * 4;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) { s->pending_buf == Z_NULL) {
@@ -337,8 +373,12 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
deflateEnd (strm); deflateEnd (strm);
return Z_MEM_ERROR; return Z_MEM_ERROR;
} }
s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->sym_buf = s->pending_buf + s->lit_bufsize;
s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3;
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
*/
s->level = level; s->level = level;
s->strategy = strategy; s->strategy = strategy;
@@ -488,13 +528,13 @@ int ZEXPORT deflateResetKeep (strm)
#ifdef GZIP #ifdef GZIP
s->wrap == 2 ? GZIP_STATE : s->wrap == 2 ? GZIP_STATE :
#endif #endif
s->wrap ? INIT_STATE : BUSY_STATE; INIT_STATE;
strm->adler = strm->adler =
#ifdef GZIP #ifdef GZIP
s->wrap == 2 ? crc32(0L, Z_NULL, 0) : s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif #endif
adler32(0L, Z_NULL, 0); adler32(0L, Z_NULL, 0);
s->last_flush = Z_NO_FLUSH; s->last_flush = -2;
_tr_init(s); _tr_init(s);
@@ -549,7 +589,8 @@ int ZEXPORT deflatePrime (strm, bits, value)
if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) if (bits < 0 || bits > 16 ||
s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR; return Z_BUF_ERROR;
do { do {
put = Buf_size - s->bi_valid; put = Buf_size - s->bi_valid;
@@ -587,12 +628,12 @@ int ZEXPORT deflateParams(strm, level, strategy)
func = configuration_table[s->level].func; func = configuration_table[s->level].func;
if ((strategy != s->strategy || func != configuration_table[level].func) && if ((strategy != s->strategy || func != configuration_table[level].func) &&
s->high_water) { s->last_flush != -2) {
/* Flush the last buffer: */ /* Flush the last buffer: */
int err = deflate(strm, Z_BLOCK); int err = deflate(strm, Z_BLOCK);
if (err == Z_STREAM_ERROR) if (err == Z_STREAM_ERROR)
return err; return err;
if (strm->avail_out == 0) if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
return Z_BUF_ERROR; return Z_BUF_ERROR;
} }
if (s->level != level) { if (s->level != level) {
@@ -811,6 +852,8 @@ int ZEXPORT deflate (strm, flush)
} }
/* Write the header */ /* Write the header */
if (s->status == INIT_STATE && s->wrap == 0)
s->status = BUSY_STATE;
if (s->status == INIT_STATE) { if (s->status == INIT_STATE) {
/* zlib header */ /* zlib header */
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
@@ -1108,7 +1151,6 @@ int ZEXPORT deflateCopy (dest, source)
#else #else
deflate_state *ds; deflate_state *ds;
deflate_state *ss; deflate_state *ss;
ushf *overlay;
if (deflateStateCheck(source) || dest == Z_NULL) { if (deflateStateCheck(source) || dest == Z_NULL) {
@@ -1128,8 +1170,7 @@ int ZEXPORT deflateCopy (dest, source)
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
ds->pending_buf = (uchf *) overlay;
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
ds->pending_buf == Z_NULL) { ds->pending_buf == Z_NULL) {
@@ -1143,8 +1184,7 @@ int ZEXPORT deflateCopy (dest, source)
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
ds->l_desc.dyn_tree = ds->dyn_ltree; ds->l_desc.dyn_tree = ds->dyn_ltree;
ds->d_desc.dyn_tree = ds->dyn_dtree; ds->d_desc.dyn_tree = ds->dyn_dtree;
@@ -1513,6 +1553,8 @@ local void fill_window(s)
s->match_start -= wsize; s->match_start -= wsize;
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
s->block_start -= (long) wsize; s->block_start -= (long) wsize;
if (s->insert > s->strstart)
s->insert = s->strstart;
slide_hash(s); slide_hash(s);
more += wsize; more += wsize;
} }
@@ -1742,6 +1784,7 @@ local block_state deflate_stored(s, flush)
s->matches = 2; /* clear hash */ s->matches = 2; /* clear hash */
zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
s->strstart = s->w_size; s->strstart = s->w_size;
s->insert = s->strstart;
} }
else { else {
if (s->window_size - s->strstart <= used) { if (s->window_size - s->strstart <= used) {
@@ -1750,12 +1793,14 @@ local block_state deflate_stored(s, flush)
zmemcpy(s->window, s->window + s->w_size, s->strstart); zmemcpy(s->window, s->window + s->w_size, s->strstart);
if (s->matches < 2) if (s->matches < 2)
s->matches++; /* add a pending slide_hash() */ s->matches++; /* add a pending slide_hash() */
if (s->insert > s->strstart)
s->insert = s->strstart;
} }
zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
s->strstart += used; s->strstart += used;
s->insert += MIN(used, s->w_size - s->insert);
} }
s->block_start = s->strstart; s->block_start = s->strstart;
s->insert += MIN(used, s->w_size - s->insert);
} }
if (s->high_water < s->strstart) if (s->high_water < s->strstart)
s->high_water = s->strstart; s->high_water = s->strstart;
@@ -1770,7 +1815,7 @@ local block_state deflate_stored(s, flush)
return block_done; return block_done;
/* Fill the window with any remaining input. */ /* Fill the window with any remaining input. */
have = s->window_size - s->strstart - 1; have = s->window_size - s->strstart;
if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
/* Slide the window down. */ /* Slide the window down. */
s->block_start -= s->w_size; s->block_start -= s->w_size;
@@ -1779,12 +1824,15 @@ local block_state deflate_stored(s, flush)
if (s->matches < 2) if (s->matches < 2)
s->matches++; /* add a pending slide_hash() */ s->matches++; /* add a pending slide_hash() */
have += s->w_size; /* more space now */ have += s->w_size; /* more space now */
if (s->insert > s->strstart)
s->insert = s->strstart;
} }
if (have > s->strm->avail_in) if (have > s->strm->avail_in)
have = s->strm->avail_in; have = s->strm->avail_in;
if (have) { if (have) {
read_buf(s->strm, s->window + s->strstart, have); read_buf(s->strm, s->window + s->strstart, have);
s->strstart += have; s->strstart += have;
s->insert += MIN(have, s->w_size - s->insert);
} }
if (s->high_water < s->strstart) if (s->high_water < s->strstart)
s->high_water = s->strstart; s->high_water = s->strstart;
@@ -1912,7 +1960,7 @@ local block_state deflate_fast(s, flush)
FLUSH_BLOCK(s, 1); FLUSH_BLOCK(s, 1);
return finish_done; return finish_done;
} }
if (s->last_lit) if (s->sym_next)
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
return block_done; return block_done;
} }
@@ -2043,7 +2091,7 @@ local block_state deflate_slow(s, flush)
FLUSH_BLOCK(s, 1); FLUSH_BLOCK(s, 1);
return finish_done; return finish_done;
} }
if (s->last_lit) if (s->sym_next)
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
return block_done; return block_done;
} }
@@ -2118,7 +2166,7 @@ local block_state deflate_rle(s, flush)
FLUSH_BLOCK(s, 1); FLUSH_BLOCK(s, 1);
return finish_done; return finish_done;
} }
if (s->last_lit) if (s->sym_next)
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
return block_done; return block_done;
} }
@@ -2157,7 +2205,7 @@ local block_state deflate_huff(s, flush)
FLUSH_BLOCK(s, 1); FLUSH_BLOCK(s, 1);
return finish_done; return finish_done;
} }
if (s->last_lit) if (s->sym_next)
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
return block_done; return block_done;
} }
+12 -15
View File
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995-2016 Jean-loup Gailly * Copyright (C) 1995-2018 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -217,7 +217,7 @@ typedef struct internal_state {
/* Depth of each subtree used as tie breaker for trees of equal frequency /* Depth of each subtree used as tie breaker for trees of equal frequency
*/ */
uchf *l_buf; /* buffer for literals or lengths */ uchf *sym_buf; /* buffer for distances and literals/lengths */
uInt lit_bufsize; uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for /* Size of match buffer for literals/lengths. There are 4 reasons for
@@ -239,13 +239,8 @@ typedef struct internal_state {
* - I can't count above 4 * - I can't count above 4
*/ */
uInt last_lit; /* running index in l_buf */ uInt sym_next; /* running index in sym_buf */
uInt sym_end; /* symbol table full when sym_next reaches this */
ushf *d_buf;
/* Buffer for distances. To simplify the code, d_buf and l_buf have
* the same number of elements. To use different lengths, an extra flag
* array would be necessary.
*/
ulg opt_len; /* bit length of current block with optimal trees */ ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */ ulg static_len; /* bit length of current block with static trees */
@@ -325,20 +320,22 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
# define _tr_tally_lit(s, c, flush) \ # define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \ { uch cc = (c); \
s->d_buf[s->last_lit] = 0; \ s->sym_buf[s->sym_next++] = 0; \
s->l_buf[s->last_lit++] = cc; \ s->sym_buf[s->sym_next++] = 0; \
s->sym_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \ s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \ flush = (s->sym_next == s->sym_end); \
} }
# define _tr_tally_dist(s, distance, length, flush) \ # define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \ { uch len = (uch)(length); \
ush dist = (ush)(distance); \ ush dist = (ush)(distance); \
s->d_buf[s->last_lit] = dist; \ s->sym_buf[s->sym_next++] = dist; \
s->l_buf[s->last_lit++] = len; \ s->sym_buf[s->sym_next++] = dist >> 8; \
s->sym_buf[s->sym_next++] = len; \
dist--; \ dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \ flush = (s->sym_next == s->sym_end); \
} }
#else #else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
Binary file not shown.
+6 -6
View File
@@ -38,15 +38,15 @@ The Algorithm
The algorithm works by dividing the set of bytecodes [0..255] into three The algorithm works by dividing the set of bytecodes [0..255] into three
categories: categories:
- The white list of textual bytecodes: - The allow list of textual bytecodes:
9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
- The gray list of tolerated bytecodes: - The gray list of tolerated bytecodes:
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
- The black list of undesired, non-textual bytecodes: - The block list of undesired, non-textual bytecodes:
0 (NUL) to 6, 14 to 31. 0 (NUL) to 6, 14 to 31.
If a file contains at least one byte that belongs to the white list and If a file contains at least one byte that belongs to the allow list and
no byte that belongs to the black list, then the file is categorized as no byte that belongs to the block list, then the file is categorized as
plain text; otherwise, it is categorized as binary. (The boundary case, plain text; otherwise, it is categorized as binary. (The boundary case,
when the file is empty, automatically falls into the latter category.) when the file is empty, automatically falls into the latter category.)
@@ -84,9 +84,9 @@ consistent results, regardless what alphabet encoding is being used.
results on a text encoded, say, using ISO-8859-16 versus UTF-8.) results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
There is an extra category of plain text files that are "polluted" with There is an extra category of plain text files that are "polluted" with
one or more black-listed codes, either by mistake or by peculiar design one or more block-listed codes, either by mistake or by peculiar design
considerations. In such cases, a scheme that tolerates a small fraction considerations. In such cases, a scheme that tolerates a small fraction
of black-listed codes would provide an increased recall (i.e. more true of block-listed codes would provide an increased recall (i.e. more true
positives). This, however, incurs a reduced precision overall, since positives). This, however, incurs a reduced precision overall, since
false positives are more likely to appear in binary files that contain false positives are more likely to appear in binary files that contain
large chunks of textual data. Furthermore, "polluted" plain text should large chunks of textual data. Furthermore, "polluted" plain text should
@@ -34,6 +34,10 @@ gzlog.h
and deflateSetDictionary() and deflateSetDictionary()
- illustrates use of a gzip header extra field - illustrates use of a gzip header extra field
gznorm.c
normalize a gzip file by combining members into a single member
- demonstrates how to concatenate deflate streams using Z_BLOCK
zlib_how.html zlib_how.html
painfully comprehensive description of zpipe.c (see below) painfully comprehensive description of zpipe.c (see below)
- describes in excruciating detail the use of deflate() and inflate() - describes in excruciating detail the use of deflate() and inflate()
@@ -44,6 +48,7 @@ zpipe.c
- deeply commented in zlib_how.html (see above) - deeply commented in zlib_how.html (see above)
zran.c zran.c
zran.h
index a zlib or gzip stream and randomly access it index a zlib or gzip stream and randomly access it
- illustrates the use of Z_BLOCK, inflatePrime(), and - illustrates the use of Z_BLOCK, inflatePrime(), and
inflateSetDictionary() to provide random access inflateSetDictionary() to provide random access
+380 -355
View File
@@ -1,7 +1,7 @@
/* enough.c -- determine the maximum size of inflate's Huffman code tables over /* enough.c -- determine the maximum size of inflate's Huffman code tables over
* all possible valid and complete Huffman codes, subject to a length limit. * all possible valid and complete prefix codes, subject to a length limit.
* Copyright (C) 2007, 2008, 2012 Mark Adler * Copyright (C) 2007, 2008, 2012, 2018 Mark Adler
* Version 1.4 18 August 2012 Mark Adler * Version 1.5 5 August 2018 Mark Adler
*/ */
/* Version history: /* Version history:
@@ -17,101 +17,107 @@
1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!) 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
Clean up comparisons of different types Clean up comparisons of different types
Clean up code indentation Clean up code indentation
1.5 5 Aug 2018 Clean up code style, formatting, and comments
Show all the codes for the maximum, and only the maximum
*/ */
/* /*
Examine all possible Huffman codes for a given number of symbols and a Examine all possible prefix codes for a given number of symbols and a
maximum code length in bits to determine the maximum table size for zilb's maximum code length in bits to determine the maximum table size for zlib's
inflate. Only complete Huffman codes are counted. inflate. Only complete prefix codes are counted.
Two codes are considered distinct if the vectors of the number of codes per Two codes are considered distinct if the vectors of the number of codes per
length are not identical. So permutations of the symbol assignments result length are not identical. So permutations of the symbol assignments result
in the same code for the counting, as do permutations of the assignments of in the same code for the counting, as do permutations of the assignments of
the bit values to the codes (i.e. only canonical codes are counted). the bit values to the codes (i.e. only canonical codes are counted).
We build a code from shorter to longer lengths, determining how many symbols We build a code from shorter to longer lengths, determining how many symbols
are coded at each length. At each step, we have how many symbols remain to are coded at each length. At each step, we have how many symbols remain to
be coded, what the last code length used was, and how many bit patterns of be coded, what the last code length used was, and how many bit patterns of
that length remain unused. Then we add one to the code length and double the that length remain unused. Then we add one to the code length and double the
number of unused patterns to graduate to the next code length. We then number of unused patterns to graduate to the next code length. We then
assign all portions of the remaining symbols to that code length that assign all portions of the remaining symbols to that code length that
preserve the properties of a correct and eventually complete code. Those preserve the properties of a correct and eventually complete code. Those
properties are: we cannot use more bit patterns than are available; and when properties are: we cannot use more bit patterns than are available; and when
all the symbols are used, there are exactly zero possible bit patterns all the symbols are used, there are exactly zero possible bit patterns left
remaining. unused.
The inflate Huffman decoding algorithm uses two-level lookup tables for The inflate Huffman decoding algorithm uses two-level lookup tables for
speed. There is a single first-level table to decode codes up to root bits speed. There is a single first-level table to decode codes up to root bits
in length (root == 9 in the current inflate implementation). The table in length (root == 9 for literal/length codes and root == 6 for distance
has 1 << root entries and is indexed by the next root bits of input. Codes codes, in the current inflate implementation). The base table has 1 << root
shorter than root bits have replicated table entries, so that the correct entries and is indexed by the next root bits of input. Codes shorter than
entry is pointed to regardless of the bits that follow the short code. If root bits have replicated table entries, so that the correct entry is
the code is longer than root bits, then the table entry points to a second- pointed to regardless of the bits that follow the short code. If the code is
level table. The size of that table is determined by the longest code with longer than root bits, then the table entry points to a second-level table.
that root-bit prefix. If that longest code has length len, then the table The size of that table is determined by the longest code with that root-bit
has size 1 << (len - root), to index the remaining bits in that set of prefix. If that longest code has length len, then the table has size 1 <<
codes. Each subsequent root-bit prefix then has its own sub-table. The (len - root), to index the remaining bits in that set of codes. Each
total number of table entries required by the code is calculated subsequent root-bit prefix then has its own sub-table. The total number of
incrementally as the number of codes at each bit length is populated. When table entries required by the code is calculated incrementally as the number
all of the codes are shorter than root bits, then root is reduced to the of codes at each bit length is populated. When all of the codes are shorter
longest code length, resulting in a single, smaller, one-level table. than root bits, then root is reduced to the longest code length, resulting
in a single, smaller, one-level table.
The inflate algorithm also provides for small values of root (relative to The inflate algorithm also provides for small values of root (relative to
the log2 of the number of symbols), where the shortest code has more bits the log2 of the number of symbols), where the shortest code has more bits
than root. In that case, root is increased to the length of the shortest than root. In that case, root is increased to the length of the shortest
code. This program, by design, does not handle that case, so it is verified code. This program, by design, does not handle that case, so it is verified
that the number of symbols is less than 2^(root + 1). that the number of symbols is less than 1 << (root + 1).
In order to speed up the examination (by about ten orders of magnitude for In order to speed up the examination (by about ten orders of magnitude for
the default arguments), the intermediate states in the build-up of a code the default arguments), the intermediate states in the build-up of a code
are remembered and previously visited branches are pruned. The memory are remembered and previously visited branches are pruned. The memory
required for this will increase rapidly with the total number of symbols and required for this will increase rapidly with the total number of symbols and
the maximum code length in bits. However this is a very small price to pay the maximum code length in bits. However this is a very small price to pay
for the vast speedup. for the vast speedup.
First, all of the possible Huffman codes are counted, and reachable First, all of the possible prefix codes are counted, and reachable
intermediate states are noted by a non-zero count in a saved-results array. intermediate states are noted by a non-zero count in a saved-results array.
Second, the intermediate states that lead to (root + 1) bit or longer codes Second, the intermediate states that lead to (root + 1) bit or longer codes
are used to look at all sub-codes from those junctures for their inflate are used to look at all sub-codes from those junctures for their inflate
memory usage. (The amount of memory used is not affected by the number of memory usage. (The amount of memory used is not affected by the number of
codes of root bits or less in length.) Third, the visited states in the codes of root bits or less in length.) Third, the visited states in the
construction of those sub-codes and the associated calculation of the table construction of those sub-codes and the associated calculation of the table
size is recalled in order to avoid recalculating from the same juncture. size is recalled in order to avoid recalculating from the same juncture.
Beginning the code examination at (root + 1) bit codes, which is enabled by Beginning the code examination at (root + 1) bit codes, which is enabled by
identifying the reachable nodes, accounts for about six of the orders of identifying the reachable nodes, accounts for about six of the orders of
magnitude of improvement for the default arguments. About another four magnitude of improvement for the default arguments. About another four
orders of magnitude come from not revisiting previous states. Out of orders of magnitude come from not revisiting previous states. Out of
approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes approximately 2x10^16 possible prefix codes, only about 2x10^6 sub-codes
need to be examined to cover all of the possible table memory usage cases need to be examined to cover all of the possible table memory usage cases
for the default arguments of 286 symbols limited to 15-bit codes. for the default arguments of 286 symbols limited to 15-bit codes.
Note that an unsigned long long type is used for counting. It is quite easy Note that the uintmax_t type is used for counting. It is quite easy to
to exceed the capacity of an eight-byte integer with a large number of exceed the capacity of an eight-byte integer with a large number of symbols
symbols and a large maximum code length, so multiple-precision arithmetic and a large maximum code length, so multiple-precision arithmetic would need
would need to replace the unsigned long long arithmetic in that case. This to replace the integer arithmetic in that case. This program will abort if
program will abort if an overflow occurs. The big_t type identifies where an overflow occurs. The big_t type identifies where the counting takes
the counting takes place. place.
An unsigned long long type is also used for calculating the number of The uintmax_t type is also used for calculating the number of possible codes
possible codes remaining at the maximum length. This limits the maximum remaining at the maximum length. This limits the maximum code length to the
code length to the number of bits in a long long minus the number of bits number of bits in a long long minus the number of bits needed to represent
needed to represent the symbols in a flat code. The code_t type identifies the symbols in a flat code. The code_t type identifies where the bit-pattern
where the bit pattern counting takes place. counting takes place.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <assert.h> #include <assert.h>
#define local static #define local static
/* special data types */ // Special data types.
typedef unsigned long long big_t; /* type for code counting */ typedef uintmax_t big_t; // type for code counting
typedef unsigned long long code_t; /* type for bit pattern counting */ #define PRIbig "ju" // printf format for big_t
struct tab { /* type for been here check */ typedef uintmax_t code_t; // type for bit pattern counting
size_t len; /* length of bit vector in char's */ struct tab { // type for been-here check
char *vec; /* allocated bit vector */ size_t len; // allocated length of bit vector in octets
char *vec; // allocated bit vector
}; };
/* The array for saving results, num[], is indexed with this triplet: /* The array for saving results, num[], is indexed with this triplet:
@@ -126,447 +132,466 @@ struct tab { /* type for been here check */
left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6) left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
len: 1..max - 1 (max == maximum code length in bits) len: 1..max - 1 (max == maximum code length in bits)
syms == 2 is not saved since that immediately leads to a single code. left syms == 2 is not saved since that immediately leads to a single code. left
must be even, since it represents the number of available bit patterns at must be even, since it represents the number of available bit patterns at
the current length, which is double the number at the previous length. the current length, which is double the number at the previous length. left
left ends at syms-1 since left == syms immediately results in a single code. ends at syms-1 since left == syms immediately results in a single code.
(left > sym is not allowed since that would result in an incomplete code.) (left > sym is not allowed since that would result in an incomplete code.)
len is less than max, since the code completes immediately when len == max. len is less than max, since the code completes immediately when len == max.
The offset into the array is calculated for the three indices with the The offset into the array is calculated for the three indices with the first
first one (syms) being outermost, and the last one (len) being innermost. one (syms) being outermost, and the last one (len) being innermost. We build
We build the array with length max-1 lists for the len index, with syms-3 the array with length max-1 lists for the len index, with syms-3 of those
of those for each symbol. There are totsym-2 of those, with each one for each symbol. There are totsym-2 of those, with each one varying in
varying in length as a function of sym. See the calculation of index in length as a function of sym. See the calculation of index in map() for the
count() for the index, and the calculation of size in main() for the size index, and the calculation of size in main() for the size of the array.
of the array.
For the deflate example of 286 symbols limited to 15-bit codes, the array For the deflate example of 286 symbols limited to 15-bit codes, the array
has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than half
half of the space allocated for saved results is actually used -- not all of the space allocated for saved results is actually used -- not all
possible triplets are reached in the generation of valid Huffman codes. possible triplets are reached in the generation of valid prefix codes.
*/ */
/* The array for tracking visited states, done[], is itself indexed identically /* The array for tracking visited states, done[], is itself indexed identically
to the num[] array as described above for the (syms, left, len) triplet. to the num[] array as described above for the (syms, left, len) triplet.
Each element in the array is further indexed by the (mem, rem) doublet, Each element in the array is further indexed by the (mem, rem) doublet,
where mem is the amount of inflate table space used so far, and rem is the where mem is the amount of inflate table space used so far, and rem is the
remaining unused entries in the current inflate sub-table. Each indexed remaining unused entries in the current inflate sub-table. Each indexed
element is simply one bit indicating whether the state has been visited or element is simply one bit indicating whether the state has been visited or
not. Since the ranges for mem and rem are not known a priori, each bit not. Since the ranges for mem and rem are not known a priori, each bit
vector is of a variable size, and grows as needed to accommodate the visited vector is of a variable size, and grows as needed to accommodate the visited
states. mem and rem are used to calculate a single index in a triangular states. mem and rem are used to calculate a single index in a triangular
array. Since the range of mem is expected in the default case to be about array. Since the range of mem is expected in the default case to be about
ten times larger than the range of rem, the array is skewed to reduce the ten times larger than the range of rem, the array is skewed to reduce the
memory usage, with eight times the range for mem than for rem. See the memory usage, with eight times the range for mem than for rem. See the
calculations for offset and bit in beenhere() for the details. calculations for offset and bit in been_here() for the details.
For the deflate example of 286 symbols limited to 15-bit codes, the bit For the deflate example of 286 symbols limited to 15-bit codes, the bit
vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[] vectors grow to total 5.5 MB, in addition to the 4.3 MB done array itself.
array itself.
*/ */
/* Globals to avoid propagating constants or constant pointers recursively */ // Type for a variable-length, allocated string.
local int max; /* maximum allowed bit length for the codes */ typedef struct {
local int root; /* size of base code table in bits */ char *str; // pointer to allocated string
local int large; /* largest code table so far */ size_t size; // size of allocation
local size_t size; /* number of elements in num and done */ size_t len; // length of string, not including terminating zero
local int *code; /* number of symbols assigned to each bit length */ } string_t;
local big_t *num; /* saved results array for code counting */
local struct tab *done; /* states already evaluated array */
/* Index function for num[] and done[] */ // Clear a string_t.
#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1) local void string_clear(string_t *s) {
s->str[0] = 0;
/* Free allocated space. Uses globals code, num, and done. */ s->len = 0;
local void cleanup(void)
{
size_t n;
if (done != NULL) {
for (n = 0; n < size; n++)
if (done[n].len)
free(done[n].vec);
free(done);
}
if (num != NULL)
free(num);
if (code != NULL)
free(code);
} }
/* Return the number of possible Huffman codes using bit patterns of lengths // Initialize a string_t.
len through max inclusive, coding syms symbols, with left bit patterns of local void string_init(string_t *s) {
length len unused -- return -1 if there is an overflow in the counting. s->size = 16;
Keep a record of previous results in num to prevent repeating the same s->str = malloc(s->size);
calculation. Uses the globals max and num. */ assert(s->str != NULL && "out of memory");
local big_t count(int syms, int len, int left) string_clear(s);
{ }
big_t sum; /* number of possible codes from this juncture */
big_t got; /* value returned from count() */
int least; /* least number of syms to use at this juncture */
int most; /* most number of syms to use at this juncture */
int use; /* number of bit patterns to use in next call */
size_t index; /* index of this case in *num */
/* see if only one possible code */ // Release the allocation of a string_t.
local void string_free(string_t *s) {
free(s->str);
s->str = NULL;
s->size = 0;
s->len = 0;
}
// Save the results of printf with fmt and the subsequent argument list to s.
// Each call appends to s. The allocated space for s is increased as needed.
local void string_printf(string_t *s, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
size_t len = s->len;
int ret = vsnprintf(s->str + len, s->size - len, fmt, ap);
assert(ret >= 0 && "out of memory");
s->len += ret;
if (s->size < s->len + 1) {
do {
s->size <<= 1;
assert(s->size != 0 && "overflow");
} while (s->size < s->len + 1);
s->str = realloc(s->str, s->size);
assert(s->str != NULL && "out of memory");
vsnprintf(s->str + len, s->size - len, fmt, ap);
}
va_end(ap);
}
// Globals to avoid propagating constants or constant pointers recursively.
struct {
int max; // maximum allowed bit length for the codes
int root; // size of base code table in bits
int large; // largest code table so far
size_t size; // number of elements in num and done
big_t tot; // total number of codes with maximum tables size
string_t out; // display of subcodes for maximum tables size
int *code; // number of symbols assigned to each bit length
big_t *num; // saved results array for code counting
struct tab *done; // states already evaluated array
} g;
// Index function for num[] and done[].
local inline size_t map(int syms, int left, int len) {
return ((size_t)((syms - 1) >> 1) * ((syms - 2) >> 1) +
(left >> 1) - 1) * (g.max - 1) +
len - 1;
}
// Free allocated space in globals.
local void cleanup(void) {
if (g.done != NULL) {
for (size_t n = 0; n < g.size; n++)
if (g.done[n].len)
free(g.done[n].vec);
g.size = 0;
free(g.done); g.done = NULL;
}
free(g.num); g.num = NULL;
free(g.code); g.code = NULL;
string_free(&g.out);
}
// Return the number of possible prefix codes using bit patterns of lengths len
// through max inclusive, coding syms symbols, with left bit patterns of length
// len unused -- return -1 if there is an overflow in the counting. Keep a
// record of previous results in num to prevent repeating the same calculation.
local big_t count(int syms, int left, int len) {
// see if only one possible code
if (syms == left) if (syms == left)
return 1; return 1;
/* note and verify the expected state */ // note and verify the expected state
assert(syms > left && left > 0 && len < max); assert(syms > left && left > 0 && len < g.max);
/* see if we've done this one already */ // see if we've done this one already
index = INDEX(syms, left, len); size_t index = map(syms, left, len);
got = num[index]; big_t got = g.num[index];
if (got) if (got)
return got; /* we have -- return the saved result */ return got; // we have -- return the saved result
/* we need to use at least this many bit patterns so that the code won't be // we need to use at least this many bit patterns so that the code won't be
incomplete at the next length (more bit patterns than symbols) */ // incomplete at the next length (more bit patterns than symbols)
least = (left << 1) - syms; int least = (left << 1) - syms;
if (least < 0) if (least < 0)
least = 0; least = 0;
/* we can use at most this many bit patterns, lest there not be enough // we can use at most this many bit patterns, lest there not be enough
available for the remaining symbols at the maximum length (if there were // available for the remaining symbols at the maximum length (if there were
no limit to the code length, this would become: most = left - 1) */ // no limit to the code length, this would become: most = left - 1)
most = (((code_t)left << (max - len)) - syms) / int most = (((code_t)left << (g.max - len)) - syms) /
(((code_t)1 << (max - len)) - 1); (((code_t)1 << (g.max - len)) - 1);
/* count all possible codes from this juncture and add them up */ // count all possible codes from this juncture and add them up
sum = 0; big_t sum = 0;
for (use = least; use <= most; use++) { for (int use = least; use <= most; use++) {
got = count(syms - use, len + 1, (left - use) << 1); got = count(syms - use, (left - use) << 1, len + 1);
sum += got; sum += got;
if (got == (big_t)0 - 1 || sum < got) /* overflow */ if (got == (big_t)-1 || sum < got) // overflow
return (big_t)0 - 1; return (big_t)-1;
} }
/* verify that all recursive calls are productive */ // verify that all recursive calls are productive
assert(sum != 0); assert(sum != 0);
/* save the result and return it */ // save the result and return it
num[index] = sum; g.num[index] = sum;
return sum; return sum;
} }
/* Return true if we've been here before, set to true if not. Set a bit in a // Return true if we've been here before, set to true if not. Set a bit in a
bit vector to indicate visiting this state. Each (syms,len,left) state // bit vector to indicate visiting this state. Each (syms,len,left) state has a
has a variable size bit vector indexed by (mem,rem). The bit vector is // variable size bit vector indexed by (mem,rem). The bit vector is lengthened
lengthened if needed to allow setting the (mem,rem) bit. */ // as needed to allow setting the (mem,rem) bit.
local int beenhere(int syms, int len, int left, int mem, int rem) local int been_here(int syms, int left, int len, int mem, int rem) {
{ // point to vector for (syms,left,len), bit in vector for (mem,rem)
size_t index; /* index for this state's bit vector */ size_t index = map(syms, left, len);
size_t offset; /* offset in this state's bit vector */ mem -= 1 << g.root; // mem always includes the root table
int bit; /* mask for this state's bit */ mem >>= 1; // mem and rem are always even
size_t length; /* length of the bit vector in bytes */ rem >>= 1;
char *vector; /* new or enlarged bit vector */ size_t offset = (mem >> 3) + rem;
/* point to vector for (syms,left,len), bit in vector for (mem,rem) */
index = INDEX(syms, left, len);
mem -= 1 << root;
offset = (mem >> 3) + rem;
offset = ((offset * (offset + 1)) >> 1) + rem; offset = ((offset * (offset + 1)) >> 1) + rem;
bit = 1 << (mem & 7); int bit = 1 << (mem & 7);
/* see if we've been here */ // see if we've been here
length = done[index].len; size_t length = g.done[index].len;
if (offset < length && (done[index].vec[offset] & bit) != 0) if (offset < length && (g.done[index].vec[offset] & bit) != 0)
return 1; /* done this! */ return 1; // done this!
/* we haven't been here before -- set the bit to show we have now */ // we haven't been here before -- set the bit to show we have now
/* see if we need to lengthen the vector in order to set the bit */ // see if we need to lengthen the vector in order to set the bit
if (length <= offset) { if (length <= offset) {
/* if we have one already, enlarge it, zero out the appended space */ // if we have one already, enlarge it, zero out the appended space
char *vector;
if (length) { if (length) {
do { do {
length <<= 1; length <<= 1;
} while (length <= offset); } while (length <= offset);
vector = realloc(done[index].vec, length); vector = realloc(g.done[index].vec, length);
if (vector != NULL) assert(vector != NULL && "out of memory");
memset(vector + done[index].len, 0, length - done[index].len); memset(vector + g.done[index].len, 0, length - g.done[index].len);
} }
/* otherwise we need to make a new vector and zero it out */ // otherwise we need to make a new vector and zero it out
else { else {
length = 1 << (len - root); length = 16;
while (length <= offset) while (length <= offset)
length <<= 1; length <<= 1;
vector = calloc(length, sizeof(char)); vector = calloc(length, 1);
assert(vector != NULL && "out of memory");
} }
/* in either case, bail if we can't get the memory */ // install the new vector
if (vector == NULL) { g.done[index].len = length;
fputs("abort: unable to allocate enough memory\n", stderr); g.done[index].vec = vector;
cleanup();
exit(1);
}
/* install the new vector */
done[index].len = length;
done[index].vec = vector;
} }
/* set the bit */ // set the bit
done[index].vec[offset] |= bit; g.done[index].vec[offset] |= bit;
return 0; return 0;
} }
/* Examine all possible codes from the given node (syms, len, left). Compute // Examine all possible codes from the given node (syms, len, left). Compute
the amount of memory required to build inflate's decoding tables, where the // the amount of memory required to build inflate's decoding tables, where the
number of code structures used so far is mem, and the number remaining in // number of code structures used so far is mem, and the number remaining in
the current sub-table is rem. Uses the globals max, code, root, large, and // the current sub-table is rem.
done. */ local void examine(int syms, int left, int len, int mem, int rem) {
local void examine(int syms, int len, int left, int mem, int rem) // see if we have a complete code
{
int least; /* least number of syms to use at this juncture */
int most; /* most number of syms to use at this juncture */
int use; /* number of bit patterns to use in next call */
/* see if we have a complete code */
if (syms == left) { if (syms == left) {
/* set the last code entry */ // set the last code entry
code[len] = left; g.code[len] = left;
/* complete computation of memory used by this code */ // complete computation of memory used by this code
while (rem < left) { while (rem < left) {
left -= rem; left -= rem;
rem = 1 << (len - root); rem = 1 << (len - g.root);
mem += rem; mem += rem;
} }
assert(rem == left); assert(rem == left);
/* if this is a new maximum, show the entries used and the sub-code */ // if this is at the maximum, show the sub-code
if (mem > large) { if (mem >= g.large) {
large = mem; // if this is a new maximum, update the maximum and clear out the
printf("max %d: ", mem); // printed sub-codes from the previous maximum
for (use = root + 1; use <= max; use++) if (mem > g.large) {
if (code[use]) g.large = mem;
printf("%d[%d] ", code[use], use); string_clear(&g.out);
putchar('\n'); }
fflush(stdout);
// compute the starting state for this sub-code
syms = 0;
left = 1 << g.max;
for (int bits = g.max; bits > g.root; bits--) {
syms += g.code[bits];
left -= g.code[bits];
assert((left & 1) == 0);
left >>= 1;
}
// print the starting state and the resulting sub-code to g.out
string_printf(&g.out, "<%u, %u, %u>:",
syms, g.root + 1, ((1 << g.root) - left) << 1);
for (int bits = g.root + 1; bits <= g.max; bits++)
if (g.code[bits])
string_printf(&g.out, " %d[%d]", g.code[bits], bits);
string_printf(&g.out, "\n");
} }
/* remove entries as we drop back down in the recursion */ // remove entries as we drop back down in the recursion
code[len] = 0; g.code[len] = 0;
return; return;
} }
/* prune the tree if we can */ // prune the tree if we can
if (beenhere(syms, len, left, mem, rem)) if (been_here(syms, left, len, mem, rem))
return; return;
/* we need to use at least this many bit patterns so that the code won't be // we need to use at least this many bit patterns so that the code won't be
incomplete at the next length (more bit patterns than symbols) */ // incomplete at the next length (more bit patterns than symbols)
least = (left << 1) - syms; int least = (left << 1) - syms;
if (least < 0) if (least < 0)
least = 0; least = 0;
/* we can use at most this many bit patterns, lest there not be enough // we can use at most this many bit patterns, lest there not be enough
available for the remaining symbols at the maximum length (if there were // available for the remaining symbols at the maximum length (if there were
no limit to the code length, this would become: most = left - 1) */ // no limit to the code length, this would become: most = left - 1)
most = (((code_t)left << (max - len)) - syms) / int most = (((code_t)left << (g.max - len)) - syms) /
(((code_t)1 << (max - len)) - 1); (((code_t)1 << (g.max - len)) - 1);
/* occupy least table spaces, creating new sub-tables as needed */ // occupy least table spaces, creating new sub-tables as needed
use = least; int use = least;
while (rem < use) { while (rem < use) {
use -= rem; use -= rem;
rem = 1 << (len - root); rem = 1 << (len - g.root);
mem += rem; mem += rem;
} }
rem -= use; rem -= use;
/* examine codes from here, updating table space as we go */ // examine codes from here, updating table space as we go
for (use = least; use <= most; use++) { for (use = least; use <= most; use++) {
code[len] = use; g.code[len] = use;
examine(syms - use, len + 1, (left - use) << 1, examine(syms - use, (left - use) << 1, len + 1,
mem + (rem ? 1 << (len - root) : 0), rem << 1); mem + (rem ? 1 << (len - g.root) : 0), rem << 1);
if (rem == 0) { if (rem == 0) {
rem = 1 << (len - root); rem = 1 << (len - g.root);
mem += rem; mem += rem;
} }
rem--; rem--;
} }
/* remove entries as we drop back down in the recursion */ // remove entries as we drop back down in the recursion
code[len] = 0; g.code[len] = 0;
} }
/* Look at all sub-codes starting with root + 1 bits. Look at only the valid // Look at all sub-codes starting with root + 1 bits. Look at only the valid
intermediate code states (syms, left, len). For each completed code, // intermediate code states (syms, left, len). For each completed code,
calculate the amount of memory required by inflate to build the decoding // calculate the amount of memory required by inflate to build the decoding
tables. Find the maximum amount of memory required and show the code that // tables. Find the maximum amount of memory required and show the codes that
requires that maximum. Uses the globals max, root, and num. */ // require that maximum.
local void enough(int syms) local void enough(int syms) {
{ // clear code
int n; /* number of remaing symbols for this node */ for (int n = 0; n <= g.max; n++)
int left; /* number of unused bit patterns at this length */ g.code[n] = 0;
size_t index; /* index of this case in *num */
/* clear code */ // look at all (root + 1) bit and longer codes
for (n = 0; n <= max; n++) string_clear(&g.out); // empty saved results
code[n] = 0; g.large = 1 << g.root; // base table
if (g.root < g.max) // otherwise, there's only a base table
for (int n = 3; n <= syms; n++)
for (int left = 2; left < n; left += 2) {
// look at all reachable (root + 1) bit nodes, and the
// resulting codes (complete at root + 2 or more)
size_t index = map(n, left, g.root + 1);
if (g.root + 1 < g.max && g.num[index]) // reachable node
examine(n, left, g.root + 1, 1 << g.root, 0);
/* look at all (root + 1) bit and longer codes */ // also look at root bit codes with completions at root + 1
large = 1 << root; /* base table */ // bits (not saved in num, since complete), just in case
if (root < max) /* otherwise, there's only a base table */ if (g.num[index - 1] && n <= left << 1)
for (n = 3; n <= syms; n++) examine((n - left) << 1, (n - left) << 1, g.root + 1,
for (left = 2; left < n; left += 2) 1 << g.root, 0);
{
/* look at all reachable (root + 1) bit nodes, and the
resulting codes (complete at root + 2 or more) */
index = INDEX(n, left, root + 1);
if (root + 1 < max && num[index]) /* reachable node */
examine(n, root + 1, left, 1 << root, 0);
/* also look at root bit codes with completions at root + 1
bits (not saved in num, since complete), just in case */
if (num[index - 1] && n <= left << 1)
examine((n - left) << 1, root + 1, (n - left) << 1,
1 << root, 0);
} }
/* done */ // done
printf("done: maximum of %d table entries\n", large); printf("maximum of %d table entries for root = %d\n", g.large, g.root);
fputs(g.out.str, stdout);
} }
/* // Examine and show the total number of possible prefix codes for a given
Examine and show the total number of possible Huffman codes for a given // maximum number of symbols, initial root table size, and maximum code length
maximum number of symbols, initial root table size, and maximum code length // in bits -- those are the command arguments in that order. The default values
in bits -- those are the command arguments in that order. The default // are 286, 9, and 15 respectively, for the deflate literal/length code. The
values are 286, 9, and 15 respectively, for the deflate literal/length code. // possible codes are counted for each number of coded symbols from two to the
The possible codes are counted for each number of coded symbols from two to // maximum. The counts for each of those and the total number of codes are
the maximum. The counts for each of those and the total number of codes are // shown. The maximum number of inflate table entires is then calculated across
shown. The maximum number of inflate table entires is then calculated // all possible codes. Each new maximum number of table entries and the
across all possible codes. Each new maximum number of table entries and the // associated sub-code (starting at root + 1 == 10 bits) is shown.
associated sub-code (starting at root + 1 == 10 bits) is shown. //
// To count and examine prefix codes that are not length-limited, provide a
// maximum length equal to the number of symbols minus one.
//
// For the deflate literal/length code, use "enough". For the deflate distance
// code, use "enough 30 6".
int main(int argc, char **argv) {
// set up globals for cleanup()
g.code = NULL;
g.num = NULL;
g.done = NULL;
string_init(&g.out);
To count and examine Huffman codes that are not length-limited, provide a // get arguments -- default to the deflate literal/length code
maximum length equal to the number of symbols minus one. int syms = 286;
g.root = 9;
For the deflate literal/length code, use "enough". For the deflate distance g.max = 15;
code, use "enough 30 6".
This uses the %llu printf format to print big_t numbers, which assumes that
big_t is an unsigned long long. If the big_t type is changed (for example
to a multiple precision type), the method of printing will also need to be
updated.
*/
int main(int argc, char **argv)
{
int syms; /* total number of symbols to code */
int n; /* number of symbols to code for this run */
big_t got; /* return value of count() */
big_t sum; /* accumulated number of codes over n */
code_t word; /* for counting bits in code_t */
/* set up globals for cleanup() */
code = NULL;
num = NULL;
done = NULL;
/* get arguments -- default to the deflate literal/length code */
syms = 286;
root = 9;
max = 15;
if (argc > 1) { if (argc > 1) {
syms = atoi(argv[1]); syms = atoi(argv[1]);
if (argc > 2) { if (argc > 2) {
root = atoi(argv[2]); g.root = atoi(argv[2]);
if (argc > 3) if (argc > 3)
max = atoi(argv[3]); g.max = atoi(argv[3]);
} }
} }
if (argc > 4 || syms < 2 || root < 1 || max < 1) { if (argc > 4 || syms < 2 || g.root < 1 || g.max < 1) {
fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
stderr); stderr);
return 1; return 1;
} }
/* if not restricting the code length, the longest is syms - 1 */ // if not restricting the code length, the longest is syms - 1
if (max > syms - 1) if (g.max > syms - 1)
max = syms - 1; g.max = syms - 1;
/* determine the number of bits in a code_t */ // determine the number of bits in a code_t
for (n = 0, word = 1; word; n++, word <<= 1) int bits = 0;
; for (code_t word = 1; word; word <<= 1)
bits++;
/* make sure that the calculation of most will not overflow */ // make sure that the calculation of most will not overflow
if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) { if (g.max > bits || (code_t)(syms - 2) >= ((code_t)-1 >> (g.max - 1))) {
fputs("abort: code length too long for internal types\n", stderr); fputs("abort: code length too long for internal types\n", stderr);
return 1; return 1;
} }
/* reject impossible code requests */ // reject impossible code requests
if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) { if ((code_t)(syms - 1) > ((code_t)1 << g.max) - 1) {
fprintf(stderr, "%d symbols cannot be coded in %d bits\n", fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
syms, max); syms, g.max);
return 1; return 1;
} }
/* allocate code vector */ // allocate code vector
code = calloc(max + 1, sizeof(int)); g.code = calloc(g.max + 1, sizeof(int));
if (code == NULL) { assert(g.code != NULL && "out of memory");
fputs("abort: unable to allocate enough memory\n", stderr);
return 1;
}
/* determine size of saved results array, checking for overflows, // determine size of saved results array, checking for overflows,
allocate and clear the array (set all to zero with calloc()) */ // allocate and clear the array (set all to zero with calloc())
if (syms == 2) /* iff max == 1 */ if (syms == 2) // iff max == 1
num = NULL; /* won't be saving any results */ g.num = NULL; // won't be saving any results
else { else {
size = syms >> 1; g.size = syms >> 1;
if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) || int n = (syms - 1) >> 1;
(size *= n, size > ((size_t)0 - 1) / (n = max - 1)) || assert(g.size <= (size_t)-1 / n && "overflow");
(size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) || g.size *= n;
(num = calloc(size, sizeof(big_t))) == NULL) { n = g.max - 1;
fputs("abort: unable to allocate enough memory\n", stderr); assert(g.size <= (size_t)-1 / n && "overflow");
cleanup(); g.size *= n;
return 1; g.num = calloc(g.size, sizeof(big_t));
} assert(g.num != NULL && "out of memory");
} }
/* count possible codes for all numbers of symbols, add up counts */ // count possible codes for all numbers of symbols, add up counts
sum = 0; big_t sum = 0;
for (n = 2; n <= syms; n++) { for (int n = 2; n <= syms; n++) {
got = count(n, 1, 2); big_t got = count(n, 2, 1);
sum += got; sum += got;
if (got == (big_t)0 - 1 || sum < got) { /* overflow */ assert(got != (big_t)-1 && sum >= got && "overflow");
fputs("abort: can't count that high!\n", stderr);
cleanup();
return 1;
}
printf("%llu %d-codes\n", got, n);
} }
printf("%llu total codes for 2 to %d symbols", sum, syms); printf("%"PRIbig" total codes for 2 to %d symbols", sum, syms);
if (max < syms - 1) if (g.max < syms - 1)
printf(" (%d-bit length limit)\n", max); printf(" (%d-bit length limit)\n", g.max);
else else
puts(" (no length limit)"); puts(" (no length limit)");
/* allocate and clear done array for beenhere() */ // allocate and clear done array for been_here()
if (syms == 2) if (syms == 2)
done = NULL; g.done = NULL;
else if (size > ((size_t)0 - 1) / sizeof(struct tab) || else {
(done = calloc(size, sizeof(struct tab))) == NULL) { g.done = calloc(g.size, sizeof(struct tab));
fputs("abort: unable to allocate enough memory\n", stderr); assert(g.done != NULL && "out of memory");
cleanup();
return 1;
} }
/* find and show maximum inflate table usage */ // find and show maximum inflate table usage
if (root > max) /* reduce root to max length */ if (g.root > g.max) // reduce root to max length
root = max; g.root = g.max;
if ((code_t)syms < ((code_t)1 << (root + 1))) if ((code_t)syms < ((code_t)1 << (g.root + 1)))
enough(syms); enough(syms);
else else
puts("cannot handle minimum code lengths > root"); fputs("cannot handle minimum code lengths > root", stderr);
/* done */ // done
cleanup(); cleanup();
return 0; return 0;
} }
+1 -1
View File
@@ -137,7 +137,7 @@ local void rotate(unsigned char *list, unsigned len, unsigned rot)
/* do simple left shift by one */ /* do simple left shift by one */
if (rot == 1) { if (rot == 1) {
tmp = *list; tmp = *list;
memcpy(list, list + 1, len - 1); memmove(list, list + 1, len - 1);
*last = tmp; *last = tmp;
return; return;
} }
+4 -2
View File
@@ -1,8 +1,8 @@
/* /*
* gzlog.c * gzlog.c
* Copyright (C) 2004, 2008, 2012, 2016 Mark Adler, all rights reserved * Copyright (C) 2004, 2008, 2012, 2016, 2019 Mark Adler, all rights reserved
* For conditions of distribution and use, see copyright notice in gzlog.h * For conditions of distribution and use, see copyright notice in gzlog.h
* version 2.2, 14 Aug 2012 * version 2.3, 25 May 2019
*/ */
/* /*
@@ -756,12 +756,14 @@ local int log_recover(struct log *log, int op)
return -2; return -2;
} }
if ((fd = open(log->path, O_RDONLY, 0)) < 0) { if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
free(data);
log_log(log, op, ".add file read failure"); log_log(log, op, ".add file read failure");
return -1; return -1;
} }
ret = (size_t)read(fd, data, len) != len; ret = (size_t)read(fd, data, len) != len;
close(fd); close(fd);
if (ret) { if (ret) {
free(data);
log_log(log, op, ".add file read failure"); log_log(log, op, ".add file read failure");
return -1; return -1;
} }
+470
View File
@@ -0,0 +1,470 @@
/* gznorm.c -- normalize a gzip stream
* Copyright (C) 2018 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
* Version 1.0 7 Oct 2018 Mark Adler */
// gznorm takes a gzip stream, potentially containing multiple members, and
// converts it to a gzip stream with a single member. In addition the gzip
// header is normalized, removing the file name and time stamp, and setting the
// other header contents (XFL, OS) to fixed values. gznorm does not recompress
// the data, so it is fast, but no advantage is gained from the history that
// could be available across member boundaries.
#include <stdio.h> // fread, fwrite, putc, fflush, ferror, fprintf,
// vsnprintf, stdout, stderr, NULL, FILE
#include <stdlib.h> // malloc, free
#include <string.h> // strerror
#include <errno.h> // errno
#include <stdarg.h> // va_list, va_start, va_end
#include "zlib.h" // inflateInit2, inflate, inflateReset, inflateEnd,
// z_stream, z_off_t, crc32_combine, Z_NULL, Z_BLOCK,
// Z_OK, Z_STREAM_END, Z_BUF_ERROR, Z_DATA_ERROR,
// Z_MEM_ERROR
#if defined(MSDOS) || defined(OS2) || 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
#define local static
// printf to an allocated string. Return the string, or NULL if the printf or
// allocation fails.
local char *aprintf(char *fmt, ...) {
// Get the length of the result of the printf.
va_list args;
va_start(args, fmt);
int len = vsnprintf(NULL, 0, fmt, args);
va_end(args);
if (len < 0)
return NULL;
// Allocate the required space and printf to it.
char *str = malloc(len + 1);
if (str == NULL)
return NULL;
va_start(args, fmt);
vsnprintf(str, len + 1, fmt, args);
va_end(args);
return str;
}
// Return with an error, putting an allocated error message in *err. Doing an
// inflateEnd() on an already ended state, or one with state set to Z_NULL, is
// permitted.
#define BYE(...) \
do { \
inflateEnd(&strm); \
*err = aprintf(__VA_ARGS__); \
return 1; \
} while (0)
// Chunk size for buffered reads and for decompression. Twice this many bytes
// will be allocated on the stack by gzip_normalize(). Must fit in an unsigned.
#define CHUNK 16384
// Read a gzip stream from in and write an equivalent normalized gzip stream to
// out. If given no input, an empty gzip stream will be written. If successful,
// 0 is returned, and *err is set to NULL. On error, 1 is returned, where the
// details of the error are returned in *err, a pointer to an allocated string.
//
// The input may be a stream with multiple gzip members, which is converted to
// a single gzip member on the output. Each gzip member is decompressed at the
// level of deflate blocks. This enables clearing the last-block bit, shifting
// the compressed data to concatenate to the previous member's compressed data,
// which can end at an arbitrary bit boundary, and identifying stored blocks in
// order to resynchronize those to byte boundaries. The deflate compressed data
// is terminated with a 10-bit empty fixed block. If any members on the input
// end with a 10-bit empty fixed block, then that block is excised from the
// stream. This avoids appending empty fixed blocks for every normalization,
// and assures that gzip_normalize applied a second time will not change the
// input. The pad bits after stored block headers and after the final deflate
// block are all forced to zeros.
local int gzip_normalize(FILE *in, FILE *out, char **err) {
// initialize the inflate engine to process a gzip member
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if (inflateInit2(&strm, 15 + 16) != Z_OK)
BYE("out of memory");
// State while processing the input gzip stream.
enum { // BETWEEN -> HEAD -> BLOCK -> TAIL -> BETWEEN -> ...
BETWEEN, // between gzip members (must end in this state)
HEAD, // reading a gzip header
BLOCK, // reading deflate blocks
TAIL // reading a gzip trailer
} state = BETWEEN; // current component being processed
unsigned long crc = 0; // accumulated CRC of uncompressed data
unsigned long len = 0; // accumulated length of uncompressed data
unsigned long buf = 0; // deflate stream bit buffer of num bits
int num = 0; // number of bits in buf (at bottom)
// Write a canonical gzip header (no mod time, file name, comment, extra
// block, or extra flags, and OS is marked as unknown).
fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
// Process the gzip stream from in until reaching the end of the input,
// encountering invalid input, or experiencing an i/o error.
int more; // true if not at the end of the input
do {
// State inside this loop.
unsigned char *put; // next input buffer location to process
int prev; // number of bits from previous block in
// the bit buffer, or -1 if not at the
// start of a block
unsigned long long memb; // uncompressed length of member
size_t tail; // number of trailer bytes read (0..8)
unsigned long part; // accumulated trailer component
// Get the next chunk of input from in.
unsigned char dat[CHUNK];
strm.avail_in = fread(dat, 1, CHUNK, in);
if (strm.avail_in == 0)
break;
more = strm.avail_in == CHUNK;
strm.next_in = put = dat;
// Run that chunk of input through the inflate engine to exhaustion.
do {
// At this point it is assured that strm.avail_in > 0.
// Inflate until the end of a gzip component (header, deflate
// block, trailer) is reached, or until all of the chunk is
// consumed. The resulting decompressed data is discarded, though
// the total size of the decompressed data in each member is
// tracked, for the calculation of the total CRC.
do {
// inflate and handle any errors
unsigned char scrap[CHUNK];
strm.avail_out = CHUNK;
strm.next_out = scrap;
int ret = inflate(&strm, Z_BLOCK);
if (ret == Z_MEM_ERROR)
BYE("out of memory");
if (ret == Z_DATA_ERROR)
BYE("input invalid: %s", strm.msg);
if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END)
BYE("internal error");
// Update the number of uncompressed bytes generated in this
// member. The actual count (not modulo 2^32) is required to
// correctly compute the total CRC.
unsigned got = CHUNK - strm.avail_out;
memb += got;
if (memb < got)
BYE("overflow error");
// Continue to process this chunk until it is consumed, or
// until the end of a component (header, deflate block, or
// trailer) is reached.
} while (strm.avail_out == 0 && (strm.data_type & 0x80) == 0);
// Since strm.avail_in was > 0 for the inflate call, some input was
// just consumed. It is therefore assured that put < strm.next_in.
// Disposition the consumed component or part of a component.
switch (state) {
case BETWEEN:
state = HEAD;
// Fall through to HEAD when some or all of the header is
// processed.
case HEAD:
// Discard the header.
if (strm.data_type & 0x80) {
// End of header reached -- deflate blocks follow.
put = strm.next_in;
prev = num;
memb = 0;
state = BLOCK;
}
break;
case BLOCK:
// Copy the deflate stream to the output, but with the
// last-block-bit cleared. Re-synchronize stored block
// headers to the output byte boundaries. The bytes at
// put..strm.next_in-1 is the compressed data that has been
// processed and is ready to be copied to the output.
// At this point, it is assured that new compressed data is
// available, i.e., put < strm.next_in. If prev is -1, then
// that compressed data starts in the middle of a deflate
// block. If prev is not -1, then the bits in the bit
// buffer, possibly combined with the bits in *put, contain
// the three-bit header of the new deflate block. In that
// case, prev is the number of bits from the previous block
// that remain in the bit buffer. Since num is the number
// of bits in the bit buffer, we have that num - prev is
// the number of bits from the new block currently in the
// bit buffer.
// If strm.data_type & 0xc0 is 0x80, then the last byte of
// the available compressed data includes the last bits of
// the end of a deflate block. In that case, that last byte
// also has strm.data_type & 0x1f bits of the next deflate
// block, in the range 0..7. If strm.data_type & 0xc0 is
// 0xc0, then the last byte of the compressed data is the
// end of the deflate stream, followed by strm.data_type &
// 0x1f pad bits, also in the range 0..7.
// Set bits to the number of bits not yet consumed from the
// last byte. If we are at the end of the block, bits is
// either the number of bits in the last byte belonging to
// the next block, or the number of pad bits after the
// final block. In either of those cases, bits is in the
// range 0..7.
; // (required due to C syntax oddity)
int bits = strm.data_type & 0x1f;
if (prev != -1) {
// We are at the start of a new block. Clear the last
// block bit, and check for special cases. If it is a
// stored block, then emit the header and pad to the
// next byte boundary. If it is a final, empty fixed
// block, then excise it.
// Some or all of the three header bits for this block
// may already be in the bit buffer. Load any remaining
// header bits into the bit buffer.
if (num - prev < 3) {
buf += (unsigned long)*put++ << num;
num += 8;
}
// Set last to have a 1 in the position of the last
// block bit in the bit buffer.
unsigned long last = (unsigned long)1 << prev;
if (((buf >> prev) & 7) == 3) {
// This is a final fixed block. Load at least ten
// bits from this block, including the header, into
// the bit buffer. We already have at least three,
// so at most one more byte needs to be loaded.
if (num - prev < 10) {
if (put == strm.next_in)
// Need to go get and process more input.
// We'll end up back here to finish this.
break;
buf += (unsigned long)*put++ << num;
num += 8;
}
if (((buf >> prev) & 0x3ff) == 3) {
// That final fixed block is empty. Delete it
// to avoid adding an empty block every time a
// gzip stream is normalized.
num = prev;
buf &= last - 1; // zero the pad bits
}
}
else if (((buf >> prev) & 6) == 0) {
// This is a stored block. Flush to the next
// byte boundary after the three-bit header.
num = (prev + 10) & ~7;
buf &= last - 1; // zero the pad bits
}
// Clear the last block bit.
buf &= ~last;
// Write out complete bytes in the bit buffer.
while (num >= 8) {
putc(buf, out);
buf >>= 8;
num -= 8;
}
// If no more bytes left to process, then we have
// consumed the byte that had bits from the next block.
if (put == strm.next_in)
bits = 0;
}
// We are done handling the deflate block header. Now copy
// all or almost all of the remaining compressed data that
// has been processed so far. Don't copy one byte at the
// end if it contains bits from the next deflate block or
// pad bits at the end of a deflate block.
// mix is 1 if we are at the end of a deflate block, and if
// some of the bits in the last byte follow this block. mix
// is 0 if we are in the middle of a deflate block, if the
// deflate block ended on a byte boundary, or if all of the
// compressed data processed so far has been consumed.
int mix = (strm.data_type & 0x80) && bits;
// Copy all of the processed compressed data to the output,
// except for the last byte if it contains bits from the
// next deflate block or pad bits at the end of the deflate
// stream. Copy the data after shifting in num bits from
// buf in front of it, leaving num bits from the end of the
// compressed data in buf when done.
unsigned char *end = strm.next_in - mix;
if (put < end) {
if (num)
// Insert num bits from buf before the data being
// copied.
do {
buf += (unsigned)(*put++) << num;
putc(buf, out);
buf >>= 8;
} while (put < end);
else {
// No shifting needed -- write directly.
fwrite(put, 1, end - put, out);
put = end;
}
}
// Process the last processed byte if it wasn't written.
if (mix) {
// Load the last byte into the bit buffer.
buf += (unsigned)(*put++) << num;
num += 8;
if (strm.data_type & 0x40) {
// We are at the end of the deflate stream and
// there are bits pad bits. Discard the pad bits
// and write a byte to the output, if available.
// Leave the num bits left over in buf to prepend
// to the next deflate stream.
num -= bits;
if (num >= 8) {
putc(buf, out);
num -= 8;
buf >>= 8;
}
// Force the pad bits in the bit buffer to zeros.
buf &= ((unsigned long)1 << num) - 1;
// Don't need to set prev here since going to TAIL.
}
else
// At the end of an internal deflate block. Leave
// the last byte in the bit buffer to examine on
// the next entry to BLOCK, when more bits from the
// next block will be available.
prev = num - bits; // number of bits in buffer
// from current block
}
// Don't have a byte left over, so we are in the middle of
// a deflate block, or the deflate block ended on a byte
// boundary. Set prev appropriately for the next entry into
// BLOCK.
else if (strm.data_type & 0x80)
// The block ended on a byte boundary, so no header
// bits are in the bit buffer.
prev = num;
else
// In the middle of a deflate block, so no header here.
prev = -1;
// Check for the end of the deflate stream.
if ((strm.data_type & 0xc0) == 0xc0) {
// That ends the deflate stream on the input side, the
// pad bits were discarded, and any remaining bits from
// the last block in the stream are saved in the bit
// buffer to prepend to the next stream. Process the
// gzip trailer next.
tail = 0;
part = 0;
state = TAIL;
}
break;
case TAIL:
// Accumulate available trailer bytes to update the total
// CRC and the total uncompressed length.
do {
part = (part >> 8) + ((unsigned long)(*put++) << 24);
tail++;
if (tail == 4) {
// Update the total CRC.
z_off_t len2 = memb;
if (len2 < 0 || (unsigned long long)len2 != memb)
BYE("overflow error");
crc = crc ? crc32_combine(crc, part, len2) : part;
part = 0;
}
else if (tail == 8) {
// Update the total uncompressed length. (It's ok
// if this sum is done modulo 2^32.)
len += part;
// At the end of a member. Set up to inflate an
// immediately following gzip member. (If we made
// it this far, then the trailer was valid.)
if (inflateReset(&strm) != Z_OK)
BYE("internal error");
state = BETWEEN;
break;
}
} while (put < strm.next_in);
break;
}
// Process the input buffer until completely consumed.
} while (strm.avail_in > 0);
// Process input until end of file, invalid input, or i/o error.
} while (more);
// Done with the inflate engine.
inflateEnd(&strm);
// Verify the validity of the input.
if (state != BETWEEN)
BYE("input invalid: incomplete gzip stream");
// Write the remaining deflate stream bits, followed by a terminating
// deflate fixed block.
buf += (unsigned long)3 << num;
putc(buf, out);
putc(buf >> 8, out);
if (num > 6)
putc(0, out);
// Write the gzip trailer, which is the CRC and the uncompressed length
// modulo 2^32, both in little-endian order.
putc(crc, out);
putc(crc >> 8, out);
putc(crc >> 16, out);
putc(crc >> 24, out);
putc(len, out);
putc(len >> 8, out);
putc(len >> 16, out);
putc(len >> 24, out);
fflush(out);
// Check for any i/o errors.
if (ferror(in) || ferror(out))
BYE("i/o error: %s", strerror(errno));
// All good!
*err = NULL;
return 0;
}
// Normalize the gzip stream on stdin, writing the result to stdout.
int main(void) {
// Avoid end-of-line conversions on evil operating systems.
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
// Normalize from stdin to stdout, returning 1 on error, 0 if ok.
char *err;
int ret = gzip_normalize(stdin, stdout, &err);
if (ret)
fprintf(stderr, "gznorm error: %s\n", err);
free(err);
return ret;
}
+163 -93
View File
@@ -1,11 +1,13 @@
/* zran.c -- example of zlib/gzip stream indexing and random access /* zran.c -- example of zlib/gzip stream indexing and random access
* Copyright (C) 2005, 2012 Mark Adler * Copyright (C) 2005, 2012, 2018 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
Version 1.1 29 Sep 2012 Mark Adler */ * Version 1.2 14 Oct 2018 Mark Adler */
/* Version History: /* Version History:
1.0 29 May 2005 First version 1.0 29 May 2005 First version
1.1 29 Sep 2012 Fix memory reallocation error 1.1 29 Sep 2012 Fix memory reallocation error
1.2 14 Oct 2018 Handle gzip streams with multiple members
Add a header file to facilitate usage in applications
*/ */
/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary() /* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
@@ -20,11 +22,11 @@
the starting file offset and bit of that block, and the 32K bytes of the starting file offset and bit of that block, and the 32K bytes of
uncompressed data that precede that block. Also the uncompressed offset of uncompressed data that precede that block. Also the uncompressed offset of
that block is saved to provide a referece for locating a desired starting that block is saved to provide a referece for locating a desired starting
point in the uncompressed stream. build_index() works by decompressing the point in the uncompressed stream. deflate_index_build() works by
input zlib or gzip stream a block at a time, and at the end of each block decompressing the input zlib or gzip stream a block at a time, and at the
deciding if enough uncompressed data has gone by to justify the creation of end of each block deciding if enough uncompressed data has gone by to
a new access point. If so, that point is saved in a data structure that justify the creation of a new access point. If so, that point is saved in a
grows as needed to accommodate the points. data structure that grows as needed to accommodate the points.
To use the index, an offset in the uncompressed data is provided, for which To use the index, an offset in the uncompressed data is provided, for which
the latest access point at or preceding that offset is located in the index. the latest access point at or preceding that offset is located in the index.
@@ -43,7 +45,8 @@
There is some fair bit of overhead to starting inflation for the random There is some fair bit of overhead to starting inflation for the random
access, mainly copying the 32K byte dictionary. So if small pieces of the access, mainly copying the 32K byte dictionary. So if small pieces of the
file are being accessed, it would make sense to implement a cache to hold file are being accessed, it would make sense to implement a cache to hold
some lookahead and avoid many calls to extract() for small lengths. some lookahead and avoid many calls to deflate_index_extract() for small
lengths.
Another way to build an index would be to use inflateCopy(). That would Another way to build an index would be to use inflateCopy(). That would
not be constrained to have access points at block boundaries, but requires not be constrained to have access points at block boundaries, but requires
@@ -56,30 +59,21 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "zlib.h" #include "zlib.h"
#include "zran.h"
#define local static
#define SPAN 1048576L /* desired distance between access points */
#define WINSIZE 32768U /* sliding window size */ #define WINSIZE 32768U /* sliding window size */
#define CHUNK 16384 /* file input buffer size */ #define CHUNK 16384 /* file input buffer size */
/* access point entry */ /* Access point entry. */
struct point { struct point {
off_t out; /* corresponding offset in uncompressed data */ off_t out; /* corresponding offset in uncompressed data */
off_t in; /* offset in input file of first full byte */ off_t in; /* offset in input file of first full byte */
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */ int bits; /* number of bits (1-7) from byte at in-1, or 0 */
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */ unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
}; };
/* access point list */ /* See comments in zran.h. */
struct access { void deflate_index_free(struct deflate_index *index)
int have; /* number of list entries filled in */
int size; /* number of list entries allocated */
struct point *list; /* allocated list */
};
/* Deallocate an index built by build_index() */
local void free_index(struct access *index)
{ {
if (index != NULL) { if (index != NULL) {
free(index->list); free(index->list);
@@ -87,39 +81,43 @@ local void free_index(struct access *index)
} }
} }
/* Add an entry to the access point list. If out of memory, deallocate the /* Add an entry to the access point list. If out of memory, deallocate the
existing list and return NULL. */ existing list and return NULL. index->gzip is the allocated size of the
local struct access *addpoint(struct access *index, int bits, index in point entries, until it is time for deflate_index_build() to
off_t in, off_t out, unsigned left, unsigned char *window) return, at which point gzip is set to indicate a gzip file or not.
*/
static struct deflate_index *addpoint(struct deflate_index *index, int bits,
off_t in, off_t out, unsigned left,
unsigned char *window)
{ {
struct point *next; struct point *next;
/* if list is empty, create it (start with eight points) */ /* if list is empty, create it (start with eight points) */
if (index == NULL) { if (index == NULL) {
index = malloc(sizeof(struct access)); index = malloc(sizeof(struct deflate_index));
if (index == NULL) return NULL; if (index == NULL) return NULL;
index->list = malloc(sizeof(struct point) << 3); index->list = malloc(sizeof(struct point) << 3);
if (index->list == NULL) { if (index->list == NULL) {
free(index); free(index);
return NULL; return NULL;
} }
index->size = 8; index->gzip = 8;
index->have = 0; index->have = 0;
} }
/* if list is full, make it bigger */ /* if list is full, make it bigger */
else if (index->have == index->size) { else if (index->have == index->gzip) {
index->size <<= 1; index->gzip <<= 1;
next = realloc(index->list, sizeof(struct point) * index->size); next = realloc(index->list, sizeof(struct point) * index->gzip);
if (next == NULL) { if (next == NULL) {
free_index(index); deflate_index_free(index);
return NULL; return NULL;
} }
index->list = next; index->list = next;
} }
/* fill in entry and increment how many we have */ /* fill in entry and increment how many we have */
next = index->list + index->have; next = (struct point *)(index->list) + index->have;
next->bits = bits; next->bits = bits;
next->in = in; next->in = in;
next->out = out; next->out = out;
@@ -133,20 +131,14 @@ local struct access *addpoint(struct access *index, int bits,
return index; return index;
} }
/* Make one entire pass through the compressed stream and build an index, with /* See comments in zran.h. */
access points about every span bytes of uncompressed output -- span is int deflate_index_build(FILE *in, off_t span, struct deflate_index **built)
chosen to balance the speed of random access against the memory requirements
of the list, about 32K bytes per access point. Note that data after the end
of the first zlib or gzip stream in the file is ignored. build_index()
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
file read error. On success, *built points to the resulting index. */
local int build_index(FILE *in, off_t span, struct access **built)
{ {
int ret; int ret;
int gzip = 0; /* true if reading a gzip file */
off_t totin, totout; /* our own total counters to avoid 4GB limit */ off_t totin, totout; /* our own total counters to avoid 4GB limit */
off_t last; /* totout value of last access point */ off_t last; /* totout value of last access point */
struct access *index; /* access points being generated */ struct deflate_index *index; /* access points being generated */
z_stream strm; z_stream strm;
unsigned char input[CHUNK]; unsigned char input[CHUNK];
unsigned char window[WINSIZE]; unsigned char window[WINSIZE];
@@ -163,7 +155,7 @@ local int build_index(FILE *in, off_t span, struct access **built)
/* inflate the input, maintain a sliding window, and build an index -- this /* inflate the input, maintain a sliding window, and build an index -- this
also validates the integrity of the compressed data using the check also validates the integrity of the compressed data using the check
information at the end of the gzip or zlib stream */ information in the gzip or zlib stream */
totin = totout = last = 0; totin = totout = last = 0;
index = NULL; /* will be allocated by first addpoint() */ index = NULL; /* will be allocated by first addpoint() */
strm.avail_out = 0; strm.avail_out = 0;
@@ -172,14 +164,19 @@ local int build_index(FILE *in, off_t span, struct access **built)
strm.avail_in = fread(input, 1, CHUNK, in); strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in)) { if (ferror(in)) {
ret = Z_ERRNO; ret = Z_ERRNO;
goto build_index_error; goto deflate_index_build_error;
} }
if (strm.avail_in == 0) { if (strm.avail_in == 0) {
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
goto build_index_error; goto deflate_index_build_error;
} }
strm.next_in = input; strm.next_in = input;
/* check for a gzip stream */
if (totin == 0 && strm.avail_in >= 3 &&
input[0] == 31 && input[1] == 139 && input[2] == 8)
gzip = 1;
/* process all of that, or until end of stream */ /* process all of that, or until end of stream */
do { do {
/* reset sliding window if necessary */ /* reset sliding window if necessary */
@@ -198,9 +195,17 @@ local int build_index(FILE *in, off_t span, struct access **built)
if (ret == Z_NEED_DICT) if (ret == Z_NEED_DICT)
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
goto build_index_error; goto deflate_index_build_error;
if (ret == Z_STREAM_END) if (ret == Z_STREAM_END) {
if (gzip &&
(strm.avail_in || ungetc(getc(in), in) != EOF)) {
ret = inflateReset(&strm);
if (ret != Z_OK)
goto deflate_index_build_error;
continue;
}
break; break;
}
/* if at end of block, consider adding an index entry (note that if /* if at end of block, consider adding an index entry (note that if
data_type indicates an end-of-block, then all of the data_type indicates an end-of-block, then all of the
@@ -217,7 +222,7 @@ local int build_index(FILE *in, off_t span, struct access **built)
totout, strm.avail_out, window); totout, strm.avail_out, window);
if (index == NULL) { if (index == NULL) {
ret = Z_MEM_ERROR; ret = Z_MEM_ERROR;
goto build_index_error; goto deflate_index_build_error;
} }
last = totout; last = totout;
} }
@@ -227,27 +232,21 @@ local int build_index(FILE *in, off_t span, struct access **built)
/* clean up and return index (release unused entries in list) */ /* clean up and return index (release unused entries in list) */
(void)inflateEnd(&strm); (void)inflateEnd(&strm);
index->list = realloc(index->list, sizeof(struct point) * index->have); index->list = realloc(index->list, sizeof(struct point) * index->have);
index->size = index->have; index->gzip = gzip;
index->length = totout;
*built = index; *built = index;
return index->size; return index->have;
/* return error */ /* return error */
build_index_error: deflate_index_build_error:
(void)inflateEnd(&strm); (void)inflateEnd(&strm);
if (index != NULL) deflate_index_free(index);
free_index(index);
return ret; return ret;
} }
/* Use the index to read len bytes from offset into buf, return bytes read or /* See comments in zran.h. */
negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past int deflate_index_extract(FILE *in, struct deflate_index *index, off_t offset,
the end of the uncompressed data, then extract() will return a value less unsigned char *buf, int len)
than len, indicating how much as actually read into buf. This function
should not return a data error unless the file was modified since the index
was generated. extract() may also return Z_ERRNO if there is an error on
reading or seeking the input file. */
local int extract(FILE *in, struct access *index, off_t offset,
unsigned char *buf, int len)
{ {
int ret, skip; int ret, skip;
z_stream strm; z_stream strm;
@@ -276,12 +275,12 @@ local int extract(FILE *in, struct access *index, off_t offset,
return ret; return ret;
ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET); ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
if (ret == -1) if (ret == -1)
goto extract_ret; goto deflate_index_extract_ret;
if (here->bits) { if (here->bits) {
ret = getc(in); ret = getc(in);
if (ret == -1) { if (ret == -1) {
ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR; ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
goto extract_ret; goto deflate_index_extract_ret;
} }
(void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits)); (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
} }
@@ -293,21 +292,21 @@ local int extract(FILE *in, struct access *index, off_t offset,
skip = 1; /* while skipping to offset */ skip = 1; /* while skipping to offset */
do { do {
/* define where to put uncompressed data, and how much */ /* define where to put uncompressed data, and how much */
if (offset == 0 && skip) { /* at offset now */
strm.avail_out = len;
strm.next_out = buf;
skip = 0; /* only do this once */
}
if (offset > WINSIZE) { /* skip WINSIZE bytes */ if (offset > WINSIZE) { /* skip WINSIZE bytes */
strm.avail_out = WINSIZE; strm.avail_out = WINSIZE;
strm.next_out = discard; strm.next_out = discard;
offset -= WINSIZE; offset -= WINSIZE;
} }
else if (offset != 0) { /* last skip */ else if (offset > 0) { /* last skip */
strm.avail_out = (unsigned)offset; strm.avail_out = (unsigned)offset;
strm.next_out = discard; strm.next_out = discard;
offset = 0; offset = 0;
} }
else if (skip) { /* at offset now */
strm.avail_out = len;
strm.next_out = buf;
skip = 0; /* only do this once */
}
/* uncompress until avail_out filled, or end of stream */ /* uncompress until avail_out filled, or end of stream */
do { do {
@@ -315,11 +314,11 @@ local int extract(FILE *in, struct access *index, off_t offset,
strm.avail_in = fread(input, 1, CHUNK, in); strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in)) { if (ferror(in)) {
ret = Z_ERRNO; ret = Z_ERRNO;
goto extract_ret; goto deflate_index_extract_ret;
} }
if (strm.avail_in == 0) { if (strm.avail_in == 0) {
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
goto extract_ret; goto deflate_index_extract_ret;
} }
strm.next_in = input; strm.next_in = input;
} }
@@ -327,41 +326,99 @@ local int extract(FILE *in, struct access *index, off_t offset,
if (ret == Z_NEED_DICT) if (ret == Z_NEED_DICT)
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
goto extract_ret; goto deflate_index_extract_ret;
if (ret == Z_STREAM_END) if (ret == Z_STREAM_END) {
break; /* the raw deflate stream has ended */
if (index->gzip == 0)
/* this is a zlib stream that has ended -- done */
break;
/* near the end of a gzip member, which might be followed by
another gzip member -- skip the gzip trailer and see if
there is more input after it */
if (strm.avail_in < 8) {
fseeko(in, 8 - strm.avail_in, SEEK_CUR);
strm.avail_in = 0;
}
else {
strm.avail_in -= 8;
strm.next_in += 8;
}
if (strm.avail_in == 0 && ungetc(getc(in), in) == EOF)
/* the input ended after the gzip trailer -- done */
break;
/* there is more input, so another gzip member should follow --
validate and skip the gzip header */
ret = inflateReset2(&strm, 31);
if (ret != Z_OK)
goto deflate_index_extract_ret;
do {
if (strm.avail_in == 0) {
strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in)) {
ret = Z_ERRNO;
goto deflate_index_extract_ret;
}
if (strm.avail_in == 0) {
ret = Z_DATA_ERROR;
goto deflate_index_extract_ret;
}
strm.next_in = input;
}
ret = inflate(&strm, Z_BLOCK);
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
goto deflate_index_extract_ret;
} while ((strm.data_type & 128) == 0);
/* set up to continue decompression of the raw deflate stream
that follows the gzip header */
ret = inflateReset2(&strm, -15);
if (ret != Z_OK)
goto deflate_index_extract_ret;
}
/* continue to process the available input before reading more */
} while (strm.avail_out != 0); } while (strm.avail_out != 0);
/* if reach end of stream, then don't keep trying to get more */
if (ret == Z_STREAM_END) if (ret == Z_STREAM_END)
/* reached the end of the compressed data -- return the data that
was available, possibly less than requested */
break; break;
/* do until offset reached and requested data read, or stream ends */ /* do until offset reached and requested data read */
} while (skip); } while (skip);
/* compute number of uncompressed bytes read after offset */ /* compute the number of uncompressed bytes read after the offset */
ret = skip ? 0 : len - strm.avail_out; ret = skip ? 0 : len - strm.avail_out;
/* clean up and return bytes read or error */ /* clean up and return the bytes read, or the negative error */
extract_ret: deflate_index_extract_ret:
(void)inflateEnd(&strm); (void)inflateEnd(&strm);
return ret; return ret;
} }
/* Demonstrate the use of build_index() and extract() by processing the file #ifdef TEST
provided on the command line, and the extracting 16K from about 2/3rds of
the way through the uncompressed output, and writing that to stdout. */ #define SPAN 1048576L /* desired distance between access points */
#define LEN 16384 /* number of bytes to extract */
/* Demonstrate the use of deflate_index_build() and deflate_index_extract() by
processing the file provided on the command line, and extracting LEN bytes
from 2/3rds of the way through the uncompressed output, writing that to
stdout. An offset can be provided as the second argument, in which case the
data is extracted from there instead. */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int len; int len;
off_t offset; off_t offset = -1;
FILE *in; FILE *in;
struct access *index = NULL; struct deflate_index *index = NULL;
unsigned char buf[CHUNK]; unsigned char buf[LEN];
/* open input file */ /* open input file */
if (argc != 2) { if (argc < 2 || argc > 3) {
fprintf(stderr, "usage: zran file.gz\n"); fprintf(stderr, "usage: zran file.gz [offset]\n");
return 1; return 1;
} }
in = fopen(argv[1], "rb"); in = fopen(argv[1], "rb");
@@ -370,8 +427,18 @@ int main(int argc, char **argv)
return 1; return 1;
} }
/* get optional offset */
if (argc == 3) {
char *end;
offset = strtoll(argv[2], &end, 10);
if (*end || offset < 0) {
fprintf(stderr, "zran: %s is not a valid offset\n", argv[2]);
return 1;
}
}
/* build index */ /* build index */
len = build_index(in, SPAN, &index); len = deflate_index_build(in, SPAN, &index);
if (len < 0) { if (len < 0) {
fclose(in); fclose(in);
switch (len) { switch (len) {
@@ -392,8 +459,9 @@ int main(int argc, char **argv)
fprintf(stderr, "zran: built index with %d access points\n", len); fprintf(stderr, "zran: built index with %d access points\n", len);
/* use index by reading some bytes from an arbitrary offset */ /* use index by reading some bytes from an arbitrary offset */
offset = (index->list[index->have - 1].out << 1) / 3; if (offset == -1)
len = extract(in, index, offset, buf, CHUNK); offset = (index->length << 1) / 3;
len = deflate_index_extract(in, index, offset, buf, LEN);
if (len < 0) if (len < 0)
fprintf(stderr, "zran: extraction failed: %s error\n", fprintf(stderr, "zran: extraction failed: %s error\n",
len == Z_MEM_ERROR ? "out of memory" : "input corrupted"); len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
@@ -403,7 +471,9 @@ int main(int argc, char **argv)
} }
/* clean up and exit */ /* clean up and exit */
free_index(index); deflate_index_free(index);
fclose(in); fclose(in);
return 0; return 0;
} }
#endif
+40
View File
@@ -0,0 +1,40 @@
/* zran.h -- example of zlib/gzip stream indexing and random access
* Copyright (C) 2005, 2012, 2018 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
* Version 1.2 14 Oct 2018 Mark Adler */
#include <stdio.h>
#include "zlib.h"
/* Access point list. */
struct deflate_index {
int have; /* number of list entries */
int gzip; /* 1 if the index is of a gzip file, 0 if it is of a
zlib stream */
off_t length; /* total length of uncompressed data */
void *list; /* allocated list of entries */
};
/* Make one entire pass through a zlib or gzip compressed stream and build an
index, with access points about every span bytes of uncompressed output.
gzip files with multiple members are indexed in their entirety. span should
be chosen to balance the speed of random access against the memory
requirements of the list, about 32K bytes per access point. The return value
is the number of access points on success (>= 1), Z_MEM_ERROR for out of
memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a file
read error. On success, *built points to the resulting index. */
int deflate_index_build(FILE *in, off_t span, struct deflate_index **built);
/* Deallocate an index built by deflate_index_build() */
void deflate_index_free(struct deflate_index *index);
/* Use the index to read len bytes from offset into buf. Return bytes read or
negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past
the end of the uncompressed data, then deflate_index_extract() will return a
value less than len, indicating how much was actually read into buf. This
function should not return a data error unless the file was modified since
the index was generated, since deflate_index_build() validated all of the
input. deflate_index_extract() will return Z_ERRNO if there is an error on
reading or seeking the input file. */
int deflate_index_extract(FILE *in, struct deflate_index *index, off_t offset,
unsigned char *buf, int len);
+3 -2
View File
@@ -1,5 +1,5 @@
/* gzguts.h -- zlib internal header definitions for gz* operations /* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -39,7 +39,7 @@
# include <io.h> # include <io.h>
#endif #endif
#if defined(_WIN32) || defined(__CYGWIN__) #if defined(_WIN32)
# define WIDECHAR # define WIDECHAR
#endif #endif
@@ -190,6 +190,7 @@ typedef struct {
/* just for writing */ /* just for writing */
int level; /* compression level */ int level; /* compression level */
int strategy; /* compression strategy */ int strategy; /* compression strategy */
int reset; /* true if a reset is pending after a Z_FINISH */
/* seek request */ /* seek request */
z_off64_t skip; /* amount to skip (already rewound if backwards) */ z_off64_t skip; /* amount to skip (already rewound if backwards) */
int seek; /* true if seek request pending */ int seek; /* true if seek request pending */
+5 -3
View File
@@ -1,11 +1,11 @@
/* gzlib.c -- zlib functions common to reading and writing gzip files /* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004-2017 Mark Adler * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "gzguts.h" #include "gzguts.h"
#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) #if defined(_WIN32) && !defined(__BORLANDC__)
# define LSEEK _lseeki64 # define LSEEK _lseeki64
#else #else
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
@@ -81,6 +81,8 @@ local void gz_reset(state)
state->past = 0; /* have not read past end yet */ state->past = 0; /* have not read past end yet */
state->how = LOOK; /* look for gzip header */ state->how = LOOK; /* look for gzip header */
} }
else /* for writing ... */
state->reset = 0; /* no deflateReset pending */
state->seek = 0; /* no seek request pending */ state->seek = 0; /* no seek request pending */
gz_error(state, Z_OK, NULL); /* clear error */ gz_error(state, Z_OK, NULL); /* clear error */
state->x.pos = 0; /* no uncompressed data yet */ state->x.pos = 0; /* no uncompressed data yet */
@@ -397,7 +399,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
/* if within raw area while reading, just go there */ /* if within raw area while reading, just go there */
if (state->mode == GZ_READ && state->how == COPY && if (state->mode == GZ_READ && state->how == COPY &&
state->x.pos + offset >= 0) { state->x.pos + offset >= 0) {
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
if (ret == -1) if (ret == -1)
return -1; return -1;
state->x.have = 0; state->x.have = 0;
+5 -7
View File
@@ -1,5 +1,5 @@
/* gzread.c -- zlib functions for reading gzip files /* gzread.c -- zlib functions for reading gzip files
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -314,9 +314,9 @@ local z_size_t gz_read(state, buf, len)
got = 0; got = 0;
do { do {
/* set n to the maximum amount of len that fits in an unsigned int */ /* set n to the maximum amount of len that fits in an unsigned int */
n = -1; n = (unsigned)-1;
if (n > len) if (n > len)
n = len; n = (unsigned)len;
/* first just try copying data from the output buffer */ /* first just try copying data from the output buffer */
if (state->x.have) { if (state->x.have) {
@@ -397,7 +397,7 @@ int ZEXPORT gzread(file, buf, len)
} }
/* read len or fewer bytes to buf */ /* read len or fewer bytes to buf */
len = gz_read(state, buf, len); len = (unsigned)gz_read(state, buf, len);
/* check for an error */ /* check for an error */
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
@@ -447,7 +447,6 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
int ZEXPORT gzgetc(file) int ZEXPORT gzgetc(file)
gzFile file; gzFile file;
{ {
int ret;
unsigned char buf[1]; unsigned char buf[1];
gz_statep state; gz_statep state;
@@ -469,8 +468,7 @@ int ZEXPORT gzgetc(file)
} }
/* nothing there -- try gz_read() */ /* nothing there -- try gz_read() */
ret = gz_read(state, buf, 1); return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
return ret < 1 ? -1 : buf[0];
} }
int ZEXPORT gzgetc_(file) int ZEXPORT gzgetc_(file)
+25 -13
View File
@@ -1,5 +1,5 @@
/* gzwrite.c -- zlib functions for writing gzip files /* gzwrite.c -- zlib functions for writing gzip files
* Copyright (C) 2004-2017 Mark Adler * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -97,6 +97,15 @@ local int gz_comp(state, flush)
return 0; return 0;
} }
/* check for a pending reset */
if (state->reset) {
/* don't start a new gzip member unless there is data to write */
if (strm->avail_in == 0)
return 0;
deflateReset(strm);
state->reset = 0;
}
/* run deflate() on provided input until it produces no more output */ /* run deflate() on provided input until it produces no more output */
ret = Z_OK; ret = Z_OK;
do { do {
@@ -134,7 +143,7 @@ local int gz_comp(state, flush)
/* if that completed a deflate stream, allow another to start */ /* if that completed a deflate stream, allow another to start */
if (flush == Z_FINISH) if (flush == Z_FINISH)
deflateReset(strm); state->reset = 1;
/* all done, no errors */ /* all done, no errors */
return 0; return 0;
@@ -209,7 +218,7 @@ local z_size_t gz_write(state, buf, len)
state->in); state->in);
copy = state->size - have; copy = state->size - have;
if (copy > len) if (copy > len)
copy = len; copy = (unsigned)len;
memcpy(state->in + have, buf, copy); memcpy(state->in + have, buf, copy);
state->strm.avail_in += copy; state->strm.avail_in += copy;
state->x.pos += copy; state->x.pos += copy;
@@ -229,7 +238,7 @@ local z_size_t gz_write(state, buf, len)
do { do {
unsigned n = (unsigned)-1; unsigned n = (unsigned)-1;
if (n > len) if (n > len)
n = len; n = (unsigned)len;
state->strm.avail_in = n; state->strm.avail_in = n;
state->x.pos += n; state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1) if (gz_comp(state, Z_NO_FLUSH) == -1)
@@ -349,12 +358,11 @@ int ZEXPORT gzputc(file, c)
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
int ZEXPORT gzputs(file, str) int ZEXPORT gzputs(file, s)
gzFile file; gzFile file;
const char *str; const char *s;
{ {
int ret; z_size_t len, put;
z_size_t len;
gz_statep state; gz_statep state;
/* get internal structure */ /* get internal structure */
@@ -367,9 +375,13 @@ int ZEXPORT gzputs(file, str)
return -1; return -1;
/* write string */ /* write string */
len = strlen(str); len = strlen(s);
ret = gz_write(state, str, len); if ((int)len < 0 || (unsigned)len != len) {
return ret == 0 && len != 0 ? -1 : ret; gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
return -1;
}
put = gz_write(state, s, len);
return put < len ? -1 : (int)len;
} }
#if defined(STDC) || defined(Z_HAVE_STDARG_H) #if defined(STDC) || defined(Z_HAVE_STDARG_H)
@@ -441,7 +453,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
strm->avail_in = state->size; strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1) if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err; return state->err;
memcpy(state->in, state->in + state->size, left); memmove(state->in, state->in + state->size, left);
strm->next_in = state->in; strm->next_in = state->in;
strm->avail_in = left; strm->avail_in = left;
} }
@@ -540,7 +552,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
strm->avail_in = state->size; strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1) if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err; return state->err;
memcpy(state->in, state->in + state->size, left); memmove(state->in, state->in + state->size, left);
strm->next_in = state->in; strm->next_in = state->in;
strm->avail_in = left; strm->avail_in = left;
} }
+2 -1
View File
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface /* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2016 Mark Adler * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -477,6 +477,7 @@ void FAR *out_desc;
} }
Tracev((stderr, "inflate: codes ok\n")); Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN; state->mode = LEN;
/* fallthrough */
case LEN: case LEN:
/* use inflate_fast() if we have enough input and output */ /* use inflate_fast() if we have enough input and output */
+14 -14
View File
@@ -70,7 +70,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
code const FAR *dcode; /* local strm->distcode */ code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */ unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */ unsigned dmask; /* mask for first level of distance codes */
code here; /* retrieved table entry */ code const *here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */ unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */ /* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */ unsigned len; /* match length, unused bytes */
@@ -107,20 +107,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold += (unsigned long)(*in++) << bits; hold += (unsigned long)(*in++) << bits;
bits += 8; bits += 8;
} }
here = lcode[hold & lmask]; here = lcode + (hold & lmask);
dolen: dolen:
op = (unsigned)(here.bits); op = (unsigned)(here->bits);
hold >>= op; hold >>= op;
bits -= op; bits -= op;
op = (unsigned)(here.op); op = (unsigned)(here->op);
if (op == 0) { /* literal */ if (op == 0) { /* literal */
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
"inflate: literal '%c'\n" : "inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here.val)); "inflate: literal 0x%02x\n", here->val));
*out++ = (unsigned char)(here.val); *out++ = (unsigned char)(here->val);
} }
else if (op & 16) { /* length base */ else if (op & 16) { /* length base */
len = (unsigned)(here.val); len = (unsigned)(here->val);
op &= 15; /* number of extra bits */ op &= 15; /* number of extra bits */
if (op) { if (op) {
if (bits < op) { if (bits < op) {
@@ -138,14 +138,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold += (unsigned long)(*in++) << bits; hold += (unsigned long)(*in++) << bits;
bits += 8; bits += 8;
} }
here = dcode[hold & dmask]; here = dcode + (hold & dmask);
dodist: dodist:
op = (unsigned)(here.bits); op = (unsigned)(here->bits);
hold >>= op; hold >>= op;
bits -= op; bits -= op;
op = (unsigned)(here.op); op = (unsigned)(here->op);
if (op & 16) { /* distance base */ if (op & 16) { /* distance base */
dist = (unsigned)(here.val); dist = (unsigned)(here->val);
op &= 15; /* number of extra bits */ op &= 15; /* number of extra bits */
if (bits < op) { if (bits < op) {
hold += (unsigned long)(*in++) << bits; hold += (unsigned long)(*in++) << bits;
@@ -264,7 +264,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
} }
} }
else if ((op & 64) == 0) { /* 2nd level distance code */ else if ((op & 64) == 0) { /* 2nd level distance code */
here = dcode[here.val + (hold & ((1U << op) - 1))]; here = dcode + here->val + (hold & ((1U << op) - 1));
goto dodist; goto dodist;
} }
else { else {
@@ -274,7 +274,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
} }
} }
else if ((op & 64) == 0) { /* 2nd level length code */ else if ((op & 64) == 0) { /* 2nd level length code */
here = lcode[here.val + (hold & ((1U << op) - 1))]; here = lcode + here->val + (hold & ((1U << op) - 1));
goto dolen; goto dolen;
} }
else if (op & 32) { /* end-of-block */ else if (op & 32) { /* end-of-block */
+39 -8
View File
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression /* inflate.c -- zlib decompression
* Copyright (C) 1995-2016 Mark Adler * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -130,6 +130,7 @@ z_streamp strm;
state->mode = HEAD; state->mode = HEAD;
state->last = 0; state->last = 0;
state->havedict = 0; state->havedict = 0;
state->flags = -1;
state->dmax = 32768U; state->dmax = 32768U;
state->head = Z_NULL; state->head = Z_NULL;
state->hold = 0; state->hold = 0;
@@ -447,10 +448,10 @@ unsigned copy;
/* check function to use adler32() for zlib or crc32() for gzip */ /* check function to use adler32() for zlib or crc32() for gzip */
#ifdef GUNZIP #ifdef GUNZIP
# define UPDATE(check, buf, len) \ # define UPDATE_CHECK(check, buf, len) \
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
#else #else
# define UPDATE(check, buf, len) adler32(check, buf, len) # define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
#endif #endif
/* check macros for header crc */ /* check macros for header crc */
@@ -670,7 +671,6 @@ int flush;
state->mode = FLAGS; state->mode = FLAGS;
break; break;
} }
state->flags = 0; /* expect zlib header */
if (state->head != Z_NULL) if (state->head != Z_NULL)
state->head->done = -1; state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */ if (!(state->wrap & 1) || /* check if zlib header allowed */
@@ -697,6 +697,7 @@ int flush;
break; break;
} }
state->dmax = 1U << len; state->dmax = 1U << len;
state->flags = 0; /* indicate zlib header */
Tracev((stderr, "inflate: zlib header ok\n")); Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0); strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE; state->mode = hold & 0x200 ? DICTID : TYPE;
@@ -722,6 +723,7 @@ int flush;
CRC2(state->check, hold); CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = TIME; state->mode = TIME;
/* fallthrough */
case TIME: case TIME:
NEEDBITS(32); NEEDBITS(32);
if (state->head != Z_NULL) if (state->head != Z_NULL)
@@ -730,6 +732,7 @@ int flush;
CRC4(state->check, hold); CRC4(state->check, hold);
INITBITS(); INITBITS();
state->mode = OS; state->mode = OS;
/* fallthrough */
case OS: case OS:
NEEDBITS(16); NEEDBITS(16);
if (state->head != Z_NULL) { if (state->head != Z_NULL) {
@@ -740,6 +743,7 @@ int flush;
CRC2(state->check, hold); CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = EXLEN; state->mode = EXLEN;
/* fallthrough */
case EXLEN: case EXLEN:
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
NEEDBITS(16); NEEDBITS(16);
@@ -753,6 +757,7 @@ int flush;
else if (state->head != Z_NULL) else if (state->head != Z_NULL)
state->head->extra = Z_NULL; state->head->extra = Z_NULL;
state->mode = EXTRA; state->mode = EXTRA;
/* fallthrough */
case EXTRA: case EXTRA:
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
copy = state->length; copy = state->length;
@@ -775,6 +780,7 @@ int flush;
} }
state->length = 0; state->length = 0;
state->mode = NAME; state->mode = NAME;
/* fallthrough */
case NAME: case NAME:
if (state->flags & 0x0800) { if (state->flags & 0x0800) {
if (have == 0) goto inf_leave; if (have == 0) goto inf_leave;
@@ -796,6 +802,7 @@ int flush;
state->head->name = Z_NULL; state->head->name = Z_NULL;
state->length = 0; state->length = 0;
state->mode = COMMENT; state->mode = COMMENT;
/* fallthrough */
case COMMENT: case COMMENT:
if (state->flags & 0x1000) { if (state->flags & 0x1000) {
if (have == 0) goto inf_leave; if (have == 0) goto inf_leave;
@@ -816,6 +823,7 @@ int flush;
else if (state->head != Z_NULL) else if (state->head != Z_NULL)
state->head->comment = Z_NULL; state->head->comment = Z_NULL;
state->mode = HCRC; state->mode = HCRC;
/* fallthrough */
case HCRC: case HCRC:
if (state->flags & 0x0200) { if (state->flags & 0x0200) {
NEEDBITS(16); NEEDBITS(16);
@@ -839,6 +847,7 @@ int flush;
strm->adler = state->check = ZSWAP32(hold); strm->adler = state->check = ZSWAP32(hold);
INITBITS(); INITBITS();
state->mode = DICT; state->mode = DICT;
/* fallthrough */
case DICT: case DICT:
if (state->havedict == 0) { if (state->havedict == 0) {
RESTORE(); RESTORE();
@@ -846,8 +855,10 @@ int flush;
} }
strm->adler = state->check = adler32(0L, Z_NULL, 0); strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE; state->mode = TYPE;
/* fallthrough */
case TYPE: case TYPE:
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
/* fallthrough */
case TYPEDO: case TYPEDO:
if (state->last) { if (state->last) {
BYTEBITS(); BYTEBITS();
@@ -898,8 +909,10 @@ int flush;
INITBITS(); INITBITS();
state->mode = COPY_; state->mode = COPY_;
if (flush == Z_TREES) goto inf_leave; if (flush == Z_TREES) goto inf_leave;
/* fallthrough */
case COPY_: case COPY_:
state->mode = COPY; state->mode = COPY;
/* fallthrough */
case COPY: case COPY:
copy = state->length; copy = state->length;
if (copy) { if (copy) {
@@ -935,6 +948,7 @@ int flush;
Tracev((stderr, "inflate: table sizes ok\n")); Tracev((stderr, "inflate: table sizes ok\n"));
state->have = 0; state->have = 0;
state->mode = LENLENS; state->mode = LENLENS;
/* fallthrough */
case LENLENS: case LENLENS:
while (state->have < state->ncode) { while (state->have < state->ncode) {
NEEDBITS(3); NEEDBITS(3);
@@ -956,6 +970,7 @@ int flush;
Tracev((stderr, "inflate: code lengths ok\n")); Tracev((stderr, "inflate: code lengths ok\n"));
state->have = 0; state->have = 0;
state->mode = CODELENS; state->mode = CODELENS;
/* fallthrough */
case CODELENS: case CODELENS:
while (state->have < state->nlen + state->ndist) { while (state->have < state->nlen + state->ndist) {
for (;;) { for (;;) {
@@ -1039,8 +1054,10 @@ int flush;
Tracev((stderr, "inflate: codes ok\n")); Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN_; state->mode = LEN_;
if (flush == Z_TREES) goto inf_leave; if (flush == Z_TREES) goto inf_leave;
/* fallthrough */
case LEN_: case LEN_:
state->mode = LEN; state->mode = LEN;
/* fallthrough */
case LEN: case LEN:
if (have >= 6 && left >= 258) { if (have >= 6 && left >= 258) {
RESTORE(); RESTORE();
@@ -1090,6 +1107,7 @@ int flush;
} }
state->extra = (unsigned)(here.op) & 15; state->extra = (unsigned)(here.op) & 15;
state->mode = LENEXT; state->mode = LENEXT;
/* fallthrough */
case LENEXT: case LENEXT:
if (state->extra) { if (state->extra) {
NEEDBITS(state->extra); NEEDBITS(state->extra);
@@ -1100,6 +1118,7 @@ int flush;
Tracevv((stderr, "inflate: length %u\n", state->length)); Tracevv((stderr, "inflate: length %u\n", state->length));
state->was = state->length; state->was = state->length;
state->mode = DIST; state->mode = DIST;
/* fallthrough */
case DIST: case DIST:
for (;;) { for (;;) {
here = state->distcode[BITS(state->distbits)]; here = state->distcode[BITS(state->distbits)];
@@ -1127,6 +1146,7 @@ int flush;
state->offset = (unsigned)here.val; state->offset = (unsigned)here.val;
state->extra = (unsigned)(here.op) & 15; state->extra = (unsigned)(here.op) & 15;
state->mode = DISTEXT; state->mode = DISTEXT;
/* fallthrough */
case DISTEXT: case DISTEXT:
if (state->extra) { if (state->extra) {
NEEDBITS(state->extra); NEEDBITS(state->extra);
@@ -1143,6 +1163,7 @@ int flush;
#endif #endif
Tracevv((stderr, "inflate: distance %u\n", state->offset)); Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH; state->mode = MATCH;
/* fallthrough */
case MATCH: case MATCH:
if (left == 0) goto inf_leave; if (left == 0) goto inf_leave;
copy = out - left; copy = out - left;
@@ -1202,7 +1223,7 @@ int flush;
state->total += out; state->total += out;
if ((state->wrap & 4) && out) if ((state->wrap & 4) && out)
strm->adler = state->check = strm->adler = state->check =
UPDATE(state->check, put - out, out); UPDATE_CHECK(state->check, put - out, out);
out = left; out = left;
if ((state->wrap & 4) && ( if ((state->wrap & 4) && (
#ifdef GUNZIP #ifdef GUNZIP
@@ -1218,10 +1239,11 @@ int flush;
} }
#ifdef GUNZIP #ifdef GUNZIP
state->mode = LENGTH; state->mode = LENGTH;
/* fallthrough */
case LENGTH: case LENGTH:
if (state->wrap && state->flags) { if (state->wrap && state->flags) {
NEEDBITS(32); NEEDBITS(32);
if (hold != (state->total & 0xffffffffUL)) { if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
strm->msg = (char *)"incorrect length check"; strm->msg = (char *)"incorrect length check";
state->mode = BAD; state->mode = BAD;
break; break;
@@ -1231,6 +1253,7 @@ int flush;
} }
#endif #endif
state->mode = DONE; state->mode = DONE;
/* fallthrough */
case DONE: case DONE:
ret = Z_STREAM_END; ret = Z_STREAM_END;
goto inf_leave; goto inf_leave;
@@ -1240,6 +1263,7 @@ int flush;
case MEM: case MEM:
return Z_MEM_ERROR; return Z_MEM_ERROR;
case SYNC: case SYNC:
/* fallthrough */
default: default:
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
@@ -1265,7 +1289,7 @@ int flush;
state->total += out; state->total += out;
if ((state->wrap & 4) && out) if ((state->wrap & 4) && out)
strm->adler = state->check = strm->adler = state->check =
UPDATE(state->check, strm->next_out - out, out); UPDATE_CHECK(state->check, strm->next_out - out, out);
strm->data_type = (int)state->bits + (state->last ? 64 : 0) + strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0) + (state->mode == TYPE ? 128 : 0) +
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
@@ -1401,6 +1425,7 @@ int ZEXPORT inflateSync(strm)
z_streamp strm; z_streamp strm;
{ {
unsigned len; /* number of bytes to look at or looked at */ unsigned len; /* number of bytes to look at or looked at */
int flags; /* temporary to save header status */
unsigned long in, out; /* temporary to save total_in and total_out */ unsigned long in, out; /* temporary to save total_in and total_out */
unsigned char buf[4]; /* to restore bit buffer to byte string */ unsigned char buf[4]; /* to restore bit buffer to byte string */
struct inflate_state FAR *state; struct inflate_state FAR *state;
@@ -1433,9 +1458,15 @@ z_streamp strm;
/* return no joy or set up to restart inflate() on a new block */ /* return no joy or set up to restart inflate() on a new block */
if (state->have != 4) return Z_DATA_ERROR; if (state->have != 4) return Z_DATA_ERROR;
if (state->flags == -1)
state->wrap = 0; /* if no header yet, treat as raw */
else
state->wrap &= ~4; /* no point in computing a check value now */
flags = state->flags;
in = strm->total_in; out = strm->total_out; in = strm->total_in; out = strm->total_out;
inflateReset(strm); inflateReset(strm);
strm->total_in = in; strm->total_out = out; strm->total_in = in; strm->total_out = out;
state->flags = flags;
state->mode = TYPE; state->mode = TYPE;
return Z_OK; return Z_OK;
} }
@@ -1531,7 +1562,7 @@ int check;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR; if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
if (check) if (check && state->wrap)
state->wrap |= 4; state->wrap |= 4;
else else
state->wrap &= ~4; state->wrap &= ~4;
+3 -2
View File
@@ -1,5 +1,5 @@
/* inflate.h -- internal inflate state definition /* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2016 Mark Adler * Copyright (C) 1995-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -86,7 +86,8 @@ struct inflate_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip, int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
bit 2 true to validate check value */ bit 2 true to validate check value */
int havedict; /* true if dictionary provided */ int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */ int flags; /* gzip header method and flags, 0 if zlib, or
-1 if raw or no header yet */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */ unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */ unsigned long total; /* protected copy of output count */
+3 -3
View File
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2017 Mark Adler * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate_copyright[] = const char inflate_copyright[] =
" inflate 1.2.11 Copyright 1995-2017 Mark Adler "; " inflate 1.2.12 Copyright 1995-2022 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+1 -1
View File
@@ -1,4 +1,4 @@
ZLIB version 1.2.11 for OS/400 installation instructions ZLIB version 1.2.12 for OS/400 installation instructions
1) Download and unpack the zlib tarball to some IFS directory. 1) Download and unpack the zlib tarball to some IFS directory.
(i.e.: /path/to/the/zlib/ifs/source/directory) (i.e.: /path/to/the/zlib/ifs/source/directory)
+3 -3
View File
@@ -1,7 +1,7 @@
* ZLIB.INC - Interface to the general purpose compression library * ZLIB.INC - Interface to the general purpose compression library
* *
* ILE RPG400 version by Patrick Monnerat, DATASPHERE. * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
* Version 1.2.11 * Version 1.2.12
* *
* *
* WARNING: * WARNING:
@@ -22,12 +22,12 @@
* *
* Versioning information. * Versioning information.
* *
D ZLIB_VERSION C '1.2.11' D ZLIB_VERSION C '1.2.12'
D ZLIB_VERNUM C X'12a0' D ZLIB_VERNUM C X'12a0'
D ZLIB_VER_MAJOR C 1 D ZLIB_VER_MAJOR C 1
D ZLIB_VER_MINOR C 2 D ZLIB_VER_MINOR C 2
D ZLIB_VER_REVISION... D ZLIB_VER_REVISION...
D C 11 D C 12
D ZLIB_VER_SUBREVISION... D ZLIB_VER_SUBREVISION...
D C 0 D C 0
* *
+5 -5
View File
@@ -25,10 +25,10 @@
<QPG:Files> <QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" user="root:bin" permission="644"/> <QPG:Add file="../libz.so.1.2.12" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.11"/> <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.12"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.11"/> <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.12"/>
<QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" component="slib"/> <QPG:Add file="../libz.so.1.2.12" install="/opt/lib/" component="slib"/>
</QPG:Files> </QPG:Files>
<QPG:PackageFilter> <QPG:PackageFilter>
@@ -63,7 +63,7 @@
</QPM:ProductDescription> </QPM:ProductDescription>
<QPM:ReleaseDescription> <QPM:ReleaseDescription>
<QPM:ReleaseVersion>1.2.11</QPM:ReleaseVersion> <QPM:ReleaseVersion>1.2.12</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency> <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability> <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor> <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
+2 -3
View File
@@ -440,9 +440,8 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
CHECK_ERR(err, "inflateSync"); CHECK_ERR(err, "inflateSync");
err = inflate(&d_stream, Z_FINISH); err = inflate(&d_stream, Z_FINISH);
if (err != Z_DATA_ERROR) { if (err != Z_STREAM_END) {
fprintf(stderr, "inflate should report DATA_ERROR\n"); fprintf(stderr, "inflate should report Z_STREAM_END\n");
/* Because of incorrect adler32 */
exit(1); exit(1);
} }
err = inflateEnd(&d_stream); err = inflateEnd(&d_stream);
+2 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<package name="zlib" version="1.2.11"> <package name="zlib" version="1.2.12">
<library name="zlib" dlversion="1.2.11" dlname="z"> <library name="zlib" dlversion="1.2.12" dlname="z">
<property name="description"> zip compression library </property> <property name="description"> zip compression library </property>
<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" /> <property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
+27 -48
View File
@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2017 Jean-loup Gailly * Copyright (C) 1995-2021 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006 * detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -149,7 +149,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
local void compress_block OF((deflate_state *s, const ct_data *ltree, local void compress_block OF((deflate_state *s, const ct_data *ltree,
const ct_data *dtree)); const ct_data *dtree));
local int detect_data_type OF((deflate_state *s)); local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length)); local unsigned bi_reverse OF((unsigned code, int len));
local void bi_windup OF((deflate_state *s)); local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s)); local void bi_flush OF((deflate_state *s));
@@ -416,7 +416,7 @@ local void init_block(s)
s->dyn_ltree[END_BLOCK].Freq = 1; s->dyn_ltree[END_BLOCK].Freq = 1;
s->opt_len = s->static_len = 0L; s->opt_len = s->static_len = 0L;
s->last_lit = s->matches = 0; s->sym_next = s->matches = 0;
} }
#define SMALLEST 1 #define SMALLEST 1
@@ -870,7 +870,8 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
bi_windup(s); /* align on byte boundary */ bi_windup(s); /* align on byte boundary */
put_short(s, (ush)stored_len); put_short(s, (ush)stored_len);
put_short(s, (ush)~stored_len); put_short(s, (ush)~stored_len);
zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); if (stored_len)
zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
s->pending += stored_len; s->pending += stored_len;
#ifdef ZLIB_DEBUG #ifdef ZLIB_DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
@@ -947,7 +948,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
s->last_lit)); s->sym_next / 3));
if (static_lenb <= opt_lenb) opt_lenb = static_lenb; if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
@@ -1016,8 +1017,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
unsigned dist; /* distance of matched string */ unsigned dist; /* distance of matched string */
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{ {
s->d_buf[s->last_lit] = (ush)dist; s->sym_buf[s->sym_next++] = dist;
s->l_buf[s->last_lit++] = (uch)lc; s->sym_buf[s->sym_next++] = dist >> 8;
s->sym_buf[s->sym_next++] = lc;
if (dist == 0) { if (dist == 0) {
/* lc is the unmatched char */ /* lc is the unmatched char */
s->dyn_ltree[lc].Freq++; s->dyn_ltree[lc].Freq++;
@@ -1032,30 +1034,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++; s->dyn_dtree[d_code(dist)].Freq++;
} }
return (s->sym_next == s->sym_end);
#ifdef TRUNCATE_BLOCK
/* Try to guess if it is profitable to stop the current block here */
if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
/* Compute an upper bound for the compressed length */
ulg out_length = (ulg)s->last_lit*8L;
ulg in_length = (ulg)((long)s->strstart - s->block_start);
int dcode;
for (dcode = 0; dcode < D_CODES; dcode++) {
out_length += (ulg)s->dyn_dtree[dcode].Freq *
(5L+extra_dbits[dcode]);
}
out_length >>= 3;
Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
s->last_lit, in_length, out_length,
100L - out_length*100L/in_length));
if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
}
#endif
return (s->last_lit == s->lit_bufsize-1);
/* We avoid equality with lit_bufsize because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
*/
} }
/* =========================================================================== /* ===========================================================================
@@ -1068,13 +1047,14 @@ local void compress_block(s, ltree, dtree)
{ {
unsigned dist; /* distance of matched string */ unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */ int lc; /* match length or unmatched char (if dist == 0) */
unsigned lx = 0; /* running index in l_buf */ unsigned sx = 0; /* running index in sym_buf */
unsigned code; /* the code to send */ unsigned code; /* the code to send */
int extra; /* number of extra bits to send */ int extra; /* number of extra bits to send */
if (s->last_lit != 0) do { if (s->sym_next != 0) do {
dist = s->d_buf[lx]; dist = s->sym_buf[sx++] & 0xff;
lc = s->l_buf[lx++]; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
lc = s->sym_buf[sx++];
if (dist == 0) { if (dist == 0) {
send_code(s, lc, ltree); /* send a literal byte */ send_code(s, lc, ltree); /* send a literal byte */
Tracecv(isgraph(lc), (stderr," '%c' ", lc)); Tracecv(isgraph(lc), (stderr," '%c' ", lc));
@@ -1099,11 +1079,10 @@ local void compress_block(s, ltree, dtree)
} }
} /* literal or match pair ? */ } /* literal or match pair ? */
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ /* Check that the overlay between pending_buf and sym_buf is ok: */
Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
"pendingBuf overflow");
} while (lx < s->last_lit); } while (sx < s->sym_next);
send_code(s, END_BLOCK, ltree); send_code(s, END_BLOCK, ltree);
} }
@@ -1112,9 +1091,9 @@ local void compress_block(s, ltree, dtree)
* Check if the data type is TEXT or BINARY, using the following algorithm: * Check if the data type is TEXT or BINARY, using the following algorithm:
* - TEXT if the two conditions below are satisfied: * - TEXT if the two conditions below are satisfied:
* a) There are no non-portable control characters belonging to the * a) There are no non-portable control characters belonging to the
* "black list" (0..6, 14..25, 28..31). * "block list" (0..6, 14..25, 28..31).
* b) There is at least one printable character belonging to the * b) There is at least one printable character belonging to the
* "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
* - BINARY otherwise. * - BINARY otherwise.
* - The following partially-portable control characters form a * - The following partially-portable control characters form a
* "gray list" that is ignored in this detection algorithm: * "gray list" that is ignored in this detection algorithm:
@@ -1124,19 +1103,19 @@ local void compress_block(s, ltree, dtree)
local int detect_data_type(s) local int detect_data_type(s)
deflate_state *s; deflate_state *s;
{ {
/* black_mask is the bit mask of black-listed bytes /* block_mask is the bit mask of block-listed bytes
* set bits 0..6, 14..25, and 28..31 * set bits 0..6, 14..25, and 28..31
* 0xf3ffc07f = binary 11110011111111111100000001111111 * 0xf3ffc07f = binary 11110011111111111100000001111111
*/ */
unsigned long black_mask = 0xf3ffc07fUL; unsigned long block_mask = 0xf3ffc07fUL;
int n; int n;
/* Check for non-textual ("black-listed") bytes. */ /* Check for non-textual ("block-listed") bytes. */
for (n = 0; n <= 31; n++, black_mask >>= 1) for (n = 0; n <= 31; n++, block_mask >>= 1)
if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
return Z_BINARY; return Z_BINARY;
/* Check for textual ("white-listed") bytes. */ /* Check for textual ("allow-listed") bytes. */
if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
|| s->dyn_ltree[13].Freq != 0) || s->dyn_ltree[13].Freq != 0)
return Z_TEXT; return Z_TEXT;
@@ -1144,7 +1123,7 @@ local int detect_data_type(s)
if (s->dyn_ltree[n].Freq != 0) if (s->dyn_ltree[n].Freq != 0)
return Z_TEXT; return Z_TEXT;
/* There are no "black-listed" or "white-listed" bytes: /* There are no "block-listed" or "allow-listed" bytes:
* this stream either is empty or has tolerated ("gray-listed") bytes only. * this stream either is empty or has tolerated ("gray-listed") bytes only.
*/ */
return Z_BINARY; return Z_BINARY;
-1
View File
@@ -3,7 +3,6 @@
# #
# Usage: # Usage:
# make -f win32/Makefile.bor # make -f win32/Makefile.bor
# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
# ------------ Borland C++ ------------ # ------------ Borland C++ ------------
-5
View File
@@ -11,10 +11,6 @@
# #
# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc # make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
# #
# To use the asm code, type:
# cp contrib/asm?86/match.S ./match.S
# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
#
# To install libz.a, zconf.h and zlib.h in the system directories, type: # To install libz.a, zconf.h and zlib.h in the system directories, type:
# #
# make install -fwin32/Makefile.gcc # make install -fwin32/Makefile.gcc
@@ -38,7 +34,6 @@ IMPLIB = libz.dll.a
# #
SHARED_MODE=0 SHARED_MODE=0
#LOC = -DASMV
#LOC = -DZLIB_DEBUG -g #LOC = -DZLIB_DEBUG -g
PREFIX = PREFIX =
-4
View File
@@ -4,10 +4,6 @@
# Usage: # Usage:
# nmake -f win32/Makefile.msc (standard build) # nmake -f win32/Makefile.msc (standard build)
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) # nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
# The toplevel directory of the source tree. # The toplevel directory of the source tree.
# #
+2 -2
View File
@@ -1,6 +1,6 @@
ZLIB DATA COMPRESSION LIBRARY ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.11 is a general purpose data compression library. All the code is zlib 1.2.12 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files (Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -22,7 +22,7 @@ before asking for help.
Manifest: Manifest:
The package zlib-1.2.11-win32-x86.zip will contain the following files: The package zlib-1.2.12-win32-x86.zip will contain the following files:
README-WIN32.txt This document README-WIN32.txt This document
ChangeLog Changes since previous zlib packages ChangeLog Changes since previous zlib packages
+3
View File
@@ -69,6 +69,7 @@ EXPORTS
gzoffset64 gzoffset64
adler32_combine64 adler32_combine64
crc32_combine64 crc32_combine64
crc32_combine_gen64
; checksum functions ; checksum functions
adler32 adler32
adler32_z adler32_z
@@ -76,6 +77,8 @@ EXPORTS
crc32_z crc32_z
adler32_combine adler32_combine
crc32_combine crc32_combine
crc32_combine_gen
crc32_combine_op
; various hacks, don't look :) ; various hacks, don't look :)
deflateInit_ deflateInit_
deflateInit2_ deflateInit2_
+3 -3
View File
@@ -1,4 +1,4 @@
.TH ZLIB 3 "15 Jan 2017" .TH ZLIB 3 "27 Mar 2022"
.SH NAME .SH NAME
zlib \- compression/decompression library zlib \- compression/decompression library
.SH SYNOPSIS .SH SYNOPSIS
@@ -105,9 +105,9 @@ before asking for help.
Send questions and/or comments to zlib@gzip.org, Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS AND LICENSE .SH AUTHORS AND LICENSE
Version 1.2.11 Version 1.2.12
.LP .LP
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
.LP .LP
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
Binary file not shown.
+123 -100
View File
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.11, January 15th, 2017 version 1.2.12, March 11th, 2022
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@@ -37,11 +37,11 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.2.11" #define ZLIB_VERSION "1.2.12"
#define ZLIB_VERNUM 0x12b0 #define ZLIB_VERNUM 0x12c0
#define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2 #define ZLIB_VER_MINOR 2
#define ZLIB_VER_REVISION 11 #define ZLIB_VER_REVISION 12
#define ZLIB_VER_SUBREVISION 0 #define ZLIB_VER_SUBREVISION 0
/* /*
@@ -543,8 +543,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int strategy)); int strategy));
This is another version of deflateInit with more compression options. The This is another version of deflateInit with more compression options. The
fields next_in, zalloc, zfree and opaque must be initialized before by the fields zalloc, zfree and opaque must be initialized before by the caller.
caller.
The method parameter is the compression method. It must be Z_DEFLATED in The method parameter is the compression method. It must be Z_DEFLATED in
this version of the library. this version of the library.
@@ -712,11 +711,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
used to switch between compression and straight copy of the input data, or used to switch between compression and straight copy of the input data, or
to switch to a different kind of input data requiring a different strategy. to switch to a different kind of input data requiring a different strategy.
If the compression approach (which is a function of the level) or the If the compression approach (which is a function of the level) or the
strategy is changed, and if any input has been consumed in a previous strategy is changed, and if there have been any deflate() calls since the
deflate() call, then the input available so far is compressed with the old state was initialized or reset, then the input available so far is
level and strategy using deflate(strm, Z_BLOCK). There are three approaches compressed with the old level and strategy using deflate(strm, Z_BLOCK).
for the compression levels 0, 1..3, and 4..9 respectively. The new level There are three approaches for the compression levels 0, 1..3, and 4..9
and strategy will take effect at the next call of deflate(). respectively. The new level and strategy will take effect at the next call
of deflate().
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
not have enough output space to complete, then the parameter change will not not have enough output space to complete, then the parameter change will not
@@ -865,9 +865,11 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
detection, or add 16 to decode only the gzip format (the zlib format will detection, or add 16 to decode only the gzip format (the zlib format will
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
below), inflate() will not automatically decode concatenated gzip streams. below), inflate() will *not* automatically decode concatenated gzip members.
inflate() will return Z_STREAM_END at the end of the gzip stream. The state inflate() will return Z_STREAM_END at the end of the gzip member. The state
would need to be reset to continue decoding a subsequent gzip stream. would need to be reset to continue decoding a subsequent gzip member. This
*must* be done if there is more data after a gzip member, in order for the
decompression to be compliant with the gzip standard (RFC 1952).
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
@@ -1302,14 +1304,14 @@ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/* /*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
Opens a gzip (.gz) file for reading or writing. The mode parameter is as Open the gzip (.gz) file at path for reading and decompressing, or
in fopen ("rb" or "wb") but can also include a compression level ("wb9") or compressing and writing. The mode parameter is as in fopen ("rb" or "wb")
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only but can also include a compression level ("wb9") or a strategy: 'f' for
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h",
for fixed code compression as in "wb9F". (See the description of 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression
deflateInit2 for more information about the strategy parameter.) 'T' will as in "wb9F". (See the description of deflateInit2 for more information
request transparent writing or appending with no compression and not using about the strategy parameter.) 'T' will request transparent writing or
the gzip format. appending with no compression and not using the gzip format.
"a" can be used instead of "w" to request that the gzip stream that will "a" can be used instead of "w" to request that the gzip stream that will
be written be appended to the file. "+" will result in an error, since be written be appended to the file. "+" will result in an error, since
@@ -1339,9 +1341,9 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
/* /*
gzdopen associates a gzFile with the file descriptor fd. File descriptors Associate a gzFile with the file descriptor fd. File descriptors are
are obtained from calls like open, dup, creat, pipe or fileno (if the file obtained from calls like open, dup, creat, pipe or fileno (if the file has
has been previously opened with fopen). The mode parameter is as in gzopen. been previously opened with fopen). The mode parameter is as in gzopen.
The next call of gzclose on the returned gzFile will also close the file The next call of gzclose on the returned gzFile will also close the file
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
@@ -1362,13 +1364,13 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
/* /*
Set the internal buffer size used by this library's functions. The Set the internal buffer size used by this library's functions for file to
default buffer size is 8192 bytes. This function must be called after size. The default buffer size is 8192 bytes. This function must be called
gzopen() or gzdopen(), and before any other calls that read or write the after gzopen() or gzdopen(), and before any other calls that read or write
file. The buffer memory allocation is always deferred to the first read or the file. The buffer memory allocation is always deferred to the first read
write. Three times that size in buffer space is allocated. A larger buffer or write. Three times that size in buffer space is allocated. A larger
size of, for example, 64K or 128K bytes will noticeably increase the speed buffer size of, for example, 64K or 128K bytes will noticeably increase the
of decompression (reading). speed of decompression (reading).
The new buffer size also affects the maximum length for gzprintf(). The new buffer size also affects the maximum length for gzprintf().
@@ -1378,9 +1380,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
/* /*
Dynamically update the compression level or strategy. See the description Dynamically update the compression level and strategy for file. See the
of deflateInit2 for the meaning of these parameters. Previously provided description of deflateInit2 for the meaning of these parameters. Previously
data is flushed before the parameter change. provided data is flushed before applying the parameter changes.
gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
opened for writing, Z_ERRNO if there is an error writing the flushed data, opened for writing, Z_ERRNO if there is an error writing the flushed data,
@@ -1389,7 +1391,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/* /*
Reads the given number of uncompressed bytes from the compressed file. If Read and decompress up to len uncompressed bytes from file into buf. If
the input file is not in gzip format, gzread copies the given number of the input file is not in gzip format, gzread copies the given number of
bytes into the buffer directly from the file. bytes into the buffer directly from the file.
@@ -1420,11 +1422,11 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
gzFile file)); gzFile file));
/* /*
Read up to nitems items of size size from file to buf, otherwise operating Read and decompress up to nitems items of size size from file into buf,
as gzread() does. This duplicates the interface of stdio's fread(), with otherwise operating as gzread() does. This duplicates the interface of
size_t request and return types. If the library defines size_t, then stdio's fread(), with size_t request and return types. If the library
z_size_t is identical to size_t. If not, then z_size_t is an unsigned defines size_t, then z_size_t is identical to size_t. If not, then z_size_t
integer type that can contain a pointer. is an unsigned integer type that can contain a pointer.
gzfread() returns the number of full items read of size size, or zero if gzfread() returns the number of full items read of size size, or zero if
the end of the file was reached and a full item could not be read, or if the end of the file was reached and a full item could not be read, or if
@@ -1443,18 +1445,16 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
file, reseting and retrying on end-of-file, when size is not 1. file, reseting and retrying on end-of-file, when size is not 1.
*/ */
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
voidpc buf, unsigned len));
/* /*
Writes the given number of uncompressed bytes into the compressed file. Compress and write the len uncompressed bytes at buf to file. gzwrite
gzwrite returns the number of uncompressed bytes written or 0 in case of returns the number of uncompressed bytes written or 0 in case of error.
error.
*/ */
ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
z_size_t nitems, gzFile file)); z_size_t nitems, gzFile file));
/* /*
gzfwrite() writes nitems items of size size from buf to file, duplicating Compress and write nitems items of size size from buf to file, duplicating
the interface of stdio's fwrite(), with size_t request and return types. If the interface of stdio's fwrite(), with size_t request and return types. If
the library defines size_t, then z_size_t is identical to size_t. If not, the library defines size_t, then z_size_t is identical to size_t. If not,
then z_size_t is an unsigned integer type that can contain a pointer. then z_size_t is an unsigned integer type that can contain a pointer.
@@ -1467,22 +1467,22 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/* /*
Converts, formats, and writes the arguments to the compressed file under Convert, format, compress, and write the arguments (...) to file under
control of the format string, as in fprintf. gzprintf returns the number of control of the string format, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written, or a negative zlib error code in case uncompressed bytes actually written, or a negative zlib error code in case
of error. The number of uncompressed bytes written is limited to 8191, or of error. The number of uncompressed bytes written is limited to 8191, or
one less than the buffer size given to gzbuffer(). The caller should assure one less than the buffer size given to gzbuffer(). The caller should assure
that this limit is not exceeded. If it is exceeded, then gzprintf() will that this limit is not exceeded. If it is exceeded, then gzprintf() will
return an error (0) with nothing written. In this case, there may also be a return an error (0) with nothing written. In this case, there may also be a
buffer overflow with unpredictable consequences, which is possible only if buffer overflow with unpredictable consequences, which is possible only if
zlib was compiled with the insecure functions sprintf() or vsprintf() zlib was compiled with the insecure functions sprintf() or vsprintf(),
because the secure snprintf() or vsnprintf() functions were not available. because the secure snprintf() or vsnprintf() functions were not available.
This can be determined using zlibCompileFlags(). This can be determined using zlibCompileFlags().
*/ */
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
/* /*
Writes the given null-terminated string to the compressed file, excluding Compress and write the given null-terminated string s to file, excluding
the terminating null character. the terminating null character.
gzputs returns the number of characters written, or -1 in case of error. gzputs returns the number of characters written, or -1 in case of error.
@@ -1490,11 +1490,12 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
/* /*
Reads bytes from the compressed file until len-1 characters are read, or a Read and decompress bytes from file into buf, until len-1 characters are
newline character is read and transferred to buf, or an end-of-file read, or until a newline character is read and transferred to buf, or an
condition is encountered. If any characters are read or if len == 1, the end-of-file condition is encountered. If any characters are read or if len
string is terminated with a null character. If no characters are read due is one, the string is terminated with a null character. If no characters
to an end-of-file or len < 1, then the buffer is left untouched. are read due to an end-of-file or len is less than one, then the buffer is
left untouched.
gzgets returns buf which is a null-terminated string, or it returns NULL gzgets returns buf which is a null-terminated string, or it returns NULL
for end-of-file or in case of error. If there was an error, the contents at for end-of-file or in case of error. If there was an error, the contents at
@@ -1503,13 +1504,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
/* /*
Writes c, converted to an unsigned char, into the compressed file. gzputc Compress and write c, converted to an unsigned char, into file. gzputc
returns the value that was written, or -1 in case of error. returns the value that was written, or -1 in case of error.
*/ */
ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/* /*
Reads one byte from the compressed file. gzgetc returns this byte or -1 Read and decompress one byte from file. gzgetc returns this byte or -1
in case of end of file or error. This is implemented as a macro for speed. in case of end of file or error. This is implemented as a macro for speed.
As such, it does not do all of the checking the other functions do. I.e. As such, it does not do all of the checking the other functions do. I.e.
it does not check to see if file is NULL, nor whether the structure file it does not check to see if file is NULL, nor whether the structure file
@@ -1518,8 +1519,8 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/* /*
Push one character back onto the stream to be read as the first character Push c back onto the stream for file to be read as the first character on
on the next read. At least one character of push-back is allowed. the next read. At least one character of push-back is always allowed.
gzungetc() returns the character pushed, or -1 on failure. gzungetc() will gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
fail if c is -1, and may fail if a character has been pushed but not read fail if c is -1, and may fail if a character has been pushed but not read
yet. If gzungetc is used immediately after gzopen or gzdopen, at least the yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
@@ -1530,9 +1531,9 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/* /*
Flushes all pending output into the compressed file. The parameter flush Flush all pending output to file. The parameter flush is as in the
is as in the deflate() function. The return value is the zlib error number deflate() function. The return value is the zlib error number (see function
(see function gzerror below). gzflush is only permitted when writing. gzerror below). gzflush is only permitted when writing.
If the flush parameter is Z_FINISH, the remaining data is written and the If the flush parameter is Z_FINISH, the remaining data is written and the
gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream is completed in the output. If gzwrite() is called again, a new
@@ -1547,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
z_off_t offset, int whence)); z_off_t offset, int whence));
Sets the starting position for the next gzread or gzwrite on the given Set the starting position to offset relative to whence for the next gzread
compressed file. The offset represents a number of bytes in the or gzwrite on file. The offset represents a number of bytes in the
uncompressed data stream. The whence parameter is defined as in lseek(2); uncompressed data stream. The whence parameter is defined as in lseek(2);
the value SEEK_END is not supported. the value SEEK_END is not supported.
@@ -1565,18 +1566,18 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
/* /*
Rewinds the given file. This function is supported only for reading. Rewind file. This function is supported only for reading.
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET).
*/ */
/* /*
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
Returns the starting position for the next gzread or gzwrite on the given Return the starting position for the next gzread or gzwrite on file.
compressed file. This position represents a number of bytes in the This position represents a number of bytes in the uncompressed data stream,
uncompressed data stream, and is zero when starting, even if appending or and is zero when starting, even if appending or reading a gzip stream from
reading a gzip stream from the middle of a file using gzdopen(). the middle of a file using gzdopen().
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
*/ */
@@ -1584,22 +1585,22 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
/* /*
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
Returns the current offset in the file being read or written. This offset Return the current compressed (actual) read or write offset of file. This
includes the count of bytes that precede the gzip stream, for example when offset includes the count of bytes that precede the gzip stream, for example
appending or when using gzdopen() for reading. When reading, the offset when appending or when using gzdopen() for reading. When reading, the
does not include as yet unused buffered input. This information can be used offset does not include as yet unused buffered input. This information can
for a progress indicator. On error, gzoffset() returns -1. be used for a progress indicator. On error, gzoffset() returns -1.
*/ */
ZEXTERN int ZEXPORT gzeof OF((gzFile file)); ZEXTERN int ZEXPORT gzeof OF((gzFile file));
/* /*
Returns true (1) if the end-of-file indicator has been set while reading, Return true (1) if the end-of-file indicator for file has been set while
false (0) otherwise. Note that the end-of-file indicator is set only if the reading, false (0) otherwise. Note that the end-of-file indicator is set
read tried to go past the end of the input, but came up short. Therefore, only if the read tried to go past the end of the input, but came up short.
just like feof(), gzeof() may return false even if there is no more data to Therefore, just like feof(), gzeof() may return false even if there is no
read, in the event that the last read request was for the exact number of more data to read, in the event that the last read request was for the exact
bytes remaining in the input file. This will happen if the input file size number of bytes remaining in the input file. This will happen if the input
is an exact multiple of the buffer size. file size is an exact multiple of the buffer size.
If gzeof() returns true, then the read functions will return no more data, If gzeof() returns true, then the read functions will return no more data,
unless the end-of-file indicator is reset by gzclearerr() and the input file unless the end-of-file indicator is reset by gzclearerr() and the input file
@@ -1608,7 +1609,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/* /*
Returns true (1) if file is being copied directly while reading, or false Return true (1) if file is being copied directly while reading, or false
(0) if file is a gzip stream being decompressed. (0) if file is a gzip stream being decompressed.
If the input file is empty, gzdirect() will return true, since the input If the input file is empty, gzdirect() will return true, since the input
@@ -1629,8 +1630,8 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
ZEXTERN int ZEXPORT gzclose OF((gzFile file)); ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/* /*
Flushes all pending output if necessary, closes the compressed file and Flush all pending output for file, if necessary, close file and
deallocates the (de)compression state. Note that once file is closed, you deallocate the (de)compression state. Note that once file is closed, you
cannot call gzerror with file, since its structures have been deallocated. cannot call gzerror with file, since its structures have been deallocated.
gzclose must not be called more than once on the same file, just as free gzclose must not be called more than once on the same file, just as free
must not be called more than once on the same allocation. must not be called more than once on the same allocation.
@@ -1654,10 +1655,10 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
/* /*
Returns the error message for the last error which occurred on the given Return the error message for the last error which occurred on file.
compressed file. errnum is set to zlib error number. If an error occurred errnum is set to zlib error number. If an error occurred in the file system
in the file system and not in the compression library, errnum is set to and not in the compression library, errnum is set to Z_ERRNO and the
Z_ERRNO and the application may consult errno to get the exact error code. application may consult errno to get the exact error code.
The application must not modify the returned string. Future calls to The application must not modify the returned string. Future calls to
this function may invalidate the previously returned string. If file is this function may invalidate the previously returned string. If file is
@@ -1670,7 +1671,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/* /*
Clears the error and end-of-file flags for file. This is analogous to the Clear the error and end-of-file flags for file. This is analogous to the
clearerr() function in stdio. This is useful for continuing to read a gzip clearerr() function in stdio. This is useful for continuing to read a gzip
file that is being written concurrently. file that is being written concurrently.
*/ */
@@ -1688,8 +1689,9 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/* /*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is Z_NULL, this function returns the return the updated checksum. An Adler-32 value is in the range of a 32-bit
required initial value for the checksum. unsigned integer. If buf is Z_NULL, this function returns the required
initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
much faster. much faster.
@@ -1722,12 +1724,13 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
negative, the result has no meaning or utility. negative, the result has no meaning or utility.
*/ */
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/* /*
Update a running CRC-32 with the bytes buf[0..len-1] and return the Update a running CRC-32 with the bytes buf[0..len-1] and return the
updated CRC-32. If buf is Z_NULL, this function returns the required updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
initial value for the crc. Pre- and post-conditioning (one's complement) is If buf is Z_NULL, this function returns the required initial value for the
performed within this function so it shouldn't be done by the application. crc. Pre- and post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the application.
Usage example: Usage example:
@@ -1739,7 +1742,7 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error(); if (crc != original_crc) error();
*/ */
ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
z_size_t len)); z_size_t len));
/* /*
Same as crc32(), but with a size_t length. Same as crc32(), but with a size_t length.
@@ -1755,6 +1758,20 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
len2. len2.
*/ */
/*
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
Return the operator corresponding to length len2, to be used with
crc32_combine_op().
*/
ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
/*
Give the same result as crc32_combine(), using op in place of len2. op is
is generated from len2 by crc32_combine_gen(). This will be faster than
crc32_combine() if the generated op is used more than once.
*/
/* various hacks, don't look :) */ /* various hacks, don't look :) */
@@ -1842,6 +1859,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
#endif #endif
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
@@ -1852,6 +1870,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
# define z_gzoffset z_gzoffset64 # define z_gzoffset z_gzoffset64
# define z_adler32_combine z_adler32_combine64 # define z_adler32_combine z_adler32_combine64
# define z_crc32_combine z_crc32_combine64 # define z_crc32_combine z_crc32_combine64
# define z_crc32_combine_gen z_crc32_combine_gen64
# else # else
# define gzopen gzopen64 # define gzopen gzopen64
# define gzseek gzseek64 # define gzseek gzseek64
@@ -1859,6 +1878,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
# define gzoffset gzoffset64 # define gzoffset gzoffset64
# define adler32_combine adler32_combine64 # define adler32_combine adler32_combine64
# define crc32_combine crc32_combine64 # define crc32_combine crc32_combine64
# define crc32_combine_gen crc32_combine_gen64
# endif # endif
# ifndef Z_LARGE64 # ifndef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
@@ -1867,6 +1887,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
# endif # endif
#else #else
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
@@ -1875,12 +1896,14 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
#endif #endif
#else /* Z_SOLO */ #else /* Z_SOLO */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
#endif /* !Z_SOLO */ #endif /* !Z_SOLO */
@@ -1893,7 +1916,7 @@ ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) #if defined(_WIN32) && !defined(Z_SOLO)
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode)); const char *mode));
#endif #endif
+6
View File
@@ -92,3 +92,9 @@ ZLIB_1.2.9 {
adler32_z; adler32_z;
crc32_z; crc32_z;
} ZLIB_1.2.7.1; } ZLIB_1.2.7.1;
ZLIB_1.2.12 {
crc32_combine_gen;
crc32_combine_gen64;
crc32_combine_op;
} ZLIB_1.2.9;
+2 -2
View File
@@ -136,8 +136,8 @@ const char * ZEXPORT zError(err)
return ERR_MSG(err); return ERR_MSG(err);
} }
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
/* The Microsoft C Run-Time Library for Windows CE doesn't have /* The older Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting. * errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used. * Its value is always 0 and should not be used.
*/ */
+12 -9
View File
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library /* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -29,10 +29,6 @@
# include <stdlib.h> # include <stdlib.h>
#endif #endif
#ifdef Z_SOLO
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
#endif
#ifndef local #ifndef local
# define local static # define local static
#endif #endif
@@ -46,6 +42,17 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; typedef unsigned long ulg;
#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (ULONG_MAX == 0xffffffffffffffff)
# define Z_U8 unsigned long
# elif (ULLONG_MAX == 0xffffffffffffffff)
# define Z_U8 unsigned long long
# elif (UINT_MAX == 0xffffffffffffffff)
# define Z_U8 unsigned
# endif
#endif
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */ /* (size given to avoid silly warnings with Visual C++) */
@@ -170,10 +177,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE) # if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */ # define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# else # else
# define fdopen(fd,type) _fdopen(fd,type) # define fdopen(fd,type) _fdopen(fd,type)
# endif # endif