diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2019-01-02 18:10:40 -0800 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2019-01-02 20:40:40 -0800 |
commit | 0d36ec47f310478549c0864f215ab5c0114c49ba (patch) | |
tree | 19821ce1a005e7a5741b65e27ef6a83d8a7a565f /inflate.c | |
parent | 7c0c75e990ca5395139c148f120042048b0ce091 (diff) | |
download | zlib-0d36ec47f310478549c0864f215ab5c0114c49ba.tar.gz zlib-0d36ec47f310478549c0864f215ab5c0114c49ba.tar.bz2 zlib-0d36ec47f310478549c0864f215ab5c0114c49ba.zip |
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.c | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -130,6 +130,7 @@ z_streamp strm; | |||
130 | state->mode = HEAD; | 130 | state->mode = HEAD; |
131 | state->last = 0; | 131 | state->last = 0; |
132 | state->havedict = 0; | 132 | state->havedict = 0; |
133 | state->flags = -1; | ||
133 | state->dmax = 32768U; | 134 | state->dmax = 32768U; |
134 | state->head = Z_NULL; | 135 | state->head = Z_NULL; |
135 | state->hold = 0; | 136 | state->hold = 0; |
@@ -670,7 +671,6 @@ int flush; | |||
670 | state->mode = FLAGS; | 671 | state->mode = FLAGS; |
671 | break; | 672 | break; |
672 | } | 673 | } |
673 | state->flags = 0; /* expect zlib header */ | ||
674 | if (state->head != Z_NULL) | 674 | if (state->head != Z_NULL) |
675 | state->head->done = -1; | 675 | state->head->done = -1; |
676 | if (!(state->wrap & 1) || /* check if zlib header allowed */ | 676 | if (!(state->wrap & 1) || /* check if zlib header allowed */ |
@@ -697,6 +697,7 @@ int flush; | |||
697 | break; | 697 | break; |
698 | } | 698 | } |
699 | state->dmax = 1U << len; | 699 | state->dmax = 1U << len; |
700 | state->flags = 0; /* indicate zlib header */ | ||
700 | Tracev((stderr, "inflate: zlib header ok\n")); | 701 | Tracev((stderr, "inflate: zlib header ok\n")); |
701 | strm->adler = state->check = adler32(0L, Z_NULL, 0); | 702 | strm->adler = state->check = adler32(0L, Z_NULL, 0); |
702 | state->mode = hold & 0x200 ? DICTID : TYPE; | 703 | state->mode = hold & 0x200 ? DICTID : TYPE; |
@@ -1221,7 +1222,7 @@ int flush; | |||
1221 | case LENGTH: | 1222 | case LENGTH: |
1222 | if (state->wrap && state->flags) { | 1223 | if (state->wrap && state->flags) { |
1223 | NEEDBITS(32); | 1224 | NEEDBITS(32); |
1224 | if (hold != (state->total & 0xffffffffUL)) { | 1225 | if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { |
1225 | strm->msg = (char *)"incorrect length check"; | 1226 | strm->msg = (char *)"incorrect length check"; |
1226 | state->mode = BAD; | 1227 | state->mode = BAD; |
1227 | break; | 1228 | break; |
@@ -1401,6 +1402,7 @@ int ZEXPORT inflateSync(strm) | |||
1401 | z_streamp strm; | 1402 | z_streamp strm; |
1402 | { | 1403 | { |
1403 | unsigned len; /* number of bytes to look at or looked at */ | 1404 | unsigned len; /* number of bytes to look at or looked at */ |
1405 | int flags; /* temporary to save header status */ | ||
1404 | unsigned long in, out; /* temporary to save total_in and total_out */ | 1406 | unsigned long in, out; /* temporary to save total_in and total_out */ |
1405 | unsigned char buf[4]; /* to restore bit buffer to byte string */ | 1407 | unsigned char buf[4]; /* to restore bit buffer to byte string */ |
1406 | struct inflate_state FAR *state; | 1408 | struct inflate_state FAR *state; |
@@ -1433,11 +1435,15 @@ z_streamp strm; | |||
1433 | 1435 | ||
1434 | /* return no joy or set up to restart inflate() on a new block */ | 1436 | /* return no joy or set up to restart inflate() on a new block */ |
1435 | if (state->have != 4) return Z_DATA_ERROR; | 1437 | if (state->have != 4) return Z_DATA_ERROR; |
1436 | if (state->mode == HEAD) | 1438 | if (state->flags == -1) |
1437 | state->wrap = 0; /* never processed header, so assume raw */ | 1439 | state->wrap = 0; /* if no header yet, treat as raw */ |
1440 | else | ||
1441 | state->wrap &= ~4; /* no point in computing a check value now */ | ||
1442 | flags = state->flags; | ||
1438 | in = strm->total_in; out = strm->total_out; | 1443 | in = strm->total_in; out = strm->total_out; |
1439 | inflateReset(strm); | 1444 | inflateReset(strm); |
1440 | strm->total_in = in; strm->total_out = out; | 1445 | strm->total_in = in; strm->total_out = out; |
1446 | state->flags = flags; | ||
1441 | state->mode = TYPE; | 1447 | state->mode = TYPE; |
1442 | return Z_OK; | 1448 | return Z_OK; |
1443 | } | 1449 | } |