aboutsummaryrefslogtreecommitdiff
path: root/inflate.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:40 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:40 -0700
commitf6194ef39af5864f792412460c354cc339dde7d1 (patch)
tree5ea1e6849128e9b2194c66ee3d82afa36b4ac07c /inflate.c
parent639be997883d9016baaf46017a2802b2ce1698bd (diff)
downloadzlib-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.c136
1 files changed, 108 insertions, 28 deletions
diff --git a/inflate.c b/inflate.c
index d3c718c..d069bbe 100644
--- a/inflate.c
+++ b/inflate.c
@@ -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
129int ZEXPORT inflatePrime(strm, bits, value) 130int ZEXPORT inflateReset2(strm, windowBits)
130z_streamp strm; 131z_streamp strm;
131int bits; 132int windowBits;
132int 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
145int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 168int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
@@ -148,6 +171,7 @@ int windowBits;
148const char *version; 171const char *version;
149int stream_size; 172int 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
188int ZEXPORT inflateInit_(strm, version, stream_size) 201int 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
209int ZEXPORT inflatePrime(strm, bits, value)
210z_streamp strm;
211int bits;
212int 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
1471long ZEXPORT inflateMark(strm)
1472z_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}