diff options
Diffstat (limited to 'src/Common/zlib/inflate.c')
-rw-r--r-- | src/Common/zlib/inflate.c | 47 |
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; |