Project

General

Profile

Submit #3402 ยป zlib-1.3.1-to-1.3.2.patch

pmjdebruijn, 02/25/2026 12:23 PM

View differences:

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
... This diff was truncated because it exceeds the maximum size that can be displayed.
    (1-1/1)