VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/zlib/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/zlib/inflate.c')
-rw-r--r--src/Common/zlib/inflate.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/Common/zlib/inflate.c b/src/Common/zlib/inflate.c
index ac333e8c..7be8c636 100644
--- a/src/Common/zlib/inflate.c
+++ b/src/Common/zlib/inflate.c
@@ -1,6 +1,6 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2016 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
@@ -129,8 +129,9 @@ z_streamp strm;
strm->adler = state->wrap & 1;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
+ state->flags = -1;
state->dmax = 32768U;
state->head = Z_NULL;
state->hold = 0;
state->bits = 0;
@@ -446,12 +447,12 @@ unsigned copy;
/* Macros for inflate(): */
/* check function to use adler32() for zlib or crc32() for gzip */
#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
+# define UPDATE_CHECK(check, buf, len) \
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
+# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
#endif
/* check macros for header crc */
#ifdef GUNZIP
@@ -669,9 +670,8 @@ int flush;
INITBITS();
state->mode = FLAGS;
break;
}
- state->flags = 0; /* expect zlib header */
if (state->head != Z_NULL)
state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */
#else
@@ -696,8 +696,9 @@ int flush;
state->mode = BAD;
break;
}
state->dmax = 1U << len;
+ state->flags = 0; /* indicate zlib header */
Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE;
INITBITS();
@@ -721,16 +722,18 @@ int flush;
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC2(state->check, hold);
INITBITS();
state->mode = TIME;
+ /* fallthrough */
case TIME:
NEEDBITS(32);
if (state->head != Z_NULL)
state->head->time = hold;
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC4(state->check, hold);
INITBITS();
state->mode = OS;
+ /* fallthrough */
case OS:
NEEDBITS(16);
if (state->head != Z_NULL) {
state->head->xflags = (int)(hold & 0xff);
@@ -739,8 +742,9 @@ int flush;
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC2(state->check, hold);
INITBITS();
state->mode = EXLEN;
+ /* fallthrough */
case EXLEN:
if (state->flags & 0x0400) {
NEEDBITS(16);
state->length = (unsigned)(hold);
@@ -752,8 +756,9 @@ int flush;
}
else if (state->head != Z_NULL)
state->head->extra = Z_NULL;
state->mode = EXTRA;
+ /* fallthrough */
case EXTRA:
if (state->flags & 0x0400) {
copy = state->length;
if (copy > have) copy = have;
@@ -774,8 +779,9 @@ int flush;
if (state->length) goto inf_leave;
}
state->length = 0;
state->mode = NAME;
+ /* fallthrough */
case NAME:
if (state->flags & 0x0800) {
if (have == 0) goto inf_leave;
copy = 0;
@@ -795,8 +801,9 @@ int flush;
else if (state->head != Z_NULL)
state->head->name = Z_NULL;
state->length = 0;
state->mode = COMMENT;
+ /* fallthrough */
case COMMENT:
if (state->flags & 0x1000) {
if (have == 0) goto inf_leave;
copy = 0;
@@ -815,8 +822,9 @@ int flush;
}
else if (state->head != Z_NULL)
state->head->comment = Z_NULL;
state->mode = HCRC;
+ /* fallthrough */
case HCRC:
if (state->flags & 0x0200) {
NEEDBITS(16);
if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
@@ -838,17 +846,20 @@ int flush;
NEEDBITS(32);
strm->adler = state->check = ZSWAP32(hold);
INITBITS();
state->mode = DICT;
+ /* fallthrough */
case DICT:
if (state->havedict == 0) {
RESTORE();
return Z_NEED_DICT;
}
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE;
+ /* fallthrough */
case TYPE:
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case TYPEDO:
if (state->last) {
BYTEBITS();
state->mode = CHECK;
@@ -897,10 +908,12 @@ int flush;
state->length));
INITBITS();
state->mode = COPY_;
if (flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case COPY_:
state->mode = COPY;
+ /* fallthrough */
case COPY:
copy = state->length;
if (copy) {
if (copy > have) copy = have;
@@ -934,8 +947,9 @@ int flush;
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
state->have = 0;
state->mode = LENLENS;
+ /* fallthrough */
case LENLENS:
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
@@ -955,8 +969,9 @@ int flush;
}
Tracev((stderr, "inflate: code lengths ok\n"));
state->have = 0;
state->mode = CODELENS;
+ /* fallthrough */
case CODELENS:
while (state->have < state->nlen + state->ndist) {
for (;;) {
here = state->lencode[BITS(state->lenbits)];
@@ -1038,10 +1053,12 @@ int flush;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN_;
if (flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case LEN_:
state->mode = LEN;
+ /* fallthrough */
case LEN:
if (have >= 6 && left >= 258) {
RESTORE();
inflate_fast(strm, out);
@@ -1089,8 +1106,9 @@ int flush;
break;
}
state->extra = (unsigned)(here.op) & 15;
state->mode = LENEXT;
+ /* fallthrough */
case LENEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
@@ -1099,8 +1117,9 @@ int flush;
}
Tracevv((stderr, "inflate: length %u\n", state->length));
state->was = state->length;
state->mode = DIST;
+ /* fallthrough */
case DIST:
for (;;) {
here = state->distcode[BITS(state->distbits)];
if ((unsigned)(here.bits) <= bits) break;
@@ -1126,8 +1145,9 @@ int flush;
}
state->offset = (unsigned)here.val;
state->extra = (unsigned)(here.op) & 15;
state->mode = DISTEXT;
+ /* fallthrough */
case DISTEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
@@ -1142,8 +1162,9 @@ int flush;
}
#endif
Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH;
+ /* fallthrough */
case MATCH:
if (left == 0) goto inf_leave;
copy = out - left;
if (state->offset > copy) { /* copy from window */
@@ -1201,9 +1222,9 @@ int flush;
strm->total_out += out;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE(state->check, put - out, out);
+ UPDATE_CHECK(state->check, put - out, out);
out = left;
if ((state->wrap & 4) && (
#ifdef GUNZIP
state->flags ? hold :
@@ -1217,12 +1238,13 @@ int flush;
Tracev((stderr, "inflate: check matches trailer\n"));
}
#ifdef GUNZIP
state->mode = LENGTH;
+ /* fallthrough */
case LENGTH:
if (state->wrap && state->flags) {
NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
+ if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
strm->msg = (char *)"incorrect length check";
state->mode = BAD;
break;
}
@@ -1230,8 +1252,9 @@ int flush;
Tracev((stderr, "inflate: length matches trailer\n"));
}
#endif
state->mode = DONE;
+ /* fallthrough */
case DONE:
ret = Z_STREAM_END;
goto inf_leave;
case BAD:
@@ -1239,8 +1262,9 @@ int flush;
goto inf_leave;
case MEM:
return Z_MEM_ERROR;
case SYNC:
+ /* fallthrough */
default:
return Z_STREAM_ERROR;
}
@@ -1264,9 +1288,9 @@ int flush;
strm->total_out += out;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
+ UPDATE_CHECK(state->check, strm->next_out - out, out);
strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0) +
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
@@ -1400,8 +1424,9 @@ unsigned len;
int ZEXPORT inflateSync(strm)
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 */
unsigned char buf[4]; /* to restore bit buffer to byte string */
struct inflate_state FAR *state;
@@ -1432,11 +1457,17 @@ z_streamp strm;
strm->total_in += len;
/* return no joy or set up to restart inflate() on a new block */
if (state->have != 4) return Z_DATA_ERROR;
+ if (state->flags == -1)
+ state->wrap = 0; /* if no header yet, treat as raw */
+ else
+ state->wrap &= ~4; /* no point in computing a check value now */
+ flags = state->flags;
in = strm->total_in; out = strm->total_out;
inflateReset(strm);
strm->total_in = in; strm->total_out = out;
+ state->flags = flags;
state->mode = TYPE;
return Z_OK;
}
@@ -1530,9 +1561,9 @@ int check;
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (check)
+ if (check && state->wrap)
state->wrap |= 4;
else
state->wrap &= ~4;
return Z_OK;