zlib 3.2.0 :

- aggiornamento alla nuova versione.
This commit is contained in:
Dario Sassi
2026-03-05 14:36:26 +01:00
parent 36de194207
commit 6f64e8124b
19 changed files with 1144 additions and 904 deletions
+35 -11
View File
@@ -1,5 +1,5 @@
/* 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
*/
@@ -18,13 +18,19 @@
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;
@@ -43,23 +49,36 @@ int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
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);
@@ -69,7 +88,12 @@ int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound(uLong sourceLen) {
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
(sourceLen >> 25) + 13;
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) {
z_size_t bound = compressBound_z(sourceLen);
return (uLong)bound != bound ? (uLong)-1 : (uLong)bound;
}
+50 -116
View File
@@ -1,5 +1,5 @@
/* 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
@@ -24,11 +24,18 @@
# 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
@@ -99,7 +106,8 @@
#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
@@ -152,10 +160,10 @@ local z_word_t byte_swap(z_word_t word) {
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) {
@@ -171,12 +179,12 @@ local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
/*
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);
@@ -204,83 +212,8 @@ local z_crc_t FAR crc_table[256];
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:
@@ -326,7 +259,7 @@ local void make_crc_table(void) {
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[] */
@@ -529,11 +462,11 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
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);
}
}
@@ -548,7 +481,7 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
*/
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;
}
@@ -572,9 +505,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table(void) {
#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;
@@ -585,7 +517,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
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 */
@@ -640,7 +572,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
}
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;
}
@@ -691,13 +623,12 @@ local z_word_t crc_word_big(z_word_t data) {
#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 */
@@ -1012,28 +943,19 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
#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) {
#ifdef DYNAMIC_CRC_TABLE
once(&made, make_crc_table);
#endif /* DYNAMIC_CRC_TABLE */
return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
}
/* ========================================================================= */
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_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 x2nmodp(len2, 3);
}
@@ -1045,5 +967,17 @@ uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
/* ========================================================================= */
uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
if (op == 0)
return 0;
return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff);
}
/* ========================================================================= */
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(uLong crc1, uLong crc2, z_off_t len2) {
return crc32_combine64(crc1, crc2, (z_off64_t)len2);
}
+143 -72
View File
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2023 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
*/
@@ -37,7 +37,7 @@
* 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.
@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
" deflate 1.3 Copyright 1995-2023 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
@@ -170,8 +170,8 @@ local const config configuration_table[10] = {
#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)
/* ===========================================================================
@@ -195,8 +195,8 @@ local void slide_hash(deflate_state *s) {
m = *--p;
*p = (Pos)(m >= wsize ? m - wsize : NIL);
} while (--n);
n = wsize;
#ifndef FASTEST
n = wsize;
p = &s->prev[n];
do {
m = *--p;
@@ -206,6 +206,7 @@ local void slide_hash(deflate_state *s) {
*/
} while (--n);
#endif
s->slid = 1;
}
/* ===========================================================================
@@ -259,7 +260,14 @@ local void fill_window(deflate_state *s) {
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;
@@ -431,6 +439,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
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() */
@@ -493,7 +502,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
* symbols from which it is being constructed.
*/
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS);
s->pending_buf_size = (ulg)s->lit_bufsize * 4;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
@@ -503,8 +512,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
deflateEnd (strm);
return Z_MEM_ERROR;
}
#ifdef LIT_MEM
s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
s->sym_end = s->lit_bufsize - 1;
#else
s->sym_buf = s->pending_buf + s->lit_bufsize;
s->sym_end = (s->lit_bufsize - 1) * 3;
#endif
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
@@ -706,10 +721,23 @@ int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {
/* ========================================================================= */
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;
}
@@ -720,9 +748,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
#ifdef LIT_MEM
if (bits < 0 || bits > 16 ||
(uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#else
if (bits < 0 || bits > 16 ||
s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#endif
do {
put = Buf_size - s->bi_valid;
if (put > bits)
@@ -819,28 +853,34 @@ int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy,
*
* 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;
@@ -870,18 +910,25 @@ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
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;
}
/* =========================================================================
@@ -905,8 +952,8 @@ local void flush_pending(z_streamp strm) {
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);
@@ -926,8 +973,8 @@ local void flush_pending(z_streamp strm) {
#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)
/* ========================================================================= */
@@ -1061,8 +1108,8 @@ int ZEXPORT deflate(z_streamp strm, int flush) {
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;
}
@@ -1070,9 +1117,9 @@ int ZEXPORT deflate(z_streamp strm, int flush) {
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;
@@ -1283,32 +1330,43 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
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));
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS);
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
ds->pending_buf == Z_NULL) {
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, (uInt)ds->pending_buf_size);
/* 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;
ds->d_desc.dyn_tree = ds->dyn_dtree;
@@ -1330,9 +1388,9 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
*/
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) ?
@@ -1347,13 +1405,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
/* 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.
@@ -1477,10 +1535,10 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
* 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.
@@ -1539,13 +1597,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
*/
local void check_match(deflate_state *s, IPos start, IPos match, int length) {
/* check that the match is indeed a match */
if (zmemcmp(s->window + match,
s->window + start, length) != EQUAL) {
fprintf(stderr, " start %u, match %u, length %d\n",
start, match, length);
Bytef *back = s->window + (int)match, *here = s->window + start;
IPos len = (IPos)length;
if (match == (IPos)-1) {
/* match starts one byte before the current window -- just compare the
subsequent length-1 bytes */
back++;
here++;
len--;
}
if (zmemcmp(back, here, len) != EQUAL) {
fprintf(stderr, " start %u, match %d, length %d\n",
start, (int)match, length);
do {
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
} while (--length != 0);
fprintf(stderr, "(%02x %02x)", *back++, *here++);
} while (--len != 0);
z_error("invalid match");
}
if (z_verbose > 1) {
@@ -1604,13 +1670,14 @@ local block_state deflate_stored(deflate_state *s, int flush) {
* 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
@@ -1618,12 +1685,12 @@ local block_state deflate_stored(deflate_state *s, int flush) {
* 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)
@@ -1646,10 +1713,10 @@ local block_state deflate_stored(deflate_state *s, int flush) {
_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);
@@ -1720,8 +1787,10 @@ local block_state deflate_stored(deflate_state *s, int flush) {
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 &&
@@ -1729,7 +1798,7 @@ local block_state deflate_stored(deflate_state *s, int flush) {
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;
@@ -1756,11 +1825,11 @@ local block_state deflate_stored(deflate_state *s, int flush) {
* 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)) {
@@ -1773,6 +1842,8 @@ local block_state deflate_stored(deflate_state *s, int flush) {
}
/* We've done all we can with the available input and output. */
if (last)
s->bi_used = 8;
return last ? finish_started : need_more;
}
@@ -1821,7 +1892,7 @@ local block_state deflate_fast(deflate_state *s, int flush) {
/* 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);
@@ -1943,7 +2014,7 @@ local block_state deflate_slow(deflate_state *s, int flush) {
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);
@@ -2051,7 +2122,7 @@ local block_state deflate_rle(deflate_state *s, int flush) {
/* 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);
+39 -2
View File
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-2018 Jean-loup Gailly
* Copyright (C) 1995-2026 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -23,6 +23,10 @@
# define GZIP
#endif
/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at
the cost of a larger memory footprint */
#define LIT_MEM
/* ===========================================================================
* Internal compression state.
*/
@@ -217,7 +221,14 @@ typedef struct internal_state {
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
#ifdef LIT_MEM
# define LIT_BUFS 5
ushf *d_buf; /* buffer for distances */
uchf *l_buf; /* buffer for literals/lengths */
#else
# define LIT_BUFS 4
uchf *sym_buf; /* buffer for distances and literals/lengths */
#endif
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
@@ -239,7 +250,7 @@ typedef struct internal_state {
* - I can't count above 4
*/
uInt sym_next; /* running index in sym_buf */
uInt sym_next; /* running index in symbol buffer */
uInt sym_end; /* symbol table full when sym_next reaches this */
ulg opt_len; /* bit length of current block with optimal trees */
@@ -260,6 +271,9 @@ typedef struct internal_state {
/* 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
@@ -268,6 +282,9 @@ typedef struct internal_state {
* 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.
@@ -318,6 +335,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
extern const uch ZLIB_INTERNAL _dist_code[];
#endif
#ifdef LIT_MEM
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->sym_next] = 0; \
s->l_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \
ush dist = (ush)(distance); \
s->d_buf[s->sym_next] = dist; \
s->l_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#else
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->sym_buf[s->sym_next++] = 0; \
@@ -337,6 +373,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#endif
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
+34 -36
View File
@@ -1,5 +1,5 @@
/* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004-2019 Mark Adler
* Copyright (C) 2004-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -17,6 +17,18 @@
# 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
@@ -25,8 +37,8 @@
# include <limits.h>
#endif
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE
#ifndef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200112L
#endif
#include <fcntl.h>
@@ -36,19 +48,13 @@
#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
@@ -72,33 +78,28 @@
#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
@@ -182,7 +183,9 @@ typedef struct {
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 */
@@ -192,7 +195,6 @@ typedef struct {
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 */
@@ -210,9 +212,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error);
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
value -- needed when comparing unsigned to z_off64_t, which is signed
(possible z_off64_t types off_t, off64_t, and long are all signed) */
#ifdef INT_MAX
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
#else
unsigned ZLIB_INTERNAL gz_intmax(void);
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
#endif
#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+69 -42
View File
@@ -1,19 +1,19 @@
/* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004-2019 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
@@ -52,7 +52,7 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
msgbuf[chars] = 0;
}
wcstombs(buf, msgbuf, chars + 1);
wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */
LocalFree(msgbuf);
}
else {
@@ -72,10 +72,12 @@ local void gz_reset(gz_statep state) {
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 */
@@ -85,16 +87,13 @@ local void gz_reset(gz_statep state) {
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 */
@@ -103,6 +102,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
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 */
@@ -133,7 +133,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
break;
#ifdef O_CLOEXEC
case 'e':
cloexec = 1;
oflag |= O_CLOEXEC;
break;
#endif
#ifdef O_EXCL
@@ -153,6 +153,14 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
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;
@@ -168,22 +176,30 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
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);
@@ -193,29 +209,29 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
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 :
@@ -228,11 +244,23 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
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);
@@ -359,9 +387,10 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
/* 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 &&
@@ -372,7 +401,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
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;
@@ -401,10 +430,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
}
/* request skip (if not zero) */
if (offset) {
state->seek = 1;
state->skip = offset;
}
state->skip = offset;
return state->x.pos + offset;
}
@@ -428,7 +454,7 @@ z_off64_t ZEXPORT gztell64(gzFile file) {
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 -- */
@@ -535,7 +561,7 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
}
/* 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 */
@@ -563,20 +589,21 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
#endif
}
#ifndef INT_MAX
/* portably return maximum value for an int (when limits.h presumed not
available) -- we need to do this to cover cases where 2's complement not
used, since C standard permits 1's complement and sign-bit representations,
otherwise we could just use ((unsigned)-1) >> 1 */
unsigned ZLIB_INTERNAL gz_intmax(void) {
unsigned p, q;
#ifdef INT_MAX
return INT_MAX;
#else
unsigned p = 1, q;
p = 1;
do {
q = p;
p <<= 1;
p++;
} while (p > q);
return q >> 1;
}
#endif
}
+190 -124
View File
@@ -1,5 +1,5 @@
/* 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
*/
@@ -8,23 +8,36 @@
/* 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;
}
@@ -50,10 +63,14 @@ local int gz_avail(gz_statep state) {
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)
@@ -104,39 +121,44 @@ local int gz_look(gz_statep state) {
}
}
/* 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
first four bytes could be gzip header in order to decide whether or not
this will be a transparent read */
/* load any header bytes into the input buffer -- if the input is empty,
then it's not an error as this is a transparent read of zero bytes */
if (gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0 || (state->again && strm->avail_in < 4))
/* if non-blocking input stalled before getting four bytes, then
return and wait until a later call has accumulated enough */
return 0;
/* see if this is (likely) gzip input -- if the first four bytes are
consistent with a gzip header, then go look for the first gzip member,
otherwise proceed to copy the input transparently */
if (strm->avail_in > 3 &&
strm->next_in[0] == 31 && strm->next_in[1] == 139 &&
strm->next_in[2] == 8 && strm->next_in[3] < 32) {
inflateReset(strm);
state->how = GZIP;
state->junk = 1;
state->direct = 0;
return 0;
}
/* doing raw i/o, copy any leftover input to output -- this assumes that
/* doing raw i/o: copy any leftover input to output -- this assumes that
the output buffer is larger than the input buffer, which also assures
space for gzungetc() */
state->x.next = state->out;
@@ -144,15 +166,17 @@ local int gz_look(gz_statep state) {
state->x.have = strm->avail_in;
strm->avail_in = 0;
state->how = COPY;
state->direct = 1;
return 0;
}
/* Decompress from input to the provided next_out and avail_out in the state.
On return, state->x.have and state->x.next point to the just decompressed
data. If the gzip stream completes, state->how is reset to LOOK to look for
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
on success, -1 on failure. */
data. If the gzip stream completes, state->how is reset to LOOK to look for
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
on success, -1 on failure. If EOF is reached when looking for more input to
complete the gzip member, then an unexpected end of file error is raised.
If there is no more input, but state->again is true, then EOF has not been
reached, and no error is raised. */
local int gz_decomp(gz_statep state) {
int ret = Z_OK;
unsigned had;
@@ -162,28 +186,41 @@ local int gz_decomp(gz_statep state) {
had = strm->avail_out;
do {
/* get more input for inflate() */
if (strm->avail_in == 0 && gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0 && gz_avail(state) == -1) {
ret = state->err;
break;
}
if (strm->avail_in == 0) {
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
if (!state->again)
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
break;
}
/* decompress and handle errors */
ret = inflate(strm, Z_NO_FLUSH);
if (strm->avail_out < had)
/* any decompressed data marks this as a real gzip stream */
state->junk = 0;
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
gz_error(state, Z_STREAM_ERROR,
"internal error: inflate stream corrupt");
return -1;
break;
}
if (ret == Z_MEM_ERROR) {
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
break;
}
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
if (state->junk == 1) { /* trailing garbage is ok */
strm->avail_in = 0;
state->eof = 1;
state->how = LOOK;
ret = Z_OK;
break;
}
gz_error(state, Z_DATA_ERROR,
strm->msg == NULL ? "compressed data error" : strm->msg);
return -1;
break;
}
} while (strm->avail_out && ret != Z_STREAM_END);
@@ -192,11 +229,14 @@ local int gz_decomp(gz_statep state) {
state->x.next = strm->next_out - state->x.have;
/* if the gzip stream completed successfully, look for another */
if (ret == Z_STREAM_END)
if (ret == Z_STREAM_END) {
state->junk = 0;
state->how = LOOK;
return 0;
}
/* good decompression */
return 0;
/* return decompression status */
return ret != Z_OK ? -1 : 0;
}
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
@@ -227,25 +267,31 @@ local int gz_fetch(gz_statep state) {
strm->next_out = state->out;
if (gz_decomp(state) == -1)
return -1;
break;
default:
gz_error(state, Z_STREAM_ERROR, "state corrupt");
return -1;
}
} while (state->x.have == 0 && (!state->eof || strm->avail_in));
return 0;
}
/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
local int gz_skip(gz_statep state, z_off64_t len) {
/* Skip state->skip (> 0) uncompressed bytes of output. Return -1 on error, 0
on success. */
local int gz_skip(gz_statep state) {
unsigned n;
/* skip over len bytes or reach end-of-file, whichever comes first */
while (len)
do {
/* skip over whatever is in output buffer */
if (state->x.have) {
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
(unsigned)len : state->x.have;
n = GT_OFF(state->x.have) ||
(z_off64_t)state->x.have > state->skip ?
(unsigned)state->skip : state->x.have;
state->x.have -= n;
state->x.next += n;
state->x.pos += n;
len -= n;
state->skip -= n;
}
/* output buffer empty -- return if we're at the end of the input */
@@ -258,30 +304,32 @@ local int gz_skip(gz_statep state, z_off64_t len) {
if (gz_fetch(state) == -1)
return -1;
}
} while (state->skip);
return 0;
}
/* Read len bytes into buf from file, or less than len up to the end of the
input. Return the number of bytes read. If zero is returned, either the
end of file was reached, or there was an error. state->err must be
consulted in that case to determine which. */
input. Return the number of bytes read. If zero is returned, either the end
of file was reached, or there was an error. state->err must be consulted in
that case to determine which. If there was an error, but some uncompressed
bytes were read before the error, then that count is returned. The error is
still recorded, and so is deferred until the next call. */
local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
z_size_t got;
unsigned n;
int err;
/* if len is zero, avoid unnecessary operations */
if (len == 0)
return 0;
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return 0;
}
if (state->skip && gz_skip(state) == -1)
return 0;
/* get len bytes to buf, or less than len if at the end */
got = 0;
err = 0;
do {
/* set n to the maximum amount of len that fits in an unsigned int */
n = (unsigned)-1;
@@ -295,37 +343,36 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
memcpy(buf, state->x.next, n);
state->x.next += n;
state->x.have -= n;
if (state->err != Z_OK)
/* caught deferred error from gz_fetch() */
err = -1;
}
/* output buffer empty -- return if we're at the end of the input */
else if (state->eof && state->strm.avail_in == 0) {
state->past = 1; /* tried to read past end */
else if (state->eof && state->strm.avail_in == 0)
break;
}
/* need output data -- for small len or new stream load up our output
buffer */
buffer, so that gzgetc() can be fast */
else if (state->how == LOOK || n < (state->size << 1)) {
/* get more output, looking for header if required */
if (gz_fetch(state) == -1)
return 0;
if (gz_fetch(state) == -1 && state->x.have == 0)
/* if state->x.have != 0, error will be caught after copy */
err = -1;
continue; /* no progress yet -- go back to copy above */
/* the copy above assures that we will leave with space in the
output buffer, allowing at least one gzungetc() to succeed */
}
/* large len -- read directly into user buffer */
else if (state->how == COPY) { /* read directly */
if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
return 0;
}
else if (state->how == COPY) /* read directly */
err = gz_load(state, (unsigned char *)buf, n, &n);
/* large len -- decompress directly into user buffer */
else { /* state->how == GZIP */
state->strm.avail_out = n;
state->strm.next_out = (unsigned char *)buf;
if (gz_decomp(state) == -1)
return 0;
err = gz_decomp(state);
n = state->x.have;
state->x.have = 0;
}
@@ -335,7 +382,11 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
buf = (char *)buf + n;
got += n;
state->x.pos += n;
} while (len);
} while (len && !err);
/* note read past eof */
if (len && state->eof)
state->past = 1;
/* return number of bytes read into user buffer */
return got;
@@ -345,16 +396,18 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
gz_statep state;
/* get internal structure */
/* get internal structure and check that it's for reading */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
if (state->mode != GZ_READ)
return -1;
/* check that there was no (serious) error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
return -1;
gz_error(state, Z_OK, NULL);
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids a flaw in the interface) */
if ((int)len < 0) {
@@ -366,28 +419,40 @@ int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
len = (unsigned)gz_read(state, buf, len);
/* check for an error */
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
if (len == 0) {
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
if (state->again) {
/* non-blocking input stalled after some input was read, but no
uncompressed bytes were produced -- let the application know
this isn't EOF */
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
}
/* return the number of bytes read (this is assured to fit in an int) */
/* return the number of bytes read */
return (int)len;
}
/* -- see zlib.h -- */
z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) {
z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
gzFile file) {
z_size_t len;
gz_statep state;
/* get internal structure */
/* get internal structure and check that it's for reading */
if (file == NULL)
return 0;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
if (state->mode != GZ_READ)
return 0;
/* check that there was no (serious) error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
return 0;
gz_error(state, Z_OK, NULL);
/* compute bytes to read -- error on overflow */
len = nitems * size;
if (size && len / size != nitems) {
@@ -409,16 +474,18 @@ int ZEXPORT gzgetc(gzFile file) {
unsigned char buf[1];
gz_statep state;
/* get internal structure */
/* get internal structure and check that it's for reading */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
if (state->mode != GZ_READ)
return -1;
/* check that there was no (serious) error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
return -1;
gz_error(state, Z_OK, NULL);
/* try output buffer (no need to check for skip request) */
if (state->x.have) {
state->x.have--;
@@ -438,26 +505,25 @@ int ZEXPORT gzgetc_(gzFile file) {
int ZEXPORT gzungetc(int c, gzFile file) {
gz_statep state;
/* get internal structure */
/* get internal structure and check that it's for reading */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* in case this was just opened, set up the input buffer */
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
(void)gz_look(state);
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
if (state->mode != GZ_READ)
return -1;
/* in case this was just opened, set up the input buffer */
if (state->how == LOOK && state->x.have == 0)
(void)gz_look(state);
/* check that there was no (serious) error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
return -1;
gz_error(state, Z_OK, NULL);
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return -1;
}
if (state->skip && gz_skip(state) == -1)
return -1;
/* can't push EOF */
if (c < 0)
@@ -483,6 +549,7 @@ int ZEXPORT gzungetc(int c, gzFile file) {
if (state->x.next == state->out) {
unsigned char *src = state->out + state->x.have;
unsigned char *dest = state->out + (state->size << 1);
while (src > state->out)
*--dest = *--src;
state->x.next = dest;
@@ -502,32 +569,31 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
unsigned char *eol;
gz_statep state;
/* check parameters and get internal structure */
/* check parameters, get internal structure, and check that it's for
reading */
if (file == NULL || buf == NULL || len < 1)
return NULL;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
if (state->mode != GZ_READ)
return NULL;
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return NULL;
}
/* check that there was no (serious) error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
return NULL;
gz_error(state, Z_OK, NULL);
/* copy output bytes up to new line or len - 1, whichever comes first --
append a terminating zero to the string (we don't check for a zero in
the contents, let the user worry about that) */
/* process a skip request */
if (state->skip && gz_skip(state) == -1)
return NULL;
/* copy output up to a new line, len-1 bytes, or there is no more output,
whichever comes first */
str = buf;
left = (unsigned)len - 1;
if (left) do {
/* assure that something is in the output buffer */
if (state->x.have == 0 && gz_fetch(state) == -1)
return NULL; /* error */
break; /* error */
if (state->x.have == 0) { /* end of file */
state->past = 1; /* read past end */
break; /* return what we have */
@@ -548,7 +614,9 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
buf += n;
} while (left && eol == NULL);
/* return terminated string, or if nothing, end of file */
/* append a terminating zero to the string (we don't check for a zero in
the contents, let the user worry about that) -- return the terminated
string, or if nothing was read, NULL */
if (buf == str)
return NULL;
buf[0] = 0;
@@ -570,7 +638,7 @@ int ZEXPORT gzdirect(gzFile file) {
(void)gz_look(state);
/* return 1 if transparent, 0 if processing a gzip stream */
return state->direct;
return state->direct == 1;
}
/* -- see zlib.h -- */
@@ -578,12 +646,10 @@ int ZEXPORT gzclose_r(gzFile file) {
int ret, err;
gz_statep state;
/* get internal structure */
/* get internal structure and check that it's for reading */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
/* check that we're reading */
if (state->mode != GZ_READ)
return Z_STREAM_ERROR;
+168 -99
View File
@@ -1,5 +1,5 @@
/* gzwrite.c -- zlib functions for writing gzip files
* Copyright (C) 2004-2019 Mark Adler
* Copyright (C) 2004-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -74,9 +74,13 @@ local int gz_comp(gz_statep state, int flush) {
/* write directly if requested */
if (state->direct) {
while (strm->avail_in) {
errno = 0;
state->again = 0;
put = strm->avail_in > max ? max : strm->avail_in;
writ = write(state->fd, strm->next_in, put);
writ = (int)write(state->fd, strm->next_in, put);
if (writ < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
state->again = 1;
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
@@ -88,8 +92,9 @@ local int gz_comp(gz_statep state, int flush) {
/* check for a pending reset */
if (state->reset) {
/* don't start a new gzip member unless there is data to write */
if (strm->avail_in == 0)
/* don't start a new gzip member unless there is data to write and
we're not flushing */
if (strm->avail_in == 0 && flush == Z_NO_FLUSH)
return 0;
deflateReset(strm);
state->reset = 0;
@@ -103,10 +108,14 @@ local int gz_comp(gz_statep state, int flush) {
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
(flush != Z_FINISH || ret == Z_STREAM_END))) {
while (strm->next_out > state->x.next) {
errno = 0;
state->again = 0;
put = strm->next_out - state->x.next > (int)max ? max :
(unsigned)(strm->next_out - state->x.next);
writ = write(state->fd, state->x.next, put);
writ = (int)write(state->fd, state->x.next, put);
if (writ < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
state->again = 1;
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
@@ -138,10 +147,12 @@ local int gz_comp(gz_statep state, int flush) {
return 0;
}
/* Compress len zeros to output. Return -1 on a write error or memory
allocation failure by gz_comp(), or 0 on success. */
local int gz_zero(gz_statep state, z_off64_t len) {
int first;
/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or
memory allocation failure by gz_comp(), or 0 on success. state->skip is
updated with the number of successfully written zeros, in case there is a
stall on a non-blocking write destination. */
local int gz_zero(gz_statep state) {
int first, ret;
unsigned n;
z_streamp strm = &(state->strm);
@@ -149,29 +160,34 @@ local int gz_zero(gz_statep state, z_off64_t len) {
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
return -1;
/* compress len zeros (len guaranteed > 0) */
/* compress state->skip zeros */
first = 1;
while (len) {
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
(unsigned)len : state->size;
do {
n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ?
(unsigned)state->skip : state->size;
if (first) {
memset(state->in, 0, n);
first = 0;
}
strm->avail_in = n;
strm->next_in = state->in;
ret = gz_comp(state, Z_NO_FLUSH);
n -= strm->avail_in;
state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
state->skip -= n;
if (ret == -1)
return -1;
len -= n;
}
} while (state->skip);
return 0;
}
/* Write len bytes from buf to file. Return the number of bytes written. If
the returned value is less than len, then there was an error. */
the returned value is less than len, then there was an error. If the error
was a non-blocking stall, then the number of bytes consumed is returned.
For any other error, 0 is returned. */
local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
z_size_t put = len;
int ret;
/* if len is zero, avoid unnecessary operations */
if (len == 0)
@@ -182,16 +198,13 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
return 0;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return 0;
}
if (state->skip && gz_zero(state) == -1)
return 0;
/* for small len, copy to input buffer, otherwise compress directly */
if (len < state->size) {
/* copy to input buffer, compress when full */
do {
for (;;) {
unsigned have, copy;
if (state->strm.avail_in == 0)
@@ -206,9 +219,11 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
state->x.pos += copy;
buf = (const char *)buf + copy;
len -= copy;
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
} while (len);
if (len == 0)
break;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->again ? put - len : 0;
}
}
else {
/* consume whatever's left in the input buffer */
@@ -219,13 +234,16 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
state->strm.next_in = (z_const Bytef *)buf;
do {
unsigned n = (unsigned)-1;
if (n > len)
n = (unsigned)len;
state->strm.avail_in = n;
ret = gz_comp(state, Z_NO_FLUSH);
n -= state->strm.avail_in;
state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
len -= n;
if (ret == -1)
return state->again ? put - len : 0;
} while (len);
}
@@ -242,9 +260,10 @@ int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
return 0;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return 0;
gz_error(state, Z_OK, NULL);
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids a flaw in the interface) */
@@ -268,9 +287,10 @@ z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
return 0;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return 0;
gz_error(state, Z_OK, NULL);
/* compute bytes to read -- error on overflow */
len = nitems * size;
@@ -296,16 +316,14 @@ int ZEXPORT gzputc(gzFile file, int c) {
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return -1;
gz_error(state, Z_OK, NULL);
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return -1;
}
if (state->skip && gz_zero(state) == -1)
return -1;
/* try writing to input buffer for speed (state->size == 0 if buffer not
initialized) */
@@ -338,9 +356,10 @@ int ZEXPORT gzputs(gzFile file, const char *s) {
return -1;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return -1;
gz_error(state, Z_OK, NULL);
/* write string */
len = strlen(s);
@@ -349,16 +368,47 @@ int ZEXPORT gzputs(gzFile file, const char *s) {
return -1;
}
put = gz_write(state, s, len);
return put < len ? -1 : (int)len;
return len && put == 0 ? -1 : (int)put;
}
#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \
(defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \
defined(ZLIB_INSECURE)
/* If the second half of the input buffer is occupied, write out the contents.
If there is any input remaining due to a non-blocking stall on write, move
it to the start of the buffer. Return true if this did not open up the
second half of the buffer. state->err should be checked after this to
handle a gz_comp() error. */
local int gz_vacate(gz_statep state) {
z_streamp strm;
strm = &(state->strm);
if (strm->next_in + strm->avail_in <= state->in + state->size)
return 0;
(void)gz_comp(state, Z_NO_FLUSH);
if (strm->avail_in == 0) {
strm->next_in = state->in;
return 0;
}
memmove(state->in, strm->next_in, strm->avail_in);
strm->next_in = state->in;
return strm->avail_in > state->size;
}
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
#include <stdarg.h>
/* -- see zlib.h -- */
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
int len;
unsigned left;
#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE)
#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()"
/* prevent use of insecure vsprintf(), unless purposefully requested */
(void)file, (void)format, (void)va;
return Z_STREAM_ERROR;
#else
int len, ret;
char *next;
gz_statep state;
z_streamp strm;
@@ -369,24 +419,34 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return Z_STREAM_ERROR;
gz_error(state, Z_OK, NULL);
/* make sure we have some buffer space */
if (state->size == 0 && gz_init(state) == -1)
return state->err;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
if (state->skip && gz_zero(state) == -1)
return state->err;
/* do the printf() into the input buffer, put length in len -- the input
buffer is double-sized just for this function, so there is guaranteed to
be state->size bytes available after the current contents */
buffer is double-sized just for this function, so there should be
state->size bytes available after the current contents */
ret = gz_vacate(state);
if (state->err) {
if (ret && state->again) {
/* There was a non-blocking stall on write, resulting in the part
of the second half of the output buffer being occupied. Return
a Z_BUF_ERROR to let the application know that this gzprintf()
needs to be retried. */
gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
}
if (!state->again)
return state->err;
}
if (strm->avail_in == 0)
strm->next_in = state->in;
next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
@@ -412,19 +472,16 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
return 0;
/* update buffer and position, compress first half if past that */
/* update buffer and position */
strm->avail_in += (unsigned)len;
state->x.pos += len;
if (strm->avail_in >= state->size) {
left = strm->avail_in - state->size;
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
/* write out buffer if more than half is occupied */
ret = gz_vacate(state);
if (state->err && !state->again)
return state->err;
return len;
#endif
}
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
@@ -444,6 +501,17 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
int a4, int a5, int a6, int a7, int a8, int a9, int a10,
int a11, int a12, int a13, int a14, int a15, int a16,
int a17, int a18, int a19, int a20) {
#if defined(NO_snprintf) && !defined(ZLIB_INSECURE)
#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()"
/* prevent use of insecure sprintf(), unless purposefully requested */
(void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5,
(void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12,
(void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18,
(void)a19, (void)a20;
return Z_STREAM_ERROR;
#else
int ret;
unsigned len, left;
char *next;
gz_statep state;
@@ -459,24 +527,34 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
if (sizeof(int) != sizeof(void *))
return Z_STREAM_ERROR;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return Z_STREAM_ERROR;
gz_error(state, Z_OK, NULL);
/* make sure we have some buffer space */
if (state->size == 0 && gz_init(state) == -1)
return state->error;
return state->err;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->error;
}
if (state->skip && gz_zero(state) == -1)
return state->err;
/* do the printf() into the input buffer, put length in len -- the input
buffer is double-sized just for this function, so there is guaranteed to
be state->size bytes available after the current contents */
ret = gz_vacate(state);
if (state->err) {
if (ret && state->again) {
/* There was a non-blocking stall on write, resulting in the part
of the second half of the output buffer being occupied. Return
a Z_BUF_ERROR to let the application know that this gzprintf()
needs to be retried. */
gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
}
if (!state->again)
return state->err;
}
if (strm->avail_in == 0)
strm->next_in = state->in;
next = (char *)(strm->next_in + strm->avail_in);
@@ -510,16 +588,13 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
/* update buffer and position, compress first half if past that */
strm->avail_in += len;
state->x.pos += len;
if (strm->avail_in >= state->size) {
left = strm->avail_in - state->size;
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
/* write out buffer if more than half is occupied */
ret = gz_vacate(state);
if (state->err && !state->again)
return state->err;
return (int)len;
#endif
}
#endif
@@ -533,20 +608,18 @@ int ZEXPORT gzflush(gzFile file, int flush) {
return Z_STREAM_ERROR;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
/* check that we're writing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
return Z_STREAM_ERROR;
gz_error(state, Z_OK, NULL);
/* check flush parameter */
if (flush < 0 || flush > Z_FINISH)
return Z_STREAM_ERROR;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
if (state->skip && gz_zero(state) == -1)
return state->err;
/* compress remaining data with requested flush */
(void)gz_comp(state, flush);
@@ -564,20 +637,19 @@ int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct)
/* check that we're compressing and that there's no (serious) error */
if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) ||
state->direct)
return Z_STREAM_ERROR;
gz_error(state, Z_OK, NULL);
/* if no change is requested, then do nothing */
if (level == state->level && strategy == state->strategy)
return Z_OK;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
if (state->skip && gz_zero(state) == -1)
return state->err;
/* change compression parameters for subsequent input */
if (state->size) {
@@ -606,11 +678,8 @@ int ZEXPORT gzclose_w(gzFile file) {
return Z_STREAM_ERROR;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
ret = state->err;
}
if (state->skip && gz_zero(state) == -1)
ret = state->err;
/* flush, free memory, and close file */
if (gz_comp(state, Z_FINISH) == -1)
+20 -67
View File
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2022 Mark Adler
* Copyright (C) 1995-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -46,7 +46,7 @@ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zfree = zcfree;
strm->zfree = zcfree;
#endif
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
@@ -63,57 +63,6 @@ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
@@ -293,7 +242,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
inflate_fixed(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
@@ -303,8 +252,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
default:
strm->msg = (z_const char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
@@ -315,7 +264,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
strm->msg = (z_const char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
@@ -353,7 +302,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
strm->msg = (z_const char *)
"too many length or distance symbols";
state->mode = BAD;
break;
}
@@ -375,7 +325,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
strm->msg = (z_const char *)"invalid code lengths set";
state->mode = BAD;
break;
}
@@ -398,7 +348,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
NEEDBITS(here.bits + 2);
DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
strm->msg = (z_const char *)
"invalid bit length repeat";
state->mode = BAD;
break;
}
@@ -421,7 +372,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
strm->msg = (z_const char *)
"invalid bit length repeat";
state->mode = BAD;
break;
}
@@ -435,7 +387,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
/* check for end-of-block code (better have one) */
if (state->lens[256] == 0) {
strm->msg = (char *)"invalid code -- missing end-of-block";
strm->msg = (z_const char *)
"invalid code -- missing end-of-block";
state->mode = BAD;
break;
}
@@ -449,7 +402,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
strm->msg = (z_const char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
@@ -458,7 +411,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
strm->msg = (z_const char *)"invalid distances set";
state->mode = BAD;
break;
}
@@ -517,7 +470,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
/* invalid code */
if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
strm->msg = (z_const char *)"invalid literal/length code";
state->mode = BAD;
break;
}
@@ -549,7 +502,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
}
DROPBITS(here.bits);
if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
strm->msg = (z_const char *)"invalid distance code";
state->mode = BAD;
break;
}
@@ -564,7 +517,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
strm->msg = (z_const char *)"invalid distance too far back";
state->mode = BAD;
break;
}
+7 -6
View File
@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding
* Copyright (C) 1995-2017 Mark Adler
* Copyright (C) 1995-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -155,7 +155,8 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
strm->msg = (z_const char *)
"invalid distance too far back";
state->mode = BAD;
break;
}
@@ -168,8 +169,8 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
op = dist - op; /* distance back in window */
if (op > whave) {
if (state->sane) {
strm->msg =
(char *)"invalid distance too far back";
strm->msg = (z_const char *)
"invalid distance too far back";
state->mode = BAD;
break;
}
@@ -265,7 +266,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
strm->msg = (z_const char *)"invalid distance code";
state->mode = BAD;
break;
}
@@ -280,7 +281,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
strm->msg = (z_const char *)"invalid literal/length code";
state->mode = BAD;
break;
}
+91 -91
View File
@@ -1,94 +1,94 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* WARNING: this file should *not* be used by applications.
It is part of the implementation of this library and is
subject to change. Applications should only use zlib.h.
*/
/* WARNING: this file should *not* be used by applications.
It is part of the implementation of this library and is
subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};
+39 -152
View File
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
* Copyright (C) 1995-2022 Mark Adler
* Copyright (C) 1995-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -85,12 +85,6 @@
#include "inflate.h"
#include "inffast.h"
#ifdef MAKEFIXED
# ifndef BUILDFIXED
# define BUILDFIXED
# endif
#endif
local int inflateStateCheck(z_streamp strm) {
struct inflate_state FAR *state;
if (strm == Z_NULL ||
@@ -110,6 +104,7 @@ int ZEXPORT inflateResetKeep(z_streamp strm) {
state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL;
strm->data_type = 0;
if (state->wrap) /* to support ill-conceived Java test suite */
strm->adler = state->wrap & 1;
state->mode = HEAD;
@@ -202,6 +197,7 @@ int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
state = (struct inflate_state FAR *)
ZALLOC(strm, 1, sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
zmemzero(state, sizeof(struct inflate_state));
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->strm = strm;
@@ -234,123 +230,11 @@ int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
}
if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
state->hold += (unsigned)value << state->bits;
state->hold += (unsigned long)value << state->bits;
state->bits += (uInt)bits;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
#ifdef MAKEFIXED
#include <stdio.h>
/*
Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
those tables to stdout, which would be piped to inffixed.h. A small program
can simply call makefixed to do this:
void makefixed(void);
int main(void)
{
makefixed();
return 0;
}
Then that can be linked with zlib built with MAKEFIXED defined and run:
a.out > inffixed.h
*/
void makefixed(void)
{
unsigned low, size;
struct inflate_state state;
fixedtables(&state);
puts(" /* inffixed.h -- table for decoding fixed codes");
puts(" * Generated automatically by makefixed().");
puts(" */");
puts("");
puts(" /* WARNING: this file should *not* be used by applications.");
puts(" It is part of the implementation of this library and is");
puts(" subject to change. Applications should only use zlib.h.");
puts(" */");
puts("");
size = 1U << 9;
printf(" static const code lenfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 7) == 0) printf("\n ");
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
state.lencode[low].bits, state.lencode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n };");
size = 1U << 5;
printf("\n static const code distfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 6) == 0) printf("\n ");
printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
state.distcode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n };");
}
#endif /* MAKEFIXED */
/*
Update the window with the last wsize (normally 32K) bytes written before
returning. If window does not exist yet, create it. This is only called
@@ -642,12 +526,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
if (
#endif
((BITS(8) << 8) + (hold >> 8)) % 31) {
strm->msg = (char *)"incorrect header check";
strm->msg = (z_const char *)"incorrect header check";
state->mode = BAD;
break;
}
if (BITS(4) != Z_DEFLATED) {
strm->msg = (char *)"unknown compression method";
strm->msg = (z_const char *)"unknown compression method";
state->mode = BAD;
break;
}
@@ -656,7 +540,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
if (state->wbits == 0)
state->wbits = len;
if (len > 15 || len > state->wbits) {
strm->msg = (char *)"invalid window size";
strm->msg = (z_const char *)"invalid window size";
state->mode = BAD;
break;
}
@@ -672,12 +556,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
NEEDBITS(16);
state->flags = (int)(hold);
if ((state->flags & 0xff) != Z_DEFLATED) {
strm->msg = (char *)"unknown compression method";
strm->msg = (z_const char *)"unknown compression method";
state->mode = BAD;
break;
}
if (state->flags & 0xe000) {
strm->msg = (char *)"unknown header flags set";
strm->msg = (z_const char *)"unknown header flags set";
state->mode = BAD;
break;
}
@@ -793,7 +677,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
if (state->flags & 0x0200) {
NEEDBITS(16);
if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
strm->msg = (char *)"header crc mismatch";
strm->msg = (z_const char *)"header crc mismatch";
state->mode = BAD;
break;
}
@@ -840,7 +724,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
inflate_fixed(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN_; /* decode codes */
@@ -854,8 +738,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
default:
strm->msg = (z_const char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
@@ -864,7 +748,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
strm->msg = (z_const char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
@@ -905,7 +789,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
strm->msg = (z_const char *)
"too many length or distance symbols";
state->mode = BAD;
break;
}
@@ -923,12 +808,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (const code FAR *)(state->next);
state->lencode = state->distcode = (const code FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
strm->msg = (z_const char *)"invalid code lengths set";
state->mode = BAD;
break;
}
@@ -952,7 +837,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
NEEDBITS(here.bits + 2);
DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
strm->msg = (z_const char *)
"invalid bit length repeat";
state->mode = BAD;
break;
}
@@ -975,7 +861,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
strm->msg = (z_const char *)
"invalid bit length repeat";
state->mode = BAD;
break;
}
@@ -989,7 +876,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
/* check for end-of-block code (better have one) */
if (state->lens[256] == 0) {
strm->msg = (char *)"invalid code -- missing end-of-block";
strm->msg = (z_const char *)
"invalid code -- missing end-of-block";
state->mode = BAD;
break;
}
@@ -1003,7 +891,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
strm->msg = (z_const char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
@@ -1012,7 +900,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
strm->msg = (z_const char *)"invalid distances set";
state->mode = BAD;
break;
}
@@ -1066,7 +954,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
break;
}
if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
strm->msg = (z_const char *)"invalid literal/length code";
state->mode = BAD;
break;
}
@@ -1104,7 +992,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
DROPBITS(here.bits);
state->back += here.bits;
if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
strm->msg = (z_const char *)"invalid distance code";
state->mode = BAD;
break;
}
@@ -1121,7 +1009,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
}
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
strm->msg = (char *)"invalid distance too far back";
strm->msg = (z_const char *)"invalid distance too far back";
state->mode = BAD;
break;
}
@@ -1136,7 +1024,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
copy = state->offset - copy;
if (copy > state->whave) {
if (state->sane) {
strm->msg = (char *)"invalid distance too far back";
strm->msg = (z_const char *)
"invalid distance too far back";
state->mode = BAD;
break;
}
@@ -1195,7 +1084,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
state->flags ? hold :
#endif
ZSWAP32(hold)) != state->check) {
strm->msg = (char *)"incorrect data check";
strm->msg = (z_const char *)"incorrect data check";
state->mode = BAD;
break;
}
@@ -1209,7 +1098,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
if (state->wrap && state->flags) {
NEEDBITS(32);
if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
strm->msg = (char *)"incorrect length check";
strm->msg = (z_const char *)"incorrect length check";
state->mode = BAD;
break;
}
@@ -1387,7 +1276,7 @@ int ZEXPORT inflateSync(z_streamp strm) {
/* if first time, start search in bit buffer */
if (state->mode != SYNC) {
state->mode = SYNC;
state->hold <<= state->bits & 7;
state->hold >>= state->bits & 7;
state->bits -= state->bits & 7;
len = 0;
while (state->bits >= 8) {
@@ -1440,7 +1329,6 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
struct inflate_state FAR *state;
struct inflate_state FAR *copy;
unsigned char FAR *window;
unsigned wsize;
/* check input */
if (inflateStateCheck(source) || dest == Z_NULL)
@@ -1451,6 +1339,7 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
copy = (struct inflate_state FAR *)
ZALLOC(source, 1, sizeof(struct inflate_state));
if (copy == Z_NULL) return Z_MEM_ERROR;
zmemzero(copy, sizeof(struct inflate_state));
window = Z_NULL;
if (state->window != Z_NULL) {
window = (unsigned char FAR *)
@@ -1462,8 +1351,8 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
}
/* copy state */
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
zmemcpy(dest, source, sizeof(z_stream));
zmemcpy(copy, state, sizeof(struct inflate_state));
copy->strm = dest;
if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) {
@@ -1471,10 +1360,8 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
copy->distcode = copy->codes + (state->distcode - state->codes);
}
copy->next = copy->codes + (state->next - state->codes);
if (window != Z_NULL) {
wsize = 1U << state->wbits;
zmemcpy(window, state->window, wsize);
}
if (window != Z_NULL)
zmemcpy(window, state->window, state->whave);
copy->window = window;
dest->state = (struct internal_state FAR *)copy;
return Z_OK;
+1 -1
View File
@@ -100,7 +100,7 @@ struct inflate_state {
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
unsigned bits; /* number of bits in hold */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
+134 -9
View File
@@ -1,15 +1,29 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2023 Mark Adler
* Copyright (C) 1995-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifdef MAKEFIXED
# ifndef BUILDFIXED
# define BUILDFIXED
# endif
#endif
#ifdef BUILDFIXED
# define Z_ONCE
#endif
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#ifndef NULL
# define NULL 0
#endif
#define MAXBITS 15
const char inflate_copyright[] =
" inflate 1.3 Copyright 1995-2023 Mark Adler ";
" inflate 1.3.2 Copyright 1995-2026 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
@@ -47,9 +61,9 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
unsigned mask; /* mask for low root bits */
code here; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
unsigned match; /* use base and extra for symbol >= match */
const unsigned short FAR *base = NULL; /* base value table to use */
const unsigned short FAR *extra = NULL; /* extra bits table to use */
unsigned match = 0; /* use base and extra for symbol >= match */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
@@ -57,7 +71,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203};
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 75};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -175,7 +189,6 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
/* set up for code type */
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
match = 20;
break;
case LENS:
@@ -183,10 +196,9 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
extra = lext;
match = 257;
break;
default: /* DISTS */
case DISTS:
base = dbase;
extra = dext;
match = 0;
}
/* initialize state for loop */
@@ -297,3 +309,116 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
*bits = root;
return 0;
}
#ifdef BUILDFIXED
/*
If this is compiled with BUILDFIXED defined, and if inflate will be used in
multiple threads, and if atomics are not available, then inflate() must be
called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must
return before any other threads are allowed to call inflate.
*/
static code *lenfix, *distfix;
static code fixed[544];
/* State for z_once(). */
local z_once_t built = Z_ONCE_INIT;
local void buildtables(void) {
unsigned sym, bits;
static code *next;
unsigned short lens[288], work[288];
/* literal/length table */
sym = 0;
while (sym < 144) lens[sym++] = 8;
while (sym < 256) lens[sym++] = 9;
while (sym < 280) lens[sym++] = 7;
while (sym < 288) lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, lens, 288, &(next), &(bits), work);
/* distance table */
sym = 0;
while (sym < 32) lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, lens, 32, &(next), &(bits), work);
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications if atomics are not available, as it will
not be thread-safe.
*/
void inflate_fixed(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
z_once(&built, buildtables);
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
#ifdef MAKEFIXED
#include <stdio.h>
/*
Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED
also defines BUILDFIXED, so the tables are built on the fly. main() writes
those tables to stdout, which would directed to inffixed.h. Compile this
along with zutil.c:
cc -DMAKEFIXED -o fix inftrees.c zutil.c
./fix > inffixed.h
*/
int main(void) {
unsigned low, size;
struct inflate_state state;
inflate_fixed(&state);
puts("/* inffixed.h -- table for decoding fixed codes");
puts(" * Generated automatically by makefixed().");
puts(" */");
puts("");
puts("/* WARNING: this file should *not* be used by applications.");
puts(" It is part of the implementation of this library and is");
puts(" subject to change. Applications should only use zlib.h.");
puts(" */");
puts("");
size = 1U << 9;
printf("static const code lenfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 7) == 0) printf("\n ");
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
state.lencode[low].bits, state.lencode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n};");
size = 1U << 5;
printf("\nstatic const code distfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 6) == 0) printf("\n ");
printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
state.distcode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n};");
return 0;
}
#endif /* MAKEFIXED */
+5 -3
View File
@@ -1,5 +1,5 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2005, 2010 Mark Adler
* Copyright (C) 1995-2026 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -41,8 +41,8 @@ typedef struct {
examples/enough.c found in the zlib distribution. The arguments to that
program are the number of symbols, the initial root table size, and the
maximum bit length of a code. "enough 286 9 15" for literal/length codes
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
The initial root table size (9 or 6) is found in the fifth argument of the
returns 852, and "enough 30 6 15" for distance codes returns 592. The
initial root table size (9 or 6) is found in the fifth argument of the
inflate_table() calls in inflate.c and infback.c. If the root table size is
changed, then these maximum sizes would be need to be recalculated and
updated. */
@@ -60,3 +60,5 @@ typedef enum {
int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work);
struct inflate_state;
void ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state);
+31 -15
View File
@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2021 Jean-loup Gailly
* Copyright (C) 1995-2026 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -112,7 +112,7 @@ local int base_dist[D_CODES];
#else
# include "trees.h"
#endif /* GEN_TREES_H */
#endif /* defined(GEN_TREES_H) || !defined(STDC) */
struct static_tree_desc_s {
const ct_data *static_tree; /* static tree or NULL */
@@ -152,7 +152,7 @@ local TCONST static_tree_desc static_bl_desc =
* IN assertion: 1 <= len <= 15
*/
local unsigned bi_reverse(unsigned code, int len) {
register unsigned res = 0;
unsigned res = 0;
do {
res |= code & 1;
code >>= 1, res <<= 1;
@@ -184,10 +184,11 @@ local void bi_windup(deflate_state *s) {
} else if (s->bi_valid > 0) {
put_byte(s, (Byte)s->bi_buf);
}
s->bi_used = ((s->bi_valid - 1) & 7) + 1;
s->bi_buf = 0;
s->bi_valid = 0;
#ifdef ZLIB_DEBUG
s->bits_sent = (s->bits_sent + 7) & ~7;
s->bits_sent = (s->bits_sent + 7) & ~(ulg)7;
#endif
}
@@ -466,6 +467,7 @@ void ZLIB_INTERNAL _tr_init(deflate_state *s) {
s->bi_buf = 0;
s->bi_valid = 0;
s->bi_used = 0;
#ifdef ZLIB_DEBUG
s->compressed_len = 0L;
s->bits_sent = 0L;
@@ -724,7 +726,7 @@ local void scan_tree(deflate_state *s, ct_data *tree, int max_code) {
if (++count < max_count && curlen == nextlen) {
continue;
} else if (count < min_count) {
s->bl_tree[curlen].Freq += count;
s->bl_tree[curlen].Freq += (ush)count;
} else if (curlen != 0) {
if (curlen != prevlen) s->bl_tree[curlen].Freq++;
s->bl_tree[REP_3_6].Freq++;
@@ -817,7 +819,7 @@ local int build_bl_tree(deflate_state *s) {
}
/* Update opt_len to include the bit length tree and counts */
s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4;
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu",
s->opt_len, s->static_len));
return max_blindex;
@@ -843,13 +845,13 @@ local void send_all_trees(deflate_state *s, int lcodes, int dcodes,
Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
}
Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent));
send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */
Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent));
send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */
Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent));
}
/* ===========================================================================
@@ -899,14 +901,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree,
const ct_data *dtree) {
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
unsigned sx = 0; /* running index in sym_buf */
unsigned sx = 0; /* running index in symbol buffers */
unsigned code; /* the code to send */
int extra; /* number of extra bits to send */
if (s->sym_next != 0) do {
#ifdef LIT_MEM
dist = s->d_buf[sx];
lc = s->l_buf[sx++];
#else
dist = s->sym_buf[sx++] & 0xff;
dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
lc = s->sym_buf[sx++];
#endif
if (dist == 0) {
send_code(s, lc, ltree); /* send a literal byte */
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
@@ -927,12 +934,16 @@ local void compress_block(deflate_state *s, const ct_data *ltree,
extra = extra_dbits[code];
if (extra != 0) {
dist -= (unsigned)base_dist[code];
send_bits(s, dist, extra); /* send the extra distance bits */
send_bits(s, (int)dist, extra); /* send the extra bits */
}
} /* literal or match pair ? */
/* Check that the overlay between pending_buf and sym_buf is ok: */
/* Check for no overlay of pending_buf on needed symbols */
#ifdef LIT_MEM
Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow");
#else
Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
#endif
} while (sx < s->sym_next);
@@ -997,11 +1008,11 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len,
s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc)));
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len,
s->static_len));
/* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations.
@@ -1074,7 +1085,7 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
#endif
}
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3,
s->compressed_len - 7*last));
s->compressed_len - 7*(ulg)last));
}
/* ===========================================================================
@@ -1082,9 +1093,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
* the current block must be flushed.
*/
int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
#ifdef LIT_MEM
s->d_buf[s->sym_next] = (ush)dist;
s->l_buf[s->sym_next++] = (uch)lc;
#else
s->sym_buf[s->sym_next++] = (uch)dist;
s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
s->sym_buf[s->sym_next++] = (uch)lc;
#endif
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;
+39 -23
View File
@@ -1,5 +1,5 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2003, 2010, 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
*/
@@ -23,24 +23,24 @@
memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
Z_DATA_ERROR if the input data was corrupted, including if the input data is
an incomplete zlib stream.
The _z versions of the functions take size_t length arguments.
*/
int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong *sourceLen) {
int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source,
z_size_t *sourceLen) {
z_stream stream;
int err;
const uInt max = (uInt)-1;
uLong len, left;
Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
z_size_t len, left;
if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) ||
destLen == NULL || (*destLen > 0 && dest == NULL))
return Z_STREAM_ERROR;
len = *sourceLen;
if (*destLen) {
left = *destLen;
*destLen = 0;
}
else {
left = 1;
dest = buf;
}
left = *destLen;
if (left == 0 && dest == Z_NULL)
dest = (Bytef *)&stream.reserved; /* next_out cannot be NULL */
stream.next_in = (z_const Bytef *)source;
stream.avail_in = 0;
@@ -56,30 +56,46 @@ int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
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 = len > (uLong)max ? max : (uInt)len;
stream.avail_in = len > (z_size_t)max ? max : (uInt)len;
len -= stream.avail_in;
}
err = inflate(&stream, Z_NO_FLUSH);
} while (err == Z_OK);
*sourceLen -= len + stream.avail_in;
if (dest != buf)
*destLen = stream.total_out;
else if (stream.total_out && err == Z_BUF_ERROR)
left = 1;
/* Set len and left to the unused input data and unused output space. Set
*sourceLen to the amount of input consumed. Set *destLen to the amount
of data produced. */
len += stream.avail_in;
left += stream.avail_out;
*sourceLen -= len;
*destLen -= left;
inflateEnd(&stream);
return err == Z_STREAM_END ? Z_OK :
err == Z_NEED_DICT ? Z_DATA_ERROR :
err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR :
err;
}
int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong *sourceLen) {
int ret;
z_size_t got = *destLen, used = *sourceLen;
ret = uncompress2_z(dest, &got, source, &used);
*sourceLen = (uLong)used;
*destLen = (uLong)got;
return ret;
}
int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source,
z_size_t sourceLen) {
z_size_t used = sourceLen;
return uncompress2_z(dest, destLen, source, &used);
}
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen) {
return uncompress2(dest, destLen, source, &sourceLen);
uLong used = sourceLen;
return uncompress2(dest, destLen, source, &used);
}
BIN
View File
Binary file not shown.
+49 -35
View File
@@ -1,5 +1,5 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2017 Jean-loup Gailly
* Copyright (C) 1995-2026 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -86,28 +86,36 @@ uLong ZEXPORT zlibCompileFlags(void) {
flags += 1L << 21;
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf
flags += 1L << 25;
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
# ifdef NO_vsnprintf
# ifdef ZLIB_INSECURE
flags += 1L << 25;
# else
flags += 1L << 27;
# endif
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
#else
flags += 1L << 24;
# ifdef NO_snprintf
flags += 1L << 25;
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
# ifdef NO_snprintf
# ifdef ZLIB_INSECURE
flags += 1L << 25;
# else
flags += 1L << 27;
# endif
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
@@ -142,28 +150,34 @@ const char * ZEXPORT zError(int err) {
#ifndef HAVE_MEMCPY
void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) {
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
void ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) {
uchf *p = dst;
const uchf *q = src;
while (n) {
*p++ = *q++;
n--;
}
}
int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) {
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) {
const uchf *p = s1, *q = s2;
while (n) {
if (*p++ != *q++)
return (int)p[-1] - (int)q[-1];
n--;
}
return 0;
}
void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) {
void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) {
uchf *p = b;
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
while (len) {
*p++ = 0;
len--;
}
}
#endif
#ifndef Z_SOLO