diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2005-07-20 15:56:47 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2005-07-20 15:56:47 +0000 |
commit | 2cf630da4ce8cccae74ab052eb0055de8afc9502 (patch) | |
tree | 32220b8c594ae0352770c85d0463f63af944cf11 /lib/libz/inflate.c | |
parent | 9ba66e2144908c121085b905f0ebf384b79343ba (diff) |
Update to zlib 1.2.3; OK deraadt@
Diffstat (limited to 'lib/libz/inflate.c')
-rw-r--r-- | lib/libz/inflate.c | 128 |
1 files changed, 111 insertions, 17 deletions
diff --git a/lib/libz/inflate.c b/lib/libz/inflate.c index a286dd4069f..23281f9ce77 100644 --- a/lib/libz/inflate.c +++ b/lib/libz/inflate.c @@ -1,6 +1,6 @@ -/* $OpenBSD: inflate.c,v 1.8 2004/12/03 03:06:36 djm Exp $ */ +/* $OpenBSD: inflate.c,v 1.9 2005/07/20 15:56:41 millert Exp $ */ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2003 Mark Adler + * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -114,8 +114,11 @@ z_streamp strm; state->mode = HEAD; state->last = 0; state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; state->wsize = 0; state->whave = 0; + state->write = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; @@ -123,6 +126,22 @@ z_streamp strm; return Z_OK; } +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; @@ -145,7 +164,7 @@ int stream_size; ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); - strm->state = (voidpf)state; + strm->state = (struct internal_state FAR *)state; if (windowBits < 0) { state->wrap = 0; windowBits = -windowBits; @@ -583,6 +602,8 @@ int flush; 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 if ( @@ -606,7 +627,8 @@ int flush; break; } DROPBITS(4); - if (BITS(4) + 8 > state->wbits) { + len = BITS(4) + 8; + if (len > state->wbits) { #ifdef SMALL strm->msg = "error"; #else @@ -615,6 +637,7 @@ int flush; state->mode = BAD; break; } + state->dmax = 1U << len; Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; @@ -642,16 +665,24 @@ int flush; state->mode = BAD; break; } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; @@ -659,15 +690,26 @@ int flush; if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; @@ -676,6 +718,7 @@ int flush; } if (state->length) goto inf_leave; } + state->length = 0; state->mode = NAME; case NAME: if (state->flags & 0x0800) { @@ -683,13 +726,20 @@ int flush; copy = 0; do { len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; } while (len && copy < have); - if (state->flags & 0x02000) + if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { @@ -697,13 +747,19 @@ int flush; copy = 0; do { len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; } while (len && copy < have); - if (state->flags & 0x02000) + if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { @@ -719,6 +775,10 @@ int flush; } INITBITS(); } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; @@ -1036,6 +1096,13 @@ int flush; state->offset += BITS(state->extra); DROPBITS(state->extra); } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif if (state->offset > state->whave + out - left) { #ifdef SMALL strm->msg = "error"; @@ -1189,12 +1256,16 @@ uInt dictLength; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - if (state->mode != DICT) return Z_STREAM_ERROR; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; /* check for correct dictionary id */ - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) return Z_DATA_ERROR; + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } /* copy dictionary to window */ if (updatewindow(strm, strm->avail_out)) { @@ -1216,6 +1287,23 @@ uInt dictLength; return Z_OK; } +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes @@ -1318,6 +1406,7 @@ z_streamp source; struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; + unsigned wsize; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || @@ -1340,14 +1429,19 @@ z_streamp source; } /* copy state */ - *dest = *source; - *copy = *state; - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) - zmemcpy(window, state->window, 1U << state->wbits); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } copy->window = window; - dest->state = (voidpf)copy; + dest->state = (struct internal_state FAR *)copy; return Z_OK; } |