diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:26:40 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:26:40 -0700 |
commit | f6194ef39af5864f792412460c354cc339dde7d1 (patch) | |
tree | 5ea1e6849128e9b2194c66ee3d82afa36b4ac07c /inflate.c | |
parent | 639be997883d9016baaf46017a2802b2ce1698bd (diff) | |
download | zlib-f6194ef39af5864f792412460c354cc339dde7d1.tar.gz zlib-f6194ef39af5864f792412460c354cc339dde7d1.tar.bz2 zlib-f6194ef39af5864f792412460c354cc339dde7d1.zip |
zlib 1.2.3.4v1.2.3.4
Diffstat (limited to 'inflate.c')
-rw-r--r-- | inflate.c | 136 |
1 files changed, 108 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* inflate.c -- zlib decompression | 1 | /* inflate.c -- zlib decompression |
2 | * Copyright (C) 1995-2006 Mark Adler | 2 | * Copyright (C) 1995-2009 Mark Adler |
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -122,24 +122,47 @@ z_streamp strm; | |||
122 | state->bits = 0; | 122 | state->bits = 0; |
123 | state->lencode = state->distcode = state->next = state->codes; | 123 | state->lencode = state->distcode = state->next = state->codes; |
124 | state->sane = 1; | 124 | state->sane = 1; |
125 | state->back = -1; | ||
125 | Tracev((stderr, "inflate: reset\n")); | 126 | Tracev((stderr, "inflate: reset\n")); |
126 | return Z_OK; | 127 | return Z_OK; |
127 | } | 128 | } |
128 | 129 | ||
129 | int ZEXPORT inflatePrime(strm, bits, value) | 130 | int ZEXPORT inflateReset2(strm, windowBits) |
130 | z_streamp strm; | 131 | z_streamp strm; |
131 | int bits; | 132 | int windowBits; |
132 | int value; | ||
133 | { | 133 | { |
134 | int wrap; | ||
134 | struct inflate_state FAR *state; | 135 | struct inflate_state FAR *state; |
135 | 136 | ||
137 | /* get the state */ | ||
136 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 138 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
137 | state = (struct inflate_state FAR *)strm->state; | 139 | state = (struct inflate_state FAR *)strm->state; |
138 | if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; | 140 | |
139 | value &= (1L << bits) - 1; | 141 | /* extract wrap request from windowBits parameter */ |
140 | state->hold += value << state->bits; | 142 | if (windowBits < 0) { |
141 | state->bits += bits; | 143 | wrap = 0; |
142 | return Z_OK; | 144 | windowBits = -windowBits; |
145 | } | ||
146 | else { | ||
147 | wrap = (windowBits >> 4) + 1; | ||
148 | #ifdef GUNZIP | ||
149 | if (windowBits < 48) | ||
150 | windowBits &= 15; | ||
151 | #endif | ||
152 | } | ||
153 | |||
154 | /* set number of window bits, free window if different */ | ||
155 | if (windowBits < 8 || windowBits > 15) | ||
156 | return Z_STREAM_ERROR; | ||
157 | if (state->wbits != windowBits && state->window != Z_NULL) { | ||
158 | ZFREE(strm, state->window); | ||
159 | state->window = Z_NULL; | ||
160 | } | ||
161 | |||
162 | /* update state and reset the rest of it */ | ||
163 | state->wrap = wrap; | ||
164 | state->wbits = (unsigned)windowBits; | ||
165 | return inflateReset(strm); | ||
143 | } | 166 | } |
144 | 167 | ||
145 | int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) | 168 | int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) |
@@ -148,6 +171,7 @@ int windowBits; | |||
148 | const char *version; | 171 | const char *version; |
149 | int stream_size; | 172 | int stream_size; |
150 | { | 173 | { |
174 | int ret; | ||
151 | struct inflate_state FAR *state; | 175 | struct inflate_state FAR *state; |
152 | 176 | ||
153 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || | 177 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || |
@@ -165,24 +189,13 @@ int stream_size; | |||
165 | if (state == Z_NULL) return Z_MEM_ERROR; | 189 | if (state == Z_NULL) return Z_MEM_ERROR; |
166 | Tracev((stderr, "inflate: allocated\n")); | 190 | Tracev((stderr, "inflate: allocated\n")); |
167 | strm->state = (struct internal_state FAR *)state; | 191 | strm->state = (struct internal_state FAR *)state; |
168 | if (windowBits < 0) { | 192 | state->window = Z_NULL; |
169 | state->wrap = 0; | 193 | ret = inflateReset2(strm, windowBits); |
170 | windowBits = -windowBits; | 194 | if (ret != Z_OK) { |
171 | } | ||
172 | else { | ||
173 | state->wrap = (windowBits >> 4) + 1; | ||
174 | #ifdef GUNZIP | ||
175 | if (windowBits < 48) windowBits &= 15; | ||
176 | #endif | ||
177 | } | ||
178 | if (windowBits < 8 || windowBits > 15) { | ||
179 | ZFREE(strm, state); | 195 | ZFREE(strm, state); |
180 | strm->state = Z_NULL; | 196 | strm->state = Z_NULL; |
181 | return Z_STREAM_ERROR; | ||
182 | } | 197 | } |
183 | state->wbits = (unsigned)windowBits; | 198 | return ret; |
184 | state->window = Z_NULL; | ||
185 | return inflateReset(strm); | ||
186 | } | 199 | } |
187 | 200 | ||
188 | int ZEXPORT inflateInit_(strm, version, stream_size) | 201 | int ZEXPORT inflateInit_(strm, version, stream_size) |
@@ -193,6 +206,27 @@ int stream_size; | |||
193 | return inflateInit2_(strm, DEF_WBITS, version, stream_size); | 206 | return inflateInit2_(strm, DEF_WBITS, version, stream_size); |
194 | } | 207 | } |
195 | 208 | ||
209 | int ZEXPORT inflatePrime(strm, bits, value) | ||
210 | z_streamp strm; | ||
211 | int bits; | ||
212 | int value; | ||
213 | { | ||
214 | struct inflate_state FAR *state; | ||
215 | |||
216 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | ||
217 | state = (struct inflate_state FAR *)strm->state; | ||
218 | if (bits < 0) { | ||
219 | state->hold = 0; | ||
220 | state->bits = 0; | ||
221 | return Z_OK; | ||
222 | } | ||
223 | if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; | ||
224 | value &= (1L << bits) - 1; | ||
225 | state->hold += value << state->bits; | ||
226 | state->bits += bits; | ||
227 | return Z_OK; | ||
228 | } | ||
229 | |||
196 | /* | 230 | /* |
197 | Return state with length and distance decoding tables and index sizes set to | 231 | Return state with length and distance decoding tables and index sizes set to |
198 | fixed code decoding. Normally this returns fixed tables from inffixed.h. | 232 | fixed code decoding. Normally this returns fixed tables from inffixed.h. |
@@ -772,7 +806,7 @@ int flush; | |||
772 | strm->adler = state->check = adler32(0L, Z_NULL, 0); | 806 | strm->adler = state->check = adler32(0L, Z_NULL, 0); |
773 | state->mode = TYPE; | 807 | state->mode = TYPE; |
774 | case TYPE: | 808 | case TYPE: |
775 | if (flush == Z_BLOCK) goto inf_leave; | 809 | if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; |
776 | case TYPEDO: | 810 | case TYPEDO: |
777 | if (state->last) { | 811 | if (state->last) { |
778 | BYTEBITS(); | 812 | BYTEBITS(); |
@@ -792,7 +826,11 @@ int flush; | |||
792 | fixedtables(state); | 826 | fixedtables(state); |
793 | Tracev((stderr, "inflate: fixed codes block%s\n", | 827 | Tracev((stderr, "inflate: fixed codes block%s\n", |
794 | state->last ? " (last)" : "")); | 828 | state->last ? " (last)" : "")); |
795 | state->mode = LEN; /* decode codes */ | 829 | state->mode = LEN_; /* decode codes */ |
830 | if (flush == Z_TREES) { | ||
831 | DROPBITS(2); | ||
832 | goto inf_leave; | ||
833 | } | ||
796 | break; | 834 | break; |
797 | case 2: /* dynamic block */ | 835 | case 2: /* dynamic block */ |
798 | Tracev((stderr, "inflate: dynamic codes block%s\n", | 836 | Tracev((stderr, "inflate: dynamic codes block%s\n", |
@@ -817,6 +855,9 @@ int flush; | |||
817 | Tracev((stderr, "inflate: stored length %u\n", | 855 | Tracev((stderr, "inflate: stored length %u\n", |
818 | state->length)); | 856 | state->length)); |
819 | INITBITS(); | 857 | INITBITS(); |
858 | state->mode = COPY_; | ||
859 | if (flush == Z_TREES) goto inf_leave; | ||
860 | case COPY_: | ||
820 | state->mode = COPY; | 861 | state->mode = COPY; |
821 | case COPY: | 862 | case COPY: |
822 | copy = state->length; | 863 | copy = state->length; |
@@ -926,7 +967,16 @@ int flush; | |||
926 | /* handle error breaks in while */ | 967 | /* handle error breaks in while */ |
927 | if (state->mode == BAD) break; | 968 | if (state->mode == BAD) break; |
928 | 969 | ||
929 | /* build code tables */ | 970 | /* check for end-of-block code (better have one) */ |
971 | if (state->lens[256] == 0) { | ||
972 | strm->msg = (char *)"invalid code -- missing end-of-block"; | ||
973 | state->mode = BAD; | ||
974 | break; | ||
975 | } | ||
976 | |||
977 | /* build code tables -- note: do not change the lenbits or distbits | ||
978 | values here (9 and 6) without reading the comments in inftrees.h | ||
979 | concerning the ENOUGH constants, which depend on those values */ | ||
930 | state->next = state->codes; | 980 | state->next = state->codes; |
931 | state->lencode = (code const FAR *)(state->next); | 981 | state->lencode = (code const FAR *)(state->next); |
932 | state->lenbits = 9; | 982 | state->lenbits = 9; |
@@ -947,14 +997,20 @@ int flush; | |||
947 | break; | 997 | break; |
948 | } | 998 | } |
949 | Tracev((stderr, "inflate: codes ok\n")); | 999 | Tracev((stderr, "inflate: codes ok\n")); |
1000 | state->mode = LEN_; | ||
1001 | if (flush == Z_TREES) goto inf_leave; | ||
1002 | case LEN_: | ||
950 | state->mode = LEN; | 1003 | state->mode = LEN; |
951 | case LEN: | 1004 | case LEN: |
952 | if (have >= 6 && left >= 258) { | 1005 | if (have >= 6 && left >= 258) { |
953 | RESTORE(); | 1006 | RESTORE(); |
954 | inflate_fast(strm, out); | 1007 | inflate_fast(strm, out); |
955 | LOAD(); | 1008 | LOAD(); |
1009 | if (state->mode == TYPE) | ||
1010 | state->back = -1; | ||
956 | break; | 1011 | break; |
957 | } | 1012 | } |
1013 | state->back = 0; | ||
958 | for (;;) { | 1014 | for (;;) { |
959 | here = state->lencode[BITS(state->lenbits)]; | 1015 | here = state->lencode[BITS(state->lenbits)]; |
960 | if ((unsigned)(here.bits) <= bits) break; | 1016 | if ((unsigned)(here.bits) <= bits) break; |
@@ -969,8 +1025,10 @@ int flush; | |||
969 | PULLBYTE(); | 1025 | PULLBYTE(); |
970 | } | 1026 | } |
971 | DROPBITS(last.bits); | 1027 | DROPBITS(last.bits); |
1028 | state->back += last.bits; | ||
972 | } | 1029 | } |
973 | DROPBITS(here.bits); | 1030 | DROPBITS(here.bits); |
1031 | state->back += here.bits; | ||
974 | state->length = (unsigned)here.val; | 1032 | state->length = (unsigned)here.val; |
975 | if ((int)(here.op) == 0) { | 1033 | if ((int)(here.op) == 0) { |
976 | Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? | 1034 | Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
@@ -981,6 +1039,7 @@ int flush; | |||
981 | } | 1039 | } |
982 | if (here.op & 32) { | 1040 | if (here.op & 32) { |
983 | Tracevv((stderr, "inflate: end of block\n")); | 1041 | Tracevv((stderr, "inflate: end of block\n")); |
1042 | state->back = -1; | ||
984 | state->mode = TYPE; | 1043 | state->mode = TYPE; |
985 | break; | 1044 | break; |
986 | } | 1045 | } |
@@ -996,8 +1055,10 @@ int flush; | |||
996 | NEEDBITS(state->extra); | 1055 | NEEDBITS(state->extra); |
997 | state->length += BITS(state->extra); | 1056 | state->length += BITS(state->extra); |
998 | DROPBITS(state->extra); | 1057 | DROPBITS(state->extra); |
1058 | state->back += state->extra; | ||
999 | } | 1059 | } |
1000 | Tracevv((stderr, "inflate: length %u\n", state->length)); | 1060 | Tracevv((stderr, "inflate: length %u\n", state->length)); |
1061 | state->was = state->length; | ||
1001 | state->mode = DIST; | 1062 | state->mode = DIST; |
1002 | case DIST: | 1063 | case DIST: |
1003 | for (;;) { | 1064 | for (;;) { |
@@ -1014,8 +1075,10 @@ int flush; | |||
1014 | PULLBYTE(); | 1075 | PULLBYTE(); |
1015 | } | 1076 | } |
1016 | DROPBITS(last.bits); | 1077 | DROPBITS(last.bits); |
1078 | state->back += last.bits; | ||
1017 | } | 1079 | } |
1018 | DROPBITS(here.bits); | 1080 | DROPBITS(here.bits); |
1081 | state->back += here.bits; | ||
1019 | if (here.op & 64) { | 1082 | if (here.op & 64) { |
1020 | strm->msg = (char *)"invalid distance code"; | 1083 | strm->msg = (char *)"invalid distance code"; |
1021 | state->mode = BAD; | 1084 | state->mode = BAD; |
@@ -1029,6 +1092,7 @@ int flush; | |||
1029 | NEEDBITS(state->extra); | 1092 | NEEDBITS(state->extra); |
1030 | state->offset += BITS(state->extra); | 1093 | state->offset += BITS(state->extra); |
1031 | DROPBITS(state->extra); | 1094 | DROPBITS(state->extra); |
1095 | state->back += state->extra; | ||
1032 | } | 1096 | } |
1033 | #ifdef INFLATE_STRICT | 1097 | #ifdef INFLATE_STRICT |
1034 | if (state->offset > state->dmax) { | 1098 | if (state->offset > state->dmax) { |
@@ -1066,6 +1130,9 @@ int flush; | |||
1066 | } | 1130 | } |
1067 | if (copy > state->write) { | 1131 | if (copy > state->write) { |
1068 | copy -= state->write; | 1132 | copy -= state->write; |
1133 | /* %% problem here if copy > state->wsize -- avoid? */ | ||
1134 | /* %% or can (state->window + state->wsize) - copy */ | ||
1135 | /* %% but really should detect and reject this case */ | ||
1069 | from = state->window + (state->wsize - copy); | 1136 | from = state->window + (state->wsize - copy); |
1070 | } | 1137 | } |
1071 | else | 1138 | else |
@@ -1162,7 +1229,8 @@ int flush; | |||
1162 | strm->adler = state->check = | 1229 | strm->adler = state->check = |
1163 | UPDATE(state->check, strm->next_out - out, out); | 1230 | UPDATE(state->check, strm->next_out - out, out); |
1164 | strm->data_type = state->bits + (state->last ? 64 : 0) + | 1231 | strm->data_type = state->bits + (state->last ? 64 : 0) + |
1165 | (state->mode == TYPE ? 128 : 0); | 1232 | (state->mode == TYPE ? 128 : 0) + |
1233 | (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); | ||
1166 | if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) | 1234 | if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) |
1167 | ret = Z_BUF_ERROR; | 1235 | ret = Z_BUF_ERROR; |
1168 | return ret; | 1236 | return ret; |
@@ -1399,3 +1467,15 @@ int subvert; | |||
1399 | return Z_DATA_ERROR; | 1467 | return Z_DATA_ERROR; |
1400 | #endif | 1468 | #endif |
1401 | } | 1469 | } |
1470 | |||
1471 | long ZEXPORT inflateMark(strm) | ||
1472 | z_streamp strm; | ||
1473 | { | ||
1474 | struct inflate_state FAR *state; | ||
1475 | |||
1476 | if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; | ||
1477 | state = (struct inflate_state FAR *)strm->state; | ||
1478 | return ((long)(state->back) << 16) + | ||
1479 | (state->mode == COPY ? state->length : | ||
1480 | (state->mode == MATCH ? state->was - state->length : 0)); | ||
1481 | } | ||