summaryrefslogtreecommitdiff
path: root/deps/zlib/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/zlib/inflate.c')
-rw-r--r--deps/zlib/inflate.c238
1 files changed, 120 insertions, 118 deletions
diff --git a/deps/zlib/inflate.c b/deps/zlib/inflate.c
index 7be8c63662..ef1d078466 100644
--- a/deps/zlib/inflate.c
+++ b/deps/zlib/inflate.c
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2022 Mark Adler
+ * Copyright (C) 1995-2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -83,7 +83,13 @@
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
+
+#if defined(INFLATE_CHUNK_SIMD_NEON) || defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_GENERIC)
+#include "inffast_chunk.h"
+#include "chunkcopy.h"
+#else
#include "inffast.h"
+#endif
#ifdef MAKEFIXED
# ifndef BUILDFIXED
@@ -92,19 +98,17 @@
#endif
/* function prototypes */
-local int inflateStateCheck OF((z_streamp strm));
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
- unsigned copy));
+local int inflateStateCheck(z_streamp strm);
+local void fixedtables(struct inflate_state FAR *state);
+local int updatewindow(z_streamp strm, const unsigned char FAR *end,
+ unsigned copy);
#ifdef BUILDFIXED
- void makefixed OF((void));
+ void makefixed(void);
#endif
-local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
- unsigned len));
+local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len);
-local int inflateStateCheck(strm)
-z_streamp strm;
-{
+static int inflateStateCheck(z_streamp strm) {
struct inflate_state FAR *state;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
@@ -116,9 +120,7 @@ z_streamp strm;
return 0;
}
-int ZEXPORT inflateResetKeep(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateResetKeep(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -142,9 +144,7 @@ z_streamp strm;
return Z_OK;
}
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateReset(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -155,10 +155,7 @@ z_streamp strm;
return inflateResetKeep(strm);
}
-int ZEXPORT inflateReset2(strm, windowBits)
-z_streamp strm;
-int windowBits;
-{
+int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
int wrap;
struct inflate_state FAR *state;
@@ -168,6 +165,8 @@ int windowBits;
/* extract wrap request from windowBits parameter */
if (windowBits < 0) {
+ if (windowBits < -15)
+ return Z_STREAM_ERROR;
wrap = 0;
windowBits = -windowBits;
}
@@ -193,12 +192,8 @@ int windowBits;
return inflateReset(strm);
}
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
+int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
+ const char *version, int stream_size) {
int ret;
struct inflate_state FAR *state;
@@ -237,32 +232,27 @@ int stream_size;
return ret;
}
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
+int ZEXPORT inflateInit_(z_streamp strm, const char *version,
+ int stream_size) {
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
}
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
+int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ if (bits == 0)
+ return Z_OK;
state = (struct inflate_state FAR *)strm->state;
if (bits < 0) {
state->hold = 0;
state->bits = 0;
return Z_OK;
}
- if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
state->hold += (unsigned)value << state->bits;
- state->bits += (uInt)bits;
+ state->bits += bits;
return Z_OK;
}
@@ -276,9 +266,7 @@ int value;
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
+static void fixedtables(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
@@ -340,7 +328,7 @@ struct inflate_state FAR *state;
a.out > inffixed.h
*/
-void makefixed()
+void makefixed(void)
{
unsigned low, size;
struct inflate_state state;
@@ -394,11 +382,7 @@ void makefixed()
output will fall in the output data, making match copies simpler and faster.
The advantage may be dependent on the size of the processor's data caches.
*/
-local int updatewindow(strm, end, copy)
-z_streamp strm;
-const Bytef *end;
-unsigned copy;
-{
+static int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {
struct inflate_state FAR *state;
unsigned dist;
@@ -406,10 +390,27 @@ unsigned copy;
/* if it hasn't been done already, allocate space for the window */
if (state->window == Z_NULL) {
+#if defined(INFLATE_CHUNK_SIMD_NEON) || defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_GENERIC)
+ unsigned wsize = 1U << state->wbits;
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, wsize + CHUNKCOPY_CHUNK_SIZE,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ #ifdef INFLATE_CLEAR_UNUSED_UNDEFINED
+ /* Copies from the overflow portion of this buffer are undefined and
+ may cause analysis tools to raise a wraning if we don't initialize
+ it. However, this undefined data overwrites other undefined data
+ and is subsequently either overwritten or left deliberately
+ undefined at the end of decode; so there's really no point.
+ */
+ zmemzero(state->window + wsize, CHUNKCOPY_CHUNK_SIZE);
+ #endif
+#else
state->window = (unsigned char FAR *)
ZALLOC(strm, 1U << state->wbits,
sizeof(unsigned char));
if (state->window == Z_NULL) return 1;
+#endif /* INFLATE_CHUNK_SIMD */
}
/* if window not in use yet, initialize */
@@ -448,10 +449,10 @@ unsigned copy;
/* check function to use adler32() for zlib or crc32() for gzip */
#ifdef GUNZIP
-# define UPDATE_CHECK(check, buf, len) \
+# define UPDATE(check, buf, len) \
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
#else
-# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
+# define UPDATE(check, buf, len) adler32(check, buf, len)
#endif
/* check macros for header crc */
@@ -620,10 +621,7 @@ unsigned copy;
will return Z_BUF_ERROR if it has not reached the end of the stream.
*/
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
+int ZEXPORT inflate(z_streamp strm, int flush) {
struct inflate_state FAR *state;
z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
@@ -764,8 +762,9 @@ int flush;
if (copy > have) copy = have;
if (copy) {
if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
+ state->head->extra != Z_NULL &&
+ (len = state->head->extra_len - state->length) <
+ state->head->extra_max) {
zmemcpy(state->head->extra + len, next,
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
@@ -790,7 +789,7 @@ int flush;
if (state->head != Z_NULL &&
state->head->name != Z_NULL &&
state->length < state->head->name_max)
- state->head->name[state->length++] = (Bytef)len;
+ state->head->name[state->length++] = len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
@@ -812,7 +811,7 @@ int flush;
if (state->head != Z_NULL &&
state->head->comment != Z_NULL &&
state->length < state->head->comm_max)
- state->head->comment[state->length++] = (Bytef)len;
+ state->head->comment[state->length++] = len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
@@ -1030,11 +1029,11 @@ int flush;
}
/* build code tables -- note: do not change the lenbits or distbits
- values here (9 and 6) without reading the comments in inftrees.h
+ values here (10 and 9) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (const code FAR *)(state->next);
- state->lenbits = 9;
+ state->lenbits = 10;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
@@ -1043,7 +1042,7 @@ int flush;
break;
}
state->distcode = (const code FAR *)(state->next);
- state->distbits = 6;
+ state->distbits = 9;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
@@ -1059,9 +1058,14 @@ int flush;
state->mode = LEN;
/* fallthrough */
case LEN:
- if (have >= 6 && left >= 258) {
+ if (have >= INFLATE_FAST_MIN_INPUT &&
+ left >= INFLATE_FAST_MIN_OUTPUT) {
RESTORE();
+#if defined(INFLATE_CHUNK_SIMD_NEON) || defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_GENERIC)
+ inflate_fast_chunk_(strm, out);
+#else
inflate_fast(strm, out);
+#endif
LOAD();
if (state->mode == TYPE)
state->back = -1;
@@ -1196,6 +1200,18 @@ int flush;
else
from = state->window + (state->wnext - copy);
if (copy > state->length) copy = state->length;
+#if defined(INFLATE_CHUNK_SIMD_NEON) || defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_GENERIC)
+ if (copy > left) copy = left;
+ put = chunkcopy_safe(put, from, copy, put + left);
+ }
+ else { /* copy from output */
+ copy = state->length;
+ if (copy > left) copy = left;
+ put = chunkcopy_lapped_safe(put, state->offset, copy, put + left);
+ }
+ left -= copy;
+ state->length -= copy;
+#else
}
else { /* copy from output */
from = put - state->offset;
@@ -1207,6 +1223,7 @@ int flush;
do {
*put++ = *from++;
} while (--copy);
+#endif
if (state->length == 0) state->mode = LEN;
break;
case LIT:
@@ -1223,7 +1240,7 @@ int flush;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE_CHECK(state->check, put - out, out);
+ UPDATE(state->check, put - out, out);
out = left;
if ((state->wrap & 4) && (
#ifdef GUNZIP
@@ -1275,6 +1292,29 @@ int flush;
Note: a memory error from inflate() is non-recoverable.
*/
inf_leave:
+#if defined(ZLIB_DEBUG) && (defined(INFLATE_CHUNK_SIMD_NEON) || defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_GENERIC))
+ /* XXX(cavalcantii): I put this in place back in 2017 to help debug faulty
+ * client code relying on undefined behavior when chunk_copy first landed.
+ *
+ * It is save to say after all these years that Chromium code is well
+ * behaved and works fine with the optimization, therefore we can enable
+ * this only for ZLIB_DEBUG builds.
+ *
+ * We write a defined value in the unused space to help mark
+ * where the stream has ended. We don't use zeros as that can
+ * mislead clients relying on undefined behavior (i.e. assuming
+ * that the data is over when the buffer has a zero/null value).
+ *
+ * The basic idea is that if client code is not relying on the zlib context
+ * to inform the amount of decompressed data, but instead reads the output
+ * buffer until a zero/null is found, it will fail faster and harder
+ * when the remaining of the buffer is marked with a symbol (e.g. 0x55).
+ */
+ if (left >= CHUNKCOPY_CHUNK_SIZE)
+ memset(put, 0x55, CHUNKCOPY_CHUNK_SIZE);
+ else
+ memset(put, 0x55, left);
+#endif
RESTORE();
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
(state->mode < CHECK || flush != Z_FINISH)))
@@ -1289,8 +1329,8 @@ int flush;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE_CHECK(state->check, strm->next_out - out, out);
- strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0) +
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
@@ -1298,8 +1338,7 @@ int flush;
return ret;
}
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
+int ZEXPORT inflateEnd(z_streamp strm)
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
@@ -1312,11 +1351,8 @@ z_streamp strm;
return Z_OK;
}
-int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-Bytef *dictionary;
-uInt *dictLength;
-{
+int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,
+ uInt *dictLength) {
struct inflate_state FAR *state;
/* check state */
@@ -1335,11 +1371,8 @@ uInt *dictLength;
return Z_OK;
}
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
+int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
+ uInt dictLength) {
struct inflate_state FAR *state;
unsigned long dictid;
int ret;
@@ -1370,10 +1403,7 @@ uInt dictLength;
return Z_OK;
}
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
+int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {
struct inflate_state FAR *state;
/* check state */
@@ -1398,11 +1428,8 @@ gz_headerp head;
called again with more data and the *have state. *have is initialized to
zero for the first call.
*/
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-const unsigned char FAR *buf;
-unsigned len;
-{
+static unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len) {
unsigned got;
unsigned next;
@@ -1421,9 +1448,7 @@ unsigned len;
return next;
}
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateSync(z_streamp strm) {
unsigned len; /* number of bytes to look at or looked at */
int flags; /* temporary to save header status */
unsigned long in, out; /* temporary to save total_in and total_out */
@@ -1479,9 +1504,7 @@ z_streamp strm;
block. When decompressing, PPP checks that at the end of input packet,
inflate is waiting for these length bytes.
*/
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateSyncPoint(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1489,10 +1512,7 @@ z_streamp strm;
return state->mode == STORED && state->bits == 0;
}
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
+int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
struct inflate_state FAR *state;
struct inflate_state FAR *copy;
unsigned char FAR *window;
@@ -1536,10 +1556,7 @@ z_streamp source;
return Z_OK;
}
-int ZEXPORT inflateUndermine(strm, subvert)
-z_streamp strm;
-int subvert;
-{
+int ZEXPORT inflateUndermine(z_streamp strm, int subvert) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1548,16 +1565,12 @@ int subvert;
state->sane = !subvert;
return Z_OK;
#else
- (void)subvert;
state->sane = 1;
return Z_DATA_ERROR;
#endif
}
-int ZEXPORT inflateValidate(strm, check)
-z_streamp strm;
-int check;
-{
+int ZEXPORT inflateValidate(z_streamp strm, int check) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1569,24 +1582,13 @@ int check;
return Z_OK;
}
-long ZEXPORT inflateMark(strm)
-z_streamp strm;
-{
+long ZEXPORT inflateMark(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
- return -(1L << 16);
+ return (long)(((unsigned long)0 - 1) << 16);
state = (struct inflate_state FAR *)strm->state;
return (long)(((unsigned long)((long)state->back)) << 16) +
(state->mode == COPY ? state->length :
(state->mode == MATCH ? state->was - state->length : 0));
}
-
-unsigned long ZEXPORT inflateCodesUsed(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (inflateStateCheck(strm)) return (unsigned long)-1;
- state = (struct inflate_state FAR *)strm->state;
- return (unsigned long)(state->next - state->codes);
-}