summaryrefslogtreecommitdiff
path: root/inflate.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2019-01-02 18:10:40 -0800
committerHans Kristian Rosbach <hk-github@circlestorm.org>2019-10-22 09:57:38 +0200
commit33ce336b82f257689e7d20cee228fa61e079b90a (patch)
tree22fb309c87c76782d97f99ffc8c33b61ef2a38df /inflate.c
parentcf5959e11915d88e1b142fef3de359a1d443bd6d (diff)
Don't bother computing check value after successful inflateSync().
inflateSync() is used to skip invalid deflate data, which means that the check value that was being computed is no longer useful. This commit turns off the check value computation, and furthermore allows a successful return if the compressed data terminated in a graceful manner. This commit also fixes a bug in the case that inflateSync() is used before a header is ever processed. In that case, there is no knowledge of a trailer, so the remainder is treated as raw.
Diffstat (limited to 'inflate.c')
-rw-r--r--inflate.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/inflate.c b/inflate.c
index 0b17e31..2ba0947 100644
--- a/inflate.c
+++ b/inflate.c
@@ -67,6 +67,7 @@ int ZEXPORT PREFIX(inflateResetKeep)(PREFIX3(stream) *strm) {
state->check = functable.adler32(0L, NULL, 0);
state->last = 0;
state->havedict = 0;
+ state->flags = -1;
state->dmax = 32768U;
state->head = NULL;
state->hold = 0;
@@ -420,7 +421,6 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) {
state->mode = FLAGS;
break;
}
- state->flags = 0; /* expect zlib header */
if (state->head != NULL)
state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */
@@ -447,6 +447,7 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) {
break;
}
state->dmax = 1U << len;
+ state->flags = 0; /* indicate zlib header */
Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = functable.adler32(0L, NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE;
@@ -1039,7 +1040,7 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) {
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;
@@ -1209,6 +1210,7 @@ static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t le
int ZEXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) {
unsigned len; /* number of bytes to look at or looked at */
+ int flags; /* temporary to save header status */
size_t in, out; /* temporary to save total_in and total_out */
unsigned char buf[4]; /* to restore bit buffer to byte string */
struct inflate_state *state;
@@ -1244,13 +1246,17 @@ int ZEXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) {
/* return no joy or set up to restart inflate() on a new block */
if (state->have != 4)
return Z_DATA_ERROR;
- if (state->mode == HEAD)
- state->wrap = 0; /* never processed header, so assume raw */
+ 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;
PREFIX(inflateReset)(strm);
strm->total_in = in;
strm->total_out = out;
+ state->flags = flags;
state->mode = TYPE;
return Z_OK;
}