Submit #3402 ยป zlib-1.3.1-to-1.3.2.patch
| zlib-1.3.2/ChangeLog 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
ChangeLog file for zlib
|
||
|
Changes in 1.3.2 (17 Feb 2026)
|
||
|
- Continued rewrite of CMake build [Vollstrecker]
|
||
|
- Various portability improvements
|
||
|
- Various github workflow additions and improvements
|
||
|
- Check for negative lengths in crc32_combine functions
|
||
|
- Copy only the initialized window contents in inflateCopy
|
||
|
- Prevent the use of insecure functions without an explicit request
|
||
|
- Add compressBound_z and deflateBound_z functions for large values
|
||
|
- Use atomics to build inflate fixed tables once
|
||
|
- Add definition of ZLIB_INSECURE to build tests with c89 and c94
|
||
|
- Add --undefined option to ./configure for UBSan checker
|
||
|
- Copy only the initialized deflate state in deflateCopy
|
||
|
- Zero inflate state on allocation
|
||
|
- Remove untgz from contrib
|
||
|
- Add _z versions of the compress and uncompress functions
|
||
|
- Vectorize the CRC-32 calculation on the s390x
|
||
|
- Set bit 11 of the zip header flags in minizip if UTF-8
|
||
|
- Update OS/400 support
|
||
|
- Add a test to configure to check for a working compiler
|
||
|
- Check for invalid NULL pointer inputs to zlib operations
|
||
|
- Add --mandir to ./configure to specify manual directory
|
||
|
- Add LICENSE.Info-Zip to contrib/minizip
|
||
|
- Remove vstudio projects in lieu of cmake-generated projects
|
||
|
- Replace strcpy() with memcpy() in contrib/minizip
|
||
|
Changes in 1.3.1.2 (8 Dec 2025)
|
||
|
- Improve portability to RISC OS
|
||
|
- Permit compiling contrib/minizip/unzip.c with decryption
|
||
|
- Enable build of shared library on AIX
|
||
|
- Make deflateBound() more conservative and handle Z_STREAM_END
|
||
|
- Add zipAlreadyThere() to minizip zip.c to help avoid duplicates
|
||
|
- Make z_off_t 64 bits by default
|
||
|
- Add deflateUsed() function to get the used bits in the last byte
|
||
|
- Avoid out-of-bounds pointer arithmetic in inflateCopy()
|
||
|
- Add Haiku to configure for proper LDSHARED settings
|
||
|
- Add Bazel targets
|
||
|
- Complete rewrite of CMake build [Vollstrecker]
|
||
|
- Clarify the use of errnum in gzerror()
|
||
|
- Note that gzseek() requests are deferred until the next operation
|
||
|
- Note the use of gzungetc() to run a deferred seek while reading
|
||
|
- Fix bug in inflatePrime() for 16-bit ints
|
||
|
- Add a "G" option to force gzip, disabling transparency in gzread()
|
||
|
- Improve the discrimination between trailing garbage and bad gzip
|
||
|
- Allow gzflush() to write empty gzip members
|
||
|
- Remove redundant frees of point list on error in examples/zran.c
|
||
|
- Clarify the use of inflateGetHeader()
|
||
|
- Update links to the RFCs
|
||
|
- Return all available uncompressed data on error in gzread.c
|
||
|
- Support non-blocking devices in the gz* routines
|
||
|
- Various other small improvements
|
||
|
Changes in 1.3.1 (22 Jan 2024)
|
||
|
- Reject overflows of zip header fields in minizip
|
||
|
- Fix bug in inflateSync() for data held in bit buffer
|
||
| zlib-1.3.2/LICENSE 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
Copyright notice:
|
||
|
(C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||
|
(C) 1995-2026 Jean-loup Gailly and Mark Adler
|
||
|
This software is provided 'as-is', without any express or implied
|
||
|
warranty. In no event will the authors be held liable for any damages
|
||
| zlib-1.3.2/README 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
ZLIB DATA COMPRESSION LIBRARY
|
||
|
zlib 1.3.1 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
|
||
|
(Request for Comments) 1950 to 1952 in the files
|
||
|
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||
|
rfc1952 (gzip format).
|
||
|
zlib 1.3.2 is a general purpose data compression library. All the code is
|
||
|
thread safe (though see the FAQ for caveats). The data format used by the zlib
|
||
|
library is described by RFCs (Request for Comments) 1950 to 1952 at
|
||
|
https://datatracker.ietf.org/doc/html/rfc1950 (zlib format), rfc1951 (deflate
|
||
|
format) and rfc1952 (gzip format).
|
||
|
All functions of the compression library are documented in the file zlib.h
|
||
|
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||
| ... | ... | |
|
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
||
|
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
||
|
http://zlib.net/ . Before reporting a problem, please check this site to
|
||
|
https://zlib.net/ . Before reporting a problem, please check this site to
|
||
|
verify that you have the latest version of zlib; otherwise get the latest
|
||
|
version and check whether the problem still exists or not.
|
||
|
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
|
||
|
PLEASE read the zlib FAQ https://zlib.net/zlib_faq.html before asking for help.
|
||
|
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
|
||
|
https://marknelson.us/posts/1997/01/01/zlib-engine.html .
|
||
|
https://zlib.net/nelson/ .
|
||
|
The changes made in version 1.3.1 are documented in the file ChangeLog.
|
||
|
The changes made in version 1.3.2 are documented in the file ChangeLog.
|
||
|
Unsupported third party contributions are provided in directory contrib/ .
|
||
| ... | ... | |
|
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
||
|
available in Python 1.5 and later versions, see
|
||
|
http://docs.python.org/library/zlib.html .
|
||
|
https://docs.python.org/3/library/zlib.html .
|
||
|
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
||
|
zlib is built into tcl: https://wiki.tcl-lang.org/page/zlib .
|
||
|
An experimental package to read and write files in .zip format, written on top
|
||
|
of zlib by Gilles Vollant <info@winimage.com>, is available in the
|
||
| ... | ... | |
|
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
|
||
|
other compilers. Use "make test" to check your compiler.
|
||
|
- gzdopen is not supported on RISCOS or BEOS.
|
||
|
- For PalmOs, see http://palmzlib.sourceforge.net/
|
||
|
- For PalmOs, see https://palmzlib.sourceforge.net/
|
||
|
Acknowledgments:
|
||
| ... | ... | |
|
Copyright notice:
|
||
|
(C) 1995-2024 Jean-loup Gailly and Mark Adler
|
||
|
(C) 1995-2026 Jean-loup Gailly and Mark Adler
|
||
|
This software is provided 'as-is', without any express or implied
|
||
|
warranty. In no event will the authors be held liable for any damages
|
||
| zlib-1.3.2/compress.c 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* compress.c -- compress a memory buffer
|
||
|
* Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
|
||
|
* Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
| ... | ... | |
|
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||
|
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||
|
Z_STREAM_ERROR if the level parameter is invalid.
|
||
|
The _z versions of the functions take size_t length arguments.
|
||
|
*/
|
||
|
int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||
|
uLong sourceLen, int level) {
|
||
|
int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source,
|
||
|
z_size_t sourceLen, int level) {
|
||
|
z_stream stream;
|
||
|
int err;
|
||
|
const uInt max = (uInt)-1;
|
||
|
uLong left;
|
||
|
z_size_t left;
|
||
|
if ((sourceLen > 0 && source == NULL) ||
|
||
|
destLen == NULL || (*destLen > 0 && dest == NULL))
|
||
|
return Z_STREAM_ERROR;
|
||
|
left = *destLen;
|
||
|
*destLen = 0;
|
||
| ... | ... | |
|
do {
|
||
|
if (stream.avail_out == 0) {
|
||
|
stream.avail_out = left > (uLong)max ? max : (uInt)left;
|
||
|
stream.avail_out = left > (z_size_t)max ? max : (uInt)left;
|
||
|
left -= stream.avail_out;
|
||
|
}
|
||
|
if (stream.avail_in == 0) {
|
||
|
stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
|
||
|
stream.avail_in = sourceLen > (z_size_t)max ? max :
|
||
|
(uInt)sourceLen;
|
||
|
sourceLen -= stream.avail_in;
|
||
|
}
|
||
|
err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
|
||
|
} while (err == Z_OK);
|
||
|
*destLen = stream.total_out;
|
||
|
*destLen = (z_size_t)(stream.next_out - dest);
|
||
|
deflateEnd(&stream);
|
||
|
return err == Z_STREAM_END ? Z_OK : err;
|
||
|
}
|
||
|
int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||
|
uLong sourceLen, int level) {
|
||
|
int ret;
|
||
|
z_size_t got = *destLen;
|
||
|
ret = compress2_z(dest, &got, source, sourceLen, level);
|
||
|
*destLen = (uLong)got;
|
||
|
return ret;
|
||
|
}
|
||
|
/* ===========================================================================
|
||
|
*/
|
||
|
int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source,
|
||
|
z_size_t sourceLen) {
|
||
|
return compress2_z(dest, destLen, source, sourceLen,
|
||
|
Z_DEFAULT_COMPRESSION);
|
||
|
}
|
||
|
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||
|
uLong sourceLen) {
|
||
|
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
|
||
| ... | ... | |
|
If the default memLevel or windowBits for deflateInit() is changed, then
|
||
|
this function needs to be updated.
|
||
|
*/
|
||
|
z_size_t ZEXPORT compressBound_z(z_size_t sourceLen) {
|
||
|
z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||
|
(sourceLen >> 25) + 13;
|
||
|
return bound < sourceLen ? (z_size_t)-1 : bound;
|
||
|
}
|
||
|
uLong ZEXPORT compressBound(uLong sourceLen) {
|
||
|
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||
|
(sourceLen >> 25) + 13;
|
||
|
z_size_t bound = compressBound_z(sourceLen);
|
||
|
return (uLong)bound != bound ? (uLong)-1 : (uLong)bound;
|
||
|
}
|
||
| zlib-1.3.2/crc32.c 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* crc32.c -- compute the CRC-32 of a data stream
|
||
|
* Copyright (C) 1995-2022 Mark Adler
|
||
|
* Copyright (C) 1995-2026 Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*
|
||
|
* This interleaved implementation of a CRC makes use of pipelined multiple
|
||
| ... | ... | |
|
# include <stdio.h>
|
||
|
# ifndef DYNAMIC_CRC_TABLE
|
||
|
# define DYNAMIC_CRC_TABLE
|
||
|
# endif /* !DYNAMIC_CRC_TABLE */
|
||
|
#endif /* MAKECRCH */
|
||
|
# endif
|
||
|
#endif
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
# define Z_ONCE
|
||
|
#endif
|
||
|
#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
|
||
|
#ifdef HAVE_S390X_VX
|
||
|
# include "contrib/crc32vx/crc32_vx_hooks.h"
|
||
|
#endif
|
||
|
/*
|
||
|
A CRC of a message is computed on N braids of words in the message, where
|
||
|
each word consists of W bytes (4 or 8). If N is 3, for example, then three
|
||
| ... | ... | |
|
#endif
|
||
|
/* If available, use the ARM processor CRC32 instruction. */
|
||
|
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
|
||
|
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \
|
||
|
defined(W) && W == 8
|
||
|
# define ARMCRC32
|
||
|
#endif
|
||
| ... | ... | |
|
Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
|
||
|
reflected. For speed, this requires that a not be zero.
|
||
|
*/
|
||
|
local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
|
||
|
z_crc_t m, p;
|
||
|
local uLong multmodp(uLong a, uLong b) {
|
||
|
uLong m, p;
|
||
|
m = (z_crc_t)1 << 31;
|
||
|
m = (uLong)1 << 31;
|
||
|
p = 0;
|
||
|
for (;;) {
|
||
|
if (a & m) {
|
||
| ... | ... | |
|
/*
|
||
|
Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
|
||
|
initialized.
|
||
|
initialized. n must not be negative.
|
||
|
*/
|
||
|
local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
|
||
|
z_crc_t p;
|
||
|
local uLong x2nmodp(z_off64_t n, unsigned k) {
|
||
|
uLong p;
|
||
|
p = (z_crc_t)1 << 31; /* x^0 == 1 */
|
||
|
p = (uLong)1 << 31; /* x^0 == 1 */
|
||
|
while (n) {
|
||
|
if (n & 1)
|
||
|
p = multmodp(x2n_table[k & 31], p);
|
||
| ... | ... | |
|
local void write_table64(FILE *, const z_word_t FAR *, int);
|
||
|
#endif /* MAKECRCH */
|
||
|
/*
|
||
|
Define a once() function depending on the availability of atomics. If this is
|
||
|
compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
|
||
|
multiple threads, and if atomics are not available, then get_crc_table() must
|
||
|
be called to initialize the tables and must return before any threads are
|
||
|
allowed to compute or combine CRCs.
|
||
|
*/
|
||
|
/* Definition of once functionality. */
|
||
|
typedef struct once_s once_t;
|
||
|
/* Check for the availability of atomics. */
|
||
|
#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
|
||
|
!defined(__STDC_NO_ATOMICS__)
|
||
|
#include <stdatomic.h>
|
||
|
/* Structure for once(), which must be initialized with ONCE_INIT. */
|
||
|
struct once_s {
|
||
|
atomic_flag begun;
|
||
|
atomic_int done;
|
||
|
};
|
||
|
#define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
|
||
|
/*
|
||
|
Run the provided init() function exactly once, even if multiple threads
|
||
|
invoke once() at the same time. The state must be a once_t initialized with
|
||
|
ONCE_INIT.
|
||
|
*/
|
||
|
local void once(once_t *state, void (*init)(void)) {
|
||
|
if (!atomic_load(&state->done)) {
|
||
|
if (atomic_flag_test_and_set(&state->begun))
|
||
|
while (!atomic_load(&state->done))
|
||
|
;
|
||
|
else {
|
||
|
init();
|
||
|
atomic_store(&state->done, 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#else /* no atomics */
|
||
|
/* Structure for once(), which must be initialized with ONCE_INIT. */
|
||
|
struct once_s {
|
||
|
volatile int begun;
|
||
|
volatile int done;
|
||
|
};
|
||
|
#define ONCE_INIT {0, 0}
|
||
|
/* Test and set. Alas, not atomic, but tries to minimize the period of
|
||
|
vulnerability. */
|
||
|
local int test_and_set(int volatile *flag) {
|
||
|
int was;
|
||
|
was = *flag;
|
||
|
*flag = 1;
|
||
|
return was;
|
||
|
}
|
||
|
/* Run the provided init() function once. This is not thread-safe. */
|
||
|
local void once(once_t *state, void (*init)(void)) {
|
||
|
if (!state->done) {
|
||
|
if (test_and_set(&state->begun))
|
||
|
while (!state->done)
|
||
|
;
|
||
|
else {
|
||
|
init();
|
||
|
state->done = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
/* State for once(). */
|
||
|
local once_t made = ONCE_INIT;
|
||
|
local z_once_t made = Z_ONCE_INIT;
|
||
|
/*
|
||
|
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||
| ... | ... | |
|
p = (z_crc_t)1 << 30; /* x^1 */
|
||
|
x2n_table[0] = p;
|
||
|
for (n = 1; n < 32; n++)
|
||
|
x2n_table[n] = p = multmodp(p, p);
|
||
|
x2n_table[n] = p = (z_crc_t)multmodp(p, p);
|
||
|
#ifdef W
|
||
|
/* initialize the braiding tables -- needs x2n_table[] */
|
||
| ... | ... | |
|
int k;
|
||
|
z_crc_t i, p, q;
|
||
|
for (k = 0; k < w; k++) {
|
||
|
p = x2nmodp((n * w + 3 - k) << 3, 0);
|
||
|
p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0);
|
||
|
ltl[k][0] = 0;
|
||
|
big[w - 1 - k][0] = 0;
|
||
|
for (i = 1; i < 256; i++) {
|
||
|
ltl[k][i] = q = multmodp(i << 24, p);
|
||
|
ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p);
|
||
|
big[w - 1 - k][i] = byte_swap(q);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
*/
|
||
|
const z_crc_t FAR * ZEXPORT get_crc_table(void) {
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
once(&made, make_crc_table);
|
||
|
z_once(&made, make_crc_table);
|
||
|
#endif /* DYNAMIC_CRC_TABLE */
|
||
|
return (const z_crc_t FAR *)crc_table;
|
||
|
}
|
||
| ... | ... | |
|
#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */
|
||
|
#define Z_BATCH_MIN 800 /* fewest words in a final batch */
|
||
|
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
|
||
|
z_size_t len) {
|
||
|
z_crc_t val;
|
||
|
uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) {
|
||
|
uLong val;
|
||
|
z_word_t crc1, crc2;
|
||
|
const z_word_t *word;
|
||
|
z_word_t val0, val1, val2;
|
||
| ... | ... | |
|
if (buf == Z_NULL) return 0;
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
once(&made, make_crc_table);
|
||
|
z_once(&made, make_crc_table);
|
||
|
#endif /* DYNAMIC_CRC_TABLE */
|
||
|
/* Pre-condition the CRC */
|
||
| ... | ... | |
|
}
|
||
|
word += 3 * last;
|
||
|
num -= 3 * last;
|
||
|
val = x2nmodp(last, 6);
|
||
|
val = x2nmodp((int)last, 6);
|
||
|
crc = multmodp(val, crc) ^ crc1;
|
||
|
crc = multmodp(val, crc) ^ crc2;
|
||
|
}
|
||
| ... | ... | |
|
#endif
|
||
|
/* ========================================================================= */
|
||
|
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
|
||
|
z_size_t len) {
|
||
|
uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) {
|
||
|
/* Return initial CRC, if requested. */
|
||
|
if (buf == Z_NULL) return 0;
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
once(&made, make_crc_table);
|
||
|
z_once(&made, make_crc_table);
|
||
|
#endif /* DYNAMIC_CRC_TABLE */
|
||
|
/* Pre-condition the CRC */
|
||
| ... | ... | |
|
#endif
|
||
|
/* ========================================================================= */
|
||
|
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
|
||
|
uInt len) {
|
||
|
uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) {
|
||
|
#ifdef HAVE_S390X_VX
|
||
|
return crc32_z_hook(crc, buf, len);
|
||
|
#endif
|
||
|
return crc32_z(crc, buf, len);
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
|
||
|
uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
|
||
|
if (len2 < 0)
|
||
|
return 0;
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
once(&made, make_crc_table);
|
||
|
z_once(&made, make_crc_table);
|
||
|
#endif /* DYNAMIC_CRC_TABLE */
|
||
|
return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
|
||
|
return x2nmodp(len2, 3);
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
|
||
|
return crc32_combine64(crc1, crc2, (z_off64_t)len2);
|
||
|
uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
|
||
|
return crc32_combine_gen64((z_off64_t)len2);
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
|
||
|
#ifdef DYNAMIC_CRC_TABLE
|
||
|
once(&made, make_crc_table);
|
||
|
#endif /* DYNAMIC_CRC_TABLE */
|
||
|
return x2nmodp(len2, 3);
|
||
|
uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
|
||
|
if (op == 0)
|
||
|
return 0;
|
||
|
return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff);
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
|
||
|
return crc32_combine_gen64((z_off64_t)len2);
|
||
|
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
|
||
|
return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2));
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
|
||
|
return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
|
||
|
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
|
||
|
return crc32_combine64(crc1, crc2, (z_off64_t)len2);
|
||
|
}
|
||
| zlib-1.3.2/deflate.c 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* deflate.c -- compress data using the deflation algorithm
|
||
|
* Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
|
||
|
* Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
| ... | ... | |
|
* REFERENCES
|
||
|
*
|
||
|
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
||
|
* Available in http://tools.ietf.org/html/rfc1951
|
||
|
* Available at https://datatracker.ietf.org/doc/html/rfc1951
|
||
|
*
|
||
|
* A description of the Rabin and Karp algorithm is given in the book
|
||
|
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
||
| ... | ... | |
|
#include "deflate.h"
|
||
|
const char deflate_copyright[] =
|
||
|
" deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler ";
|
||
|
" deflate 1.3.2 Copyright 1995-2026 Jean-loup Gailly and Mark Adler ";
|
||
|
/*
|
||
|
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
|
||
| ... | ... | |
|
#define CLEAR_HASH(s) \
|
||
|
do { \
|
||
|
s->head[s->hash_size - 1] = NIL; \
|
||
|
zmemzero((Bytef *)s->head, \
|
||
|
(unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
|
||
|
zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
|
||
|
s->slid = 0; \
|
||
|
} while (0)
|
||
|
/* ===========================================================================
|
||
| ... | ... | |
|
m = *--p;
|
||
|
*p = (Pos)(m >= wsize ? m - wsize : NIL);
|
||
|
} while (--n);
|
||
|
n = wsize;
|
||
|
#ifndef FASTEST
|
||
|
n = wsize;
|
||
|
p = &s->prev[n];
|
||
|
do {
|
||
|
m = *--p;
|
||
| ... | ... | |
|
*/
|
||
|
} while (--n);
|
||
|
#endif
|
||
|
s->slid = 1;
|
||
|
}
|
||
|
/* ===========================================================================
|
||
| ... | ... | |
|
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
||
|
/* Deal with !@#$% 64K limit: */
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable: 4127)
|
||
|
#endif
|
||
|
if (sizeof(int) <= 2) {
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning(pop)
|
||
|
#endif
|
||
|
if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
|
||
|
more = wsize;
|
||
| ... | ... | |
|
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
|
||
|
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
|
||
|
if (s == Z_NULL) return Z_MEM_ERROR;
|
||
|
zmemzero(s, sizeof(deflate_state));
|
||
|
strm->state = (struct internal_state FAR *)s;
|
||
|
s->strm = strm;
|
||
|
s->status = INIT_STATE; /* to pass state test in deflateReset() */
|
||
| ... | ... | |
|
/* ========================================================================= */
|
||
|
int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
|
||
|
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||
|
if (pending != Z_NULL)
|
||
|
*pending = strm->state->pending;
|
||
|
if (bits != Z_NULL)
|
||
|
*bits = strm->state->bi_valid;
|
||
|
if (pending != Z_NULL) {
|
||
|
*pending = (unsigned)strm->state->pending;
|
||
|
if (*pending != strm->state->pending) {
|
||
|
*pending = (unsigned)-1;
|
||
|
return Z_BUF_ERROR;
|
||
|
}
|
||
|
}
|
||
|
return Z_OK;
|
||
|
}
|
||
|
/* ========================================================================= */
|
||
|
int ZEXPORT deflateUsed(z_streamp strm, int *bits) {
|
||
|
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||
|
if (bits != Z_NULL)
|
||
|
*bits = strm->state->bi_used;
|
||
|
return Z_OK;
|
||
|
}
|
||
| ... | ... | |
|
*
|
||
|
* Shifts are used to approximate divisions, for speed.
|
||
|
*/
|
||
|
uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
|
||
|
z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) {
|
||
|
deflate_state *s;
|
||
|
uLong fixedlen, storelen, wraplen;
|
||
|
z_size_t fixedlen, storelen, wraplen, bound;
|
||
|
/* upper bound for fixed blocks with 9-bit literals and length 255
|
||
|
(memLevel == 2, which is the lowest that may not use stored blocks) --
|
||
|
~13% overhead plus a small constant */
|
||
|
fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) +
|
||
|
(sourceLen >> 9) + 4;
|
||
|
if (fixedlen < sourceLen)
|
||
|
fixedlen = (z_size_t)-1;
|
||
|
/* upper bound for stored blocks with length 127 (memLevel == 1) --
|
||
|
~4% overhead plus a small constant */
|
||
|
storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) +
|
||
|
(sourceLen >> 11) + 7;
|
||
|
if (storelen < sourceLen)
|
||
|
storelen = (z_size_t)-1;
|
||
|
/* if can't get parameters, return larger bound plus a zlib wrapper */
|
||
|
if (deflateStateCheck(strm))
|
||
|
return (fixedlen > storelen ? fixedlen : storelen) + 6;
|
||
|
/* if can't get parameters, return larger bound plus a wrapper */
|
||
|
if (deflateStateCheck(strm)) {
|
||
|
bound = fixedlen > storelen ? fixedlen : storelen;
|
||
|
return bound + 18 < bound ? (z_size_t)-1 : bound + 18;
|
||
|
}
|
||
|
/* compute wrapper length */
|
||
|
s = strm->state;
|
||
|
switch (s->wrap) {
|
||
|
switch (s->wrap < 0 ? -s->wrap : s->wrap) {
|
||
|
case 0: /* raw deflate */
|
||
|
wraplen = 0;
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
#endif
|
||
|
default: /* for compiler happiness */
|
||
|
wraplen = 6;
|
||
|
wraplen = 18;
|
||
|
}
|
||
|
/* if not default parameters, return one of the conservative bounds */
|
||
|
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
|
||
|
return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
|
||
|
wraplen;
|
||
|
if (s->w_bits != 15 || s->hash_bits != 8 + 7) {
|
||
|
bound = s->w_bits <= s->hash_bits && s->level ? fixedlen :
|
||
|
storelen;
|
||
|
return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen;
|
||
|
}
|
||
|
/* default settings: return tight bound for that case -- ~0.03% overhead
|
||
|
plus a small constant */
|
||
|
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||
|
(sourceLen >> 25) + 13 - 6 + wraplen;
|
||
|
bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||
|
(sourceLen >> 25) + 13 - 6 + wraplen;
|
||
|
return bound < sourceLen ? (z_size_t)-1 : bound;
|
||
|
}
|
||
|
uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
|
||
|
z_size_t bound = deflateBound_z(strm, sourceLen);
|
||
|
return (uLong)bound != bound ? (uLong)-1 : (uLong)bound;
|
||
|
}
|
||
|
/* =========================================================================
|
||
| ... | ... | |
|
deflate_state *s = strm->state;
|
||
|
_tr_flush_bits(s);
|
||
|
len = s->pending;
|
||
|
if (len > strm->avail_out) len = strm->avail_out;
|
||
|
len = s->pending > strm->avail_out ? strm->avail_out :
|
||
|
(unsigned)s->pending;
|
||
|
if (len == 0) return;
|
||
|
zmemcpy(strm->next_out, s->pending_out, len);
|
||
| ... | ... | |
|
#define HCRC_UPDATE(beg) \
|
||
|
do { \
|
||
|
if (s->gzhead->hcrc && s->pending > (beg)) \
|
||
|
strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
|
||
|
s->pending - (beg)); \
|
||
|
strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \
|
||
|
s->pending - (beg)); \
|
||
|
} while (0)
|
||
|
/* ========================================================================= */
|
||
| ... | ... | |
|
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
|
||
|
}
|
||
|
if (s->gzhead->hcrc)
|
||
|
strm->adler = crc32(strm->adler, s->pending_buf,
|
||
|
s->pending);
|
||
|
strm->adler = crc32_z(strm->adler, s->pending_buf,
|
||
|
s->pending);
|
||
|
s->gzindex = 0;
|
||
|
s->status = EXTRA_STATE;
|
||
|
}
|
||
| ... | ... | |
|
if (s->status == EXTRA_STATE) {
|
||
|
if (s->gzhead->extra != Z_NULL) {
|
||
|
ulg beg = s->pending; /* start of bytes to update crc */
|
||
|
uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
|
||
|
ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
|
||
|
while (s->pending + left > s->pending_buf_size) {
|
||
|
uInt copy = s->pending_buf_size - s->pending;
|
||
|
ulg copy = s->pending_buf_size - s->pending;
|
||
|
zmemcpy(s->pending_buf + s->pending,
|
||
|
s->gzhead->extra + s->gzindex, copy);
|
||
|
s->pending = s->pending_buf_size;
|
||
| ... | ... | |
|
ss = source->state;
|
||
|
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||
|
zmemcpy(dest, source, sizeof(z_stream));
|
||
|
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
||
|
if (ds == Z_NULL) return Z_MEM_ERROR;
|
||
|
zmemzero(ds, sizeof(deflate_state));
|
||
|
dest->state = (struct internal_state FAR *) ds;
|
||
|
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
||
|
zmemcpy(ds, ss, sizeof(deflate_state));
|
||
|
ds->strm = dest;
|
||
|
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||
| ... | ... | |
|
deflateEnd (dest);
|
||
|
return Z_MEM_ERROR;
|
||
|
}
|
||
|
/* following zmemcpy do not work for 16-bit MSDOS */
|
||
|
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
||
|
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
|
||
|
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
|
||
|
zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS);
|
||
|
/* following zmemcpy's do not work for 16-bit MSDOS */
|
||
|
zmemcpy(ds->window, ss->window, ss->high_water);
|
||
|
zmemcpy(ds->prev, ss->prev,
|
||
|
(ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size :
|
||
|
ss->strstart - ss->insert) * sizeof(Pos));
|
||
|
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
||
|
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||
|
zmemcpy(ds->pending_out, ss->pending_out, ss->pending);
|
||
|
#ifdef LIT_MEM
|
||
|
ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
|
||
|
ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
|
||
|
zmemcpy(ds->d_buf, ss->d_buf, ss->sym_next * sizeof(ush));
|
||
|
zmemcpy(ds->l_buf, ss->l_buf, ss->sym_next);
|
||
|
#else
|
||
|
ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
|
||
|
zmemcpy(ds->sym_buf, ss->sym_buf, ss->sym_next);
|
||
|
#endif
|
||
|
ds->l_desc.dyn_tree = ds->dyn_ltree;
|
||
| ... | ... | |
|
*/
|
||
|
local uInt longest_match(deflate_state *s, IPos cur_match) {
|
||
|
unsigned chain_length = s->max_chain_length;/* max hash chain length */
|
||
|
register Bytef *scan = s->window + s->strstart; /* current string */
|
||
|
register Bytef *match; /* matched string */
|
||
|
register int len; /* length of current match */
|
||
|
Bytef *scan = s->window + s->strstart; /* current string */
|
||
|
Bytef *match; /* matched string */
|
||
|
int len; /* length of current match */
|
||
|
int best_len = (int)s->prev_length; /* best match length so far */
|
||
|
int nice_match = s->nice_match; /* stop if match long enough */
|
||
|
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
|
||
| ... | ... | |
|
/* Compare two bytes at a time. Note: this is not always beneficial.
|
||
|
* Try with and without -DUNALIGNED_OK to check.
|
||
|
*/
|
||
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
|
||
|
register ush scan_start = *(ushf*)scan;
|
||
|
register ush scan_end = *(ushf*)(scan + best_len - 1);
|
||
|
Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
|
||
|
ush scan_start = *(ushf*)scan;
|
||
|
ush scan_end = *(ushf*)(scan + best_len - 1);
|
||
|
#else
|
||
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||
|
register Byte scan_end1 = scan[best_len - 1];
|
||
|
register Byte scan_end = scan[best_len];
|
||
|
Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||
|
Byte scan_end1 = scan[best_len - 1];
|
||
|
Byte scan_end = scan[best_len];
|
||
|
#endif
|
||
|
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
||
| ... | ... | |
|
* Optimized version for FASTEST only
|
||
|
*/
|
||
|
local uInt longest_match(deflate_state *s, IPos cur_match) {
|
||
|
register Bytef *scan = s->window + s->strstart; /* current string */
|
||
|
register Bytef *match; /* matched string */
|
||
|
register int len; /* length of current match */
|
||
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||
|
Bytef *scan = s->window + s->strstart; /* current string */
|
||
|
Bytef *match; /* matched string */
|
||
|
int len; /* length of current match */
|
||
|
Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||
|
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
||
|
* It is easy to get rid of this optimization if necessary.
|
||
| ... | ... | |
|
local void check_match(deflate_state *s, IPos start, IPos match, int length) {
|
||
|
/* check that the match is indeed a match */
|
||
|
Bytef *back = s->window + (int)match, *here = s->window + start;
|
||
|
IPos len = length;
|
||
|
IPos len = (IPos)length;
|
||
|
if (match == (IPos)-1) {
|
||
|
/* match starts one byte before the current window -- just compare the
|
||
|
subsequent length-1 bytes */
|
||
| ... | ... | |
|
* this is 32K. This can be as small as 507 bytes for memLevel == 1. For
|
||
|
* large input and output buffers, the stored block size will be larger.
|
||
|
*/
|
||
|
unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
|
||
|
unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size));
|
||
|
/* Copy as many min_block or larger stored blocks directly to next_out as
|
||
|
* possible. If flushing, copy the remaining available input to next_out as
|
||
|
* stored blocks, if there is enough space.
|
||
|
*/
|
||
|
unsigned len, left, have, last = 0;
|
||
|
int last = 0;
|
||
|
unsigned len, left, have;
|
||
|
unsigned used = s->strm->avail_in;
|
||
|
do {
|
||
|
/* Set len to the maximum size block that we can copy directly with the
|
||
| ... | ... | |
|
* would be copied from what's left in the window.
|
||
|
*/
|
||
|
len = MAX_STORED; /* maximum deflate stored block length */
|
||
|
have = (s->bi_valid + 42) >> 3; /* number of header bytes */
|
||
|
have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */
|
||
|
if (s->strm->avail_out < have) /* need room for header */
|
||
|
break;
|
||
|
/* maximum stored block length that will fit in avail_out: */
|
||
|
have = s->strm->avail_out - have;
|
||
|
left = s->strstart - s->block_start; /* bytes left in window */
|
||
|
left = (unsigned)(s->strstart - s->block_start); /* window bytes */
|
||
|
if (len > (ulg)left + s->strm->avail_in)
|
||
|
len = left + s->strm->avail_in; /* limit len to the input */
|
||
|
if (len > have)
|
||
| ... | ... | |
|
_tr_stored_block(s, (char *)0, 0L, last);
|
||
|
/* Replace the lengths in the dummy stored block with len. */
|
||
|
s->pending_buf[s->pending - 4] = len;
|
||
|
s->pending_buf[s->pending - 3] = len >> 8;
|
||
|
s->pending_buf[s->pending - 2] = ~len;
|
||
|
s->pending_buf[s->pending - 1] = ~len >> 8;
|
||
|
s->pending_buf[s->pending - 4] = (Bytef)len;
|
||
|
s->pending_buf[s->pending - 3] = (Bytef)(len >> 8);
|
||
|
s->pending_buf[s->pending - 2] = (Bytef)~len;
|
||
|
s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8);
|
||
|
/* Write the stored block header bytes. */
|
||
|
flush_pending(s->strm);
|
||
| ... | ... | |
|
s->high_water = s->strstart;
|
||
|
/* If the last block was written to next_out, then done. */
|
||
|
if (last)
|
||
|
if (last) {
|
||
|
s->bi_used = 8;
|
||
|
return finish_done;
|
||
|
}
|
||
|
/* If flushing and all input has been consumed, then done. */
|
||
|
if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
|
||
| ... | ... | |
|
return block_done;
|
||
|
/* Fill the window with any remaining input. */
|
||
|
have = s->window_size - s->strstart;
|
||
|
have = (unsigned)(s->window_size - s->strstart);
|
||
|
if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
|
||
|
/* Slide the window down. */
|
||
|
s->block_start -= s->w_size;
|
||
| ... | ... | |
|
* have enough input for a worthy block, or if flushing and there is enough
|
||
|
* room for the remaining input as a stored block in the pending buffer.
|
||
|
*/
|
||
|
have = (s->bi_valid + 42) >> 3; /* number of header bytes */
|
||
|
have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */
|
||
|
/* maximum stored block length that will fit in pending: */
|
||
|
have = MIN(s->pending_buf_size - have, MAX_STORED);
|
||
|
have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED);
|
||
|
min_block = MIN(have, s->w_size);
|
||
|
left = s->strstart - s->block_start;
|
||
|
left = (unsigned)(s->strstart - s->block_start);
|
||
|
if (left >= min_block ||
|
||
|
((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
|
||
|
s->strm->avail_in == 0 && left <= have)) {
|
||
| ... | ... | |
|
}
|
||
|
/* We've done all we can with the available input and output. */
|
||
|
if (last)
|
||
|
s->bi_used = 8;
|
||
|
return last ? finish_started : need_more;
|
||
|
}
|
||
| ... | ... | |
|
/* longest_match() sets match_start */
|
||
|
}
|
||
|
if (s->match_length >= MIN_MATCH) {
|
||
|
check_match(s, s->strstart, s->match_start, s->match_length);
|
||
|
check_match(s, s->strstart, s->match_start, (int)s->match_length);
|
||
|
_tr_tally_dist(s, s->strstart - s->match_start,
|
||
|
s->match_length - MIN_MATCH, bflush);
|
||
| ... | ... | |
|
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
|
||
|
/* Do not insert strings in hash table beyond this. */
|
||
|
check_match(s, s->strstart - 1, s->prev_match, s->prev_length);
|
||
|
check_match(s, s->strstart - 1, s->prev_match, (int)s->prev_length);
|
||
|
_tr_tally_dist(s, s->strstart - 1 - s->prev_match,
|
||
|
s->prev_length - MIN_MATCH, bflush);
|
||
| ... | ... | |
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||
|
if (s->match_length >= MIN_MATCH) {
|
||
|
check_match(s, s->strstart, s->strstart - 1, s->match_length);
|
||
|
check_match(s, s->strstart, s->strstart - 1, (int)s->match_length);
|
||
|
_tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
|
||
| zlib-1.3.2/deflate.h 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* deflate.h -- internal compression state
|
||
|
* Copyright (C) 1995-2024 Jean-loup Gailly
|
||
|
* Copyright (C) 1995-2026 Jean-loup Gailly
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
| ... | ... | |
|
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||
|
* are always zero.
|
||
|
*/
|
||
|
int bi_used;
|
||
|
/* Last number of used bits when going to a byte boundary.
|
||
|
*/
|
||
|
ulg high_water;
|
||
|
/* High water mark offset in window for initialized bytes -- bytes above
|
||
| ... | ... | |
|
* updated to the new high water mark.
|
||
|
*/
|
||
|
int slid;
|
||
|
/* True if the hash table has been slid since it was cleared. */
|
||
|
} FAR deflate_state;
|
||
|
/* Output a byte on the stream.
|
||
| zlib-1.3.2/gzguts.h 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* gzguts.h -- zlib internal header definitions for gz* operations
|
||
|
* Copyright (C) 2004-2024 Mark Adler
|
||
|
* Copyright (C) 2004-2026 Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
| ... | ... | |
|
# define ZLIB_INTERNAL
|
||
|
#endif
|
||
|
#if defined(_WIN32)
|
||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||
|
# define WIN32_LEAN_AND_MEAN
|
||
|
# endif
|
||
|
# ifndef _CRT_SECURE_NO_WARNINGS
|
||
|
# define _CRT_SECURE_NO_WARNINGS
|
||
|
# endif
|
||
|
# ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||
|
# define _CRT_NONSTDC_NO_DEPRECATE
|
||
|
# endif
|
||
|
#endif
|
||
|
#include <stdio.h>
|
||
|
#include "zlib.h"
|
||
|
#ifdef STDC
|
||
| ... | ... | |
|
# include <limits.h>
|
||
|
#endif
|
||
|
#ifndef _POSIX_SOURCE
|
||
|
# define _POSIX_SOURCE
|
||
|
#ifndef _POSIX_C_SOURCE
|
||
|
# define _POSIX_C_SOURCE 200112L
|
||
|
#endif
|
||
|
#include <fcntl.h>
|
||
| ... | ... | |
|
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
|
||
|
# include <io.h>
|
||
|
# include <sys/stat.h>
|
||
|
#endif
|
||
|
#if defined(_WIN32)
|
||
|
#if defined(_WIN32) && !defined(WIDECHAR)
|
||
|
# define WIDECHAR
|
||
|
#endif
|
||
|
#ifdef WINAPI_FAMILY
|
||
|
# define open _open
|
||
|
# define read _read
|
||
|
# define write _write
|
||
|
# define close _close
|
||
|
#endif
|
||
|
#ifdef NO_DEFLATE /* for compatibility with old definition */
|
||
|
# define NO_GZCOMPRESS
|
||
|
#endif
|
||
| ... | ... | |
|
#endif
|
||
|
#ifndef HAVE_VSNPRINTF
|
||
|
# ifdef MSDOS
|
||
|
# if !defined(NO_vsnprintf) && \
|
||
|
(defined(MSDOS) || defined(__TURBOC__) || defined(__SASC) || \
|
||
|
defined(VMS) || defined(__OS400) || defined(__MVS__))
|
||
|
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||
|
but for now we just assume it doesn't. */
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# ifdef __TURBOC__
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# ifdef WIN32
|
||
|
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||
|
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||
|
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||
|
# define vsnprintf _vsnprintf
|
||
|
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||
|
# ifndef vsnprintf
|
||
|
# define vsnprintf _vsnprintf
|
||
|
# endif
|
||
|
# endif
|
||
|
# endif
|
||
|
# ifdef __SASC
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# ifdef VMS
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# ifdef __OS400__
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# ifdef __MVS__
|
||
|
# define NO_vsnprintf
|
||
|
# elif !defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L
|
||
|
/* Otherwise if C89/90, assume no C99 snprintf() or vsnprintf() */
|
||
|
# ifndef NO_snprintf
|
||
|
# define NO_snprintf
|
||
|
# endif
|
||
|
# ifndef NO_vsnprintf
|
||
|
# define NO_vsnprintf
|
||
|
# endif
|
||
|
# endif
|
||
|
#endif
|
||
| ... | ... | |
|
unsigned char *out; /* output buffer (double-sized when reading) */
|
||
|
int direct; /* 0 if processing gzip, 1 if transparent */
|
||
|
/* just for reading */
|
||
|
int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */
|
||
|
int how; /* 0: get header, 1: copy, 2: decompress */
|
||
|
int again; /* true if EAGAIN or EWOULDBLOCK on last i/o */
|
||
|
z_off64_t start; /* where the gzip data started, for rewinding */
|
||
|
int eof; /* true if end of input file reached */
|
||
|
int past; /* true if read requested past end */
|
||
| ... | ... | |
|
int reset; /* true if a reset is pending after a Z_FINISH */
|
||
|
/* seek request */
|
||
|
z_off64_t skip; /* amount to skip (already rewound if backwards) */
|
||
|
int seek; /* true if seek request pending */
|
||
|
/* error information */
|
||
|
int err; /* error code */
|
||
|
char *msg; /* error message */
|
||
| zlib-1.3.2/gzlib.c 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||
|
* Copyright (C) 2004-2024 Mark Adler
|
||
|
* Copyright (C) 2004-2026 Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
|
#include "gzguts.h"
|
||
|
#if defined(_WIN32) && !defined(__BORLANDC__)
|
||
|
#if defined(__DJGPP__)
|
||
|
# define LSEEK llseek
|
||
|
#elif defined(_WIN32) && !defined(__BORLANDC__) && !defined(UNDER_CE)
|
||
|
# define LSEEK _lseeki64
|
||
|
#else
|
||
|
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||
|
#elif defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||
|
# define LSEEK lseek64
|
||
|
#else
|
||
|
# define LSEEK lseek
|
||
|
#endif
|
||
|
#endif
|
||
|
#if defined UNDER_CE
|
||
| ... | ... | |
|
msgbuf[chars] = 0;
|
||
|
}
|
||
|
wcstombs(buf, msgbuf, chars + 1);
|
||
|
wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */
|
||
|
LocalFree(msgbuf);
|
||
|
}
|
||
|
else {
|
||
| ... | ... | |
|
state->eof = 0; /* not at end of file */
|
||
|
state->past = 0; /* have not read past end yet */
|
||
|
state->how = LOOK; /* look for gzip header */
|
||
|
state->junk = -1; /* mark first member */
|
||
|
}
|
||
|
else /* for writing ... */
|
||
|
state->reset = 0; /* no deflateReset pending */
|
||
|
state->seek = 0; /* no seek request pending */
|
||
|
state->again = 0; /* no stalled i/o yet */
|
||
|
state->skip = 0; /* no seek request pending */
|
||
|
gz_error(state, Z_OK, NULL); /* clear error */
|
||
|
state->x.pos = 0; /* no uncompressed data yet */
|
||
|
state->strm.avail_in = 0; /* no input data yet */
|
||
| ... | ... | |
|
local gzFile gz_open(const void *path, int fd, const char *mode) {
|
||
|
gz_statep state;
|
||
|
z_size_t len;
|
||
|
int oflag;
|
||
|
#ifdef O_CLOEXEC
|
||
|
int cloexec = 0;
|
||
|
#endif
|
||
|
int oflag = 0;
|
||
|
#ifdef O_EXCL
|
||
|
int exclusive = 0;
|
||
|
#endif
|
||
|
/* check input */
|
||
|
if (path == NULL)
|
||
|
if (path == NULL || mode == NULL)
|
||
|
return NULL;
|
||
|
/* allocate gzFile structure to return */
|
||
| ... | ... | |
|
return NULL;
|
||
|
state->size = 0; /* no buffers allocated yet */
|
||
|
state->want = GZBUFSIZE; /* requested buffer size */
|
||
|
state->err = Z_OK; /* no error yet */
|
||
|
state->msg = NULL; /* no error message yet */
|
||
|
/* interpret mode */
|
||
| ... | ... | |
|
break;
|
||
|
#ifdef O_CLOEXEC
|
||
|
case 'e':
|
||
|
cloexec = 1;
|
||
|
oflag |= O_CLOEXEC;
|
||
|
break;
|
||
|
#endif
|
||
|
#ifdef O_EXCL
|
||
| ... | ... | |
|
case 'F':
|
||
|
state->strategy = Z_FIXED;
|
||
|
break;
|
||
|
case 'G':
|
||
|
state->direct = -1;
|
||
|
break;
|
||
|
#ifdef O_NONBLOCK
|
||
|
case 'N':
|
||
|
oflag |= O_NONBLOCK;
|
||
|
break;
|
||
|
#endif
|
||
|
case 'T':
|
||
|
state->direct = 1;
|
||
|
break;
|
||
| ... | ... | |
|
return NULL;
|
||
|
}
|
||
|
/* can't force transparent read */
|
||
|
/* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */
|
||
|
if (state->mode == GZ_READ) {
|
||
|
if (state->direct) {
|
||
|
if (state->direct == 1) {
|
||
|
/* can't force a transparent read */
|
||
|
free(state);
|
||
|
return NULL;
|
||
|
}
|
||
|
state->direct = 1; /* for empty file */
|
||
|
if (state->direct == 0)
|
||
|
/* default when reading is auto-detect of gzip vs. transparent --
|
||
|
start with a transparent assumption in case of an empty file */
|
||
|
state->direct = 1;
|
||
|
}
|
||
|
else if (state->direct == -1) {
|
||
|
/* "G" has no meaning when writing -- disallow it */
|
||
|
free(state);
|
||
|
return NULL;
|
||
|
}
|
||
|
/* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or
|
||
|
appending, direct == 0 for gzip, 1 for transparent (copy in to out) */
|
||
|
/* save the path name for error messages */
|
||
|
#ifdef WIDECHAR
|
||
|
if (fd == -2) {
|
||
|
if (fd == -2)
|
||
|
len = wcstombs(NULL, path, 0);
|
||
|
if (len == (z_size_t)-1)
|
||
|
len = 0;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
len = strlen((const char *)path);
|
||
| ... | ... | |
|
return NULL;
|
||
|
}
|
||
|
#ifdef WIDECHAR
|
||
|
if (fd == -2)
|
||
|
if (fd == -2) {
|
||
|
if (len)
|
||
|
wcstombs(state->path, path, len + 1);
|
||
|
else
|
||
|
*(state->path) = 0;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||
|
(void)snprintf(state->path, len + 1, "%s", (const char *)path);
|
||
|
#else
|
||
|
strcpy(state->path, path);
|
||
|
#endif
|
||
|
}
|
||
|
/* compute the flags for open() */
|
||
|
oflag =
|
||
|
oflag |=
|
||
|
#ifdef O_LARGEFILE
|
||
|
O_LARGEFILE |
|
||
|
#endif
|
||
|
#ifdef O_BINARY
|
||
|
O_BINARY |
|
||
|
#endif
|
||
|
#ifdef O_CLOEXEC
|
||
|
(cloexec ? O_CLOEXEC : 0) |
|
||
|
#endif
|
||
|
(state->mode == GZ_READ ?
|
||
|
O_RDONLY :
|
||
|
(O_WRONLY | O_CREAT |
|
||
| ... | ... | |
|
O_APPEND)));
|
||
|
/* open the file with the appropriate flags (or just use fd) */
|
||
|
state->fd = fd > -1 ? fd : (
|
||
|
if (fd == -1)
|
||
|
state->fd = open((const char *)path, oflag, 0666);
|
||
|
#ifdef WIDECHAR
|
||
|
fd == -2 ? _wopen(path, oflag, 0666) :
|
||
|
else if (fd == -2)
|
||
|
state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE);
|
||
|
#endif
|
||
|
open((const char *)path, oflag, 0666));
|
||
|
else {
|
||
|
#ifdef O_NONBLOCK
|
||
|
if (oflag & O_NONBLOCK)
|
||
|
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
|
||
|
#endif
|
||
|
#ifdef O_CLOEXEC
|
||
|
if (oflag & O_CLOEXEC)
|
||
|
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC);
|
||
|
#endif
|
||
|
state->fd = fd;
|
||
|
}
|
||
|
if (state->fd == -1) {
|
||
|
free(state->path);
|
||
|
free(state);
|
||
| ... | ... | |
|
/* normalize offset to a SEEK_CUR specification */
|
||
|
if (whence == SEEK_SET)
|
||
|
offset -= state->x.pos;
|
||
|
else if (state->seek)
|
||
|
offset += state->skip;
|
||
|
state->seek = 0;
|
||
|
else {
|
||
|
offset += state->past ? 0 : state->skip;
|
||
|
state->skip = 0;
|
||
|
}
|
||
|
/* if within raw area while reading, just go there */
|
||
|
if (state->mode == GZ_READ && state->how == COPY &&
|
||
| ... | ... | |
|
state->x.have = 0;
|
||
|
state->eof = 0;
|
||
|
state->past = 0;
|
||
|
state->seek = 0;
|
||
|
state->skip = 0;
|
||
|
gz_error(state, Z_OK, NULL);
|
||
|
state->strm.avail_in = 0;
|
||
|
state->x.pos += offset;
|
||
| ... | ... | |
|
}
|
||
|
/* request skip (if not zero) */
|
||
|
if (offset) {
|
||
|
state->seek = 1;
|
||
|
state->skip = offset;
|
||
|
}
|
||
|
state->skip = offset;
|
||
|
return state->x.pos + offset;
|
||
|
}
|
||
| ... | ... | |
|
return -1;
|
||
|
/* return position */
|
||
|
return state->x.pos + (state->seek ? state->skip : 0);
|
||
|
return state->x.pos + (state->past ? 0 : state->skip);
|
||
|
}
|
||
|
/* -- see zlib.h -- */
|
||
| ... | ... | |
|
}
|
||
|
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
|
||
|
if (err != Z_OK && err != Z_BUF_ERROR)
|
||
|
if (err != Z_OK && err != Z_BUF_ERROR && !state->again)
|
||
|
state->x.have = 0;
|
||
|
/* set error code, and if no message, then done */
|
||
| ... | ... | |
|
return INT_MAX;
|
||
|
#else
|
||
|
unsigned p = 1, q;
|
||
|
do {
|
||
|
q = p;
|
||
|
p <<= 1;
|
||
| zlib-1.3.2/gzread.c 2026-02-17 04:47:06.000000000 +0100 | ||
|---|---|---|
|
/* gzread.c -- zlib functions for reading gzip files
|
||
|
* Copyright (C) 2004-2017 Mark Adler
|
||
|
* Copyright (C) 2004-2026 Mark Adler
|
||
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||
|
*/
|
||
| ... | ... | |
|
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||
|
state->fd, and update state->eof, state->err, and state->msg as appropriate.
|
||
|
This function needs to loop on read(), since read() is not guaranteed to
|
||
|
read the number of bytes requested, depending on the type of descriptor. */
|
||
|
read the number of bytes requested, depending on the type of descriptor. It
|
||
|
also needs to loop to manage the fact that read() returns an int. If the
|
||
|
descriptor is non-blocking and read() returns with no data in order to avoid
|
||
|
blocking, then gz_load() will return 0 if some data has been read, or -1 if
|
||
|
no data has been read. Either way, state->again is set true to indicate a
|
||
|
non-blocking event. If errno is non-zero on return, then there was an error
|
||
|
signaled from read(). *have is set to the number of bytes read. */
|
||
|
local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
|
||
|
unsigned *have) {
|
||
|
int ret;
|
||
|
unsigned get, max = ((unsigned)-1 >> 2) + 1;
|
||
|
state->again = 0;
|
||
|
errno = 0;
|
||
|
*have = 0;
|
||
|
do {
|
||
|
get = len - *have;
|
||
|
if (get > max)
|
||
|
get = max;
|
||
|
ret = read(state->fd, buf + *have, get);
|
||
|
ret = (int)read(state->fd, buf + *have, get);
|
||
|
if (ret <= 0)
|
||
|
break;
|
||
|
*have += (unsigned)ret;
|
||
|
} while (*have < len);
|
||
|
if (ret < 0) {
|
||
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||
|
state->again = 1;
|
||
|
if (*have != 0)
|
||
|
return 0;
|
||
|
}
|
||
|
gz_error(state, Z_ERRNO, zstrerror());
|
||
|
return -1;
|
||
|
}
|
||
| ... | ... | |
|
if (strm->avail_in) { /* copy what's there to the start */
|
||
|
unsigned char *p = state->in;
|
||
|
unsigned const char *q = strm->next_in;
|
||
|
unsigned n = strm->avail_in;
|
||
|
do {
|
||
|
*p++ = *q++;
|
||
|
} while (--n);
|
||
|
if (q != p) {
|
||
|
unsigned n = strm->avail_in;
|
||
|
do {
|
||
|
*p++ = *q++;
|
||
|
} while (--n);
|
||
|
}
|
||
|
}
|
||
|
if (gz_load(state, state->in + strm->avail_in,
|
||
|
state->size - strm->avail_in, &got) == -1)
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
/* get at least the magic bytes in the input buffer */
|
||
|
if (strm->avail_in < 2) {
|
||
|
if (gz_avail(state) == -1)
|
||
|
return -1;
|
||
|
if (strm->avail_in == 0)
|
||
|
return 0;
|
||
|
}
|
||
|
/* look for gzip magic bytes -- if there, do gzip decoding (note: there is
|
||
|
a logical dilemma here when considering the case of a partially written
|
||
|
gzip file, to wit, if a single 31 byte is written, then we cannot tell
|
||
|
whether this is a single-byte file, or just a partially written gzip
|
||
|
file -- for here we assume that if a gzip file is being written, then
|
||
|
the header will be written in a single operation, so that reading a
|
||
|
single byte is sufficient indication that it is not a gzip file) */
|
||
|
if (strm->avail_in > 1 &&
|
||
|
strm->next_in[0] == 31 && strm->next_in[1] == 139) {
|
||
|
/* if transparent reading is disabled, which would only be at the start, or
|
||
|
if we're looking for a gzip member after the first one, which is not at
|
||
|
the start, then proceed directly to look for a gzip member next */
|
||
|
if (state->direct == -1 || state->junk == 0) {
|
||
|
inflateReset(strm);
|
||
|
state->how = GZIP;
|
||
|
state->junk = state->junk != -1;
|
||
|
state->direct = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
/* no gzip header -- if we were decoding gzip before, then this is trailing
|
||
|
garbage. Ignore the trailing garbage and finish. */
|
||
|
if (state->direct == 0) {
|
||
|
strm->avail_in = 0;
|
||
|
state->eof = 1;
|
||
|
state->x.have = 0;
|
||
|
/* otherwise we're at the start with auto-detect -- we check to see if the
|
||