diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2016-09-20 18:49:21 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2016-09-20 18:55:37 -0700 |
commit | 9852c209ac49c0d8d1192e46115d7c37d4344bbd (patch) | |
tree | 875f72cb5cbc1724f180cc866cef203ddbe3c075 /inflate.c | |
parent | 93b0af4aa73c8debe2cc18e56101700423096146 (diff) | |
download | zlib-9852c209ac49c0d8d1192e46115d7c37d4344bbd.tar.gz zlib-9852c209ac49c0d8d1192e46115d7c37d4344bbd.tar.bz2 zlib-9852c209ac49c0d8d1192e46115d7c37d4344bbd.zip |
Add option to not compute or check check values.
The undocumented (except in these commit comments) function
inflateValidate(strm, check) can be called after an inflateInit(),
inflateInit2(), or inflateReset2() with check equal to zero to
turn off the check value (CRC-32 or Adler-32) computation and
comparison. Calling with check not equal to zero turns checking
back on. This should only be called immediately after the init or
reset function. inflateReset() does not change the state, so a
previous inflateValidate() setting will remain in effect.
This also turns off validation of the gzip header CRC when
present.
This should only be used when a zlib or gzip stream has already
been checked, and repeated decompressions of the same stream no
longer need to be validated.
Diffstat (limited to 'inflate.c')
-rw-r--r-- | inflate.c | 43 |
1 files changed, 31 insertions, 12 deletions
@@ -156,7 +156,7 @@ int windowBits; | |||
156 | windowBits = -windowBits; | 156 | windowBits = -windowBits; |
157 | } | 157 | } |
158 | else { | 158 | else { |
159 | wrap = (windowBits >> 4) + 1; | 159 | wrap = (windowBits >> 4) + 5; |
160 | #ifdef GUNZIP | 160 | #ifdef GUNZIP |
161 | if (windowBits < 48) | 161 | if (windowBits < 48) |
162 | windowBits &= 15; | 162 | windowBits &= 15; |
@@ -701,14 +701,16 @@ int flush; | |||
701 | } | 701 | } |
702 | if (state->head != Z_NULL) | 702 | if (state->head != Z_NULL) |
703 | state->head->text = (int)((hold >> 8) & 1); | 703 | state->head->text = (int)((hold >> 8) & 1); |
704 | if (state->flags & 0x0200) CRC2(state->check, hold); | 704 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
705 | CRC2(state->check, hold); | ||
705 | INITBITS(); | 706 | INITBITS(); |
706 | state->mode = TIME; | 707 | state->mode = TIME; |
707 | case TIME: | 708 | case TIME: |
708 | NEEDBITS(32); | 709 | NEEDBITS(32); |
709 | if (state->head != Z_NULL) | 710 | if (state->head != Z_NULL) |
710 | state->head->time = hold; | 711 | state->head->time = hold; |
711 | if (state->flags & 0x0200) CRC4(state->check, hold); | 712 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
713 | CRC4(state->check, hold); | ||
712 | INITBITS(); | 714 | INITBITS(); |
713 | state->mode = OS; | 715 | state->mode = OS; |
714 | case OS: | 716 | case OS: |
@@ -717,7 +719,8 @@ int flush; | |||
717 | state->head->xflags = (int)(hold & 0xff); | 719 | state->head->xflags = (int)(hold & 0xff); |
718 | state->head->os = (int)(hold >> 8); | 720 | state->head->os = (int)(hold >> 8); |
719 | } | 721 | } |
720 | if (state->flags & 0x0200) CRC2(state->check, hold); | 722 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
723 | CRC2(state->check, hold); | ||
721 | INITBITS(); | 724 | INITBITS(); |
722 | state->mode = EXLEN; | 725 | state->mode = EXLEN; |
723 | case EXLEN: | 726 | case EXLEN: |
@@ -726,7 +729,8 @@ int flush; | |||
726 | state->length = (unsigned)(hold); | 729 | state->length = (unsigned)(hold); |
727 | if (state->head != Z_NULL) | 730 | if (state->head != Z_NULL) |
728 | state->head->extra_len = (unsigned)hold; | 731 | state->head->extra_len = (unsigned)hold; |
729 | if (state->flags & 0x0200) CRC2(state->check, hold); | 732 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
733 | CRC2(state->check, hold); | ||
730 | INITBITS(); | 734 | INITBITS(); |
731 | } | 735 | } |
732 | else if (state->head != Z_NULL) | 736 | else if (state->head != Z_NULL) |
@@ -744,7 +748,7 @@ int flush; | |||
744 | len + copy > state->head->extra_max ? | 748 | len + copy > state->head->extra_max ? |
745 | state->head->extra_max - len : copy); | 749 | state->head->extra_max - len : copy); |
746 | } | 750 | } |
747 | if (state->flags & 0x0200) | 751 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
748 | state->check = crc32(state->check, next, copy); | 752 | state->check = crc32(state->check, next, copy); |
749 | have -= copy; | 753 | have -= copy; |
750 | next += copy; | 754 | next += copy; |
@@ -765,7 +769,7 @@ int flush; | |||
765 | state->length < state->head->name_max) | 769 | state->length < state->head->name_max) |
766 | state->head->name[state->length++] = len; | 770 | state->head->name[state->length++] = len; |
767 | } while (len && copy < have); | 771 | } while (len && copy < have); |
768 | if (state->flags & 0x0200) | 772 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
769 | state->check = crc32(state->check, next, copy); | 773 | state->check = crc32(state->check, next, copy); |
770 | have -= copy; | 774 | have -= copy; |
771 | next += copy; | 775 | next += copy; |
@@ -786,7 +790,7 @@ int flush; | |||
786 | state->length < state->head->comm_max) | 790 | state->length < state->head->comm_max) |
787 | state->head->comment[state->length++] = len; | 791 | state->head->comment[state->length++] = len; |
788 | } while (len && copy < have); | 792 | } while (len && copy < have); |
789 | if (state->flags & 0x0200) | 793 | if ((state->flags & 0x0200) && (state->wrap & 4)) |
790 | state->check = crc32(state->check, next, copy); | 794 | state->check = crc32(state->check, next, copy); |
791 | have -= copy; | 795 | have -= copy; |
792 | next += copy; | 796 | next += copy; |
@@ -798,7 +802,7 @@ int flush; | |||
798 | case HCRC: | 802 | case HCRC: |
799 | if (state->flags & 0x0200) { | 803 | if (state->flags & 0x0200) { |
800 | NEEDBITS(16); | 804 | NEEDBITS(16); |
801 | if (hold != (state->check & 0xffff)) { | 805 | if ((state->wrap & 4) && hold != (state->check & 0xffff)) { |
802 | strm->msg = (char *)"header crc mismatch"; | 806 | strm->msg = (char *)"header crc mismatch"; |
803 | state->mode = BAD; | 807 | state->mode = BAD; |
804 | break; | 808 | break; |
@@ -1179,11 +1183,11 @@ int flush; | |||
1179 | out -= left; | 1183 | out -= left; |
1180 | strm->total_out += out; | 1184 | strm->total_out += out; |
1181 | state->total += out; | 1185 | state->total += out; |
1182 | if (out) | 1186 | if ((state->wrap & 4) && out) |
1183 | strm->adler = state->check = | 1187 | strm->adler = state->check = |
1184 | UPDATE(state->check, put - out, out); | 1188 | UPDATE(state->check, put - out, out); |
1185 | out = left; | 1189 | out = left; |
1186 | if (( | 1190 | if ((state->wrap & 4) && ( |
1187 | #ifdef GUNZIP | 1191 | #ifdef GUNZIP |
1188 | state->flags ? hold : | 1192 | state->flags ? hold : |
1189 | #endif | 1193 | #endif |
@@ -1242,7 +1246,7 @@ int flush; | |||
1242 | strm->total_in += in; | 1246 | strm->total_in += in; |
1243 | strm->total_out += out; | 1247 | strm->total_out += out; |
1244 | state->total += out; | 1248 | state->total += out; |
1245 | if (state->wrap && out) | 1249 | if ((state->wrap & 4) && out) |
1246 | strm->adler = state->check = | 1250 | strm->adler = state->check = |
1247 | UPDATE(state->check, strm->next_out - out, out); | 1251 | UPDATE(state->check, strm->next_out - out, out); |
1248 | strm->data_type = state->bits + (state->last ? 64 : 0) + | 1252 | strm->data_type = state->bits + (state->last ? 64 : 0) + |
@@ -1501,6 +1505,21 @@ int subvert; | |||
1501 | #endif | 1505 | #endif |
1502 | } | 1506 | } |
1503 | 1507 | ||
1508 | int ZEXPORT inflateValidate(strm, check) | ||
1509 | z_streamp strm; | ||
1510 | int check; | ||
1511 | { | ||
1512 | struct inflate_state FAR *state; | ||
1513 | |||
1514 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | ||
1515 | state = (struct inflate_state FAR *)strm->state; | ||
1516 | if (check) | ||
1517 | state->wrap |= 4; | ||
1518 | else | ||
1519 | state->wrap &= ~4; | ||
1520 | return Z_OK; | ||
1521 | } | ||
1522 | |||
1504 | long ZEXPORT inflateMark(strm) | 1523 | long ZEXPORT inflateMark(strm) |
1505 | z_streamp strm; | 1524 | z_streamp strm; |
1506 | { | 1525 | { |