summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2019-01-02 18:10:40 -0800
committerMark Adler <madler@alumni.caltech.edu>2019-01-02 20:40:40 -0800
commit0d36ec47f310478549c0864f215ab5c0114c49ba (patch)
tree19821ce1a005e7a5741b65e27ef6a83d8a7a565f
parent7c0c75e990ca5395139c148f120042048b0ce091 (diff)
downloadzlib-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.
-rw-r--r--inflate.c14
-rw-r--r--inflate.h3
-rw-r--r--test/example.c5
3 files changed, 14 insertions, 8 deletions
diff --git a/inflate.c b/inflate.c
index 575fcdf..2c1b17f 100644
--- a/inflate.c
+++ b/inflate.c
@@ -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)
1401z_streamp strm; 1402z_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}
diff --git a/inflate.h b/inflate.h
index a46cce6..98679fa 100644
--- a/inflate.h
+++ b/inflate.h
@@ -86,7 +86,8 @@ struct inflate_state {
86 int wrap; /* bit 0 true for zlib, bit 1 true for gzip, 86 int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
87 bit 2 true to validate check value */ 87 bit 2 true to validate check value */
88 int havedict; /* true if dictionary provided */ 88 int havedict; /* true if dictionary provided */
89 int flags; /* gzip header method and flags (0 if zlib) */ 89 int flags; /* gzip header method and flags, 0 if zlib, or
90 -1 if raw or no header yet */
90 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ 91 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
91 unsigned long check; /* protected copy of check value */ 92 unsigned long check; /* protected copy of check value */
92 unsigned long total; /* protected copy of output count */ 93 unsigned long total; /* protected copy of output count */
diff --git a/test/example.c b/test/example.c
index eee17ce..949f4f6 100644
--- a/test/example.c
+++ b/test/example.c
@@ -440,9 +440,8 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
440 CHECK_ERR(err, "inflateSync"); 440 CHECK_ERR(err, "inflateSync");
441 441
442 err = inflate(&d_stream, Z_FINISH); 442 err = inflate(&d_stream, Z_FINISH);
443 if (err != Z_DATA_ERROR) { 443 if (err != Z_STREAM_END) {
444 fprintf(stderr, "inflate should report DATA_ERROR\n"); 444 fprintf(stderr, "inflate should report Z_STREAM_END\n");
445 /* Because of incorrect adler32 */
446 exit(1); 445 exit(1);
447 } 446 }
448 err = inflateEnd(&d_stream); 447 err = inflateEnd(&d_stream);