75{
77 unsigned char FAR *in;
79 unsigned char FAR *out;
80 unsigned char FAR *beg;
81 unsigned char FAR *end;
82#ifdef INFLATE_STRICT
84#endif
90 unsigned bits;
93 unsigned lmask;
94 unsigned dmask;
96 unsigned op;
97
98 unsigned len;
99 unsigned dist;
100 unsigned char FAR *from;
101
102
104 in = strm->next_in -
OFF;
105 last = in + (strm->avail_in - 5);
106 out = strm->next_out -
OFF;
107 beg = out - (start - strm->avail_out);
108 end = out + (strm->avail_out - 257);
109#ifdef INFLATE_STRICT
111#endif
112 wsize = state->wsize;
113 whave = state->whave;
114 wnext = state->wnext;
117 bits = state->bits;
118 lcode = state->lencode;
119 dcode = state->distcode;
120 lmask = (1U << state->lenbits) - 1;
121 dmask = (1U << state->distbits) - 1;
122
123
124
125 do {
126 if (bits < 15) {
127 hold += (
unsigned long)(
PUP(in)) << bits;
128 bits += 8;
129 hold += (
unsigned long)(
PUP(in)) << bits;
130 bits += 8;
131 }
132 here = lcode[
hold & lmask];
133 dolen:
134 op = (unsigned)(here.bits);
136 bits -= op;
137 op = (unsigned)(here.op);
138 if (op == 0) {
139 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
140 "inflate: literal '%c'\n" :
141 "inflate: literal 0x%02x\n", here.val));
142 PUP(out) = (
unsigned char)(here.val);
143 }
144 else if (op & 16) {
145 len = (unsigned)(here.val);
146 op &= 15;
147 if (op) {
148 if (bits < op) {
149 hold += (
unsigned long)(
PUP(in)) << bits;
150 bits += 8;
151 }
152 len += (unsigned)
hold & ((1U << op) - 1);
154 bits -= op;
155 }
156 Tracevv((stderr,
"inflate: length %u\n", len));
157 if (bits < 15) {
158 hold += (
unsigned long)(
PUP(in)) << bits;
159 bits += 8;
160 hold += (
unsigned long)(
PUP(in)) << bits;
161 bits += 8;
162 }
163 here = dcode[
hold & dmask];
164 dodist:
165 op = (unsigned)(here.bits);
167 bits -= op;
168 op = (unsigned)(here.op);
169 if (op & 16) {
170 dist = (unsigned)(here.val);
171 op &= 15;
172 if (bits < op) {
173 hold += (
unsigned long)(
PUP(in)) << bits;
174 bits += 8;
175 if (bits < op) {
176 hold += (
unsigned long)(
PUP(in)) << bits;
177 bits += 8;
178 }
179 }
180 dist += (unsigned)
hold & ((1U << op) - 1);
181#ifdef INFLATE_STRICT
183 strm->msg = (char *)"invalid distance too far back";
185 break;
186 }
187#endif
189 bits -= op;
190 Tracevv((stderr,
"inflate: distance %u\n", dist));
191 op = (unsigned)(out - beg);
192 if (dist > op) {
193 op = dist - op;
195 if (state->sane) {
196 strm->msg =
197 (char *)"invalid distance too far back";
199 break;
200 }
201#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
202 if (len <= op -
whave) {
203 do {
205 } while (--len);
206 continue;
207 }
209 do {
211 }
while (--op >
whave);
212 if (op == 0) {
213 from = out - dist;
214 do {
216 } while (--len);
217 continue;
218 }
219#endif
220 }
224 if (op < len) {
225 len -= op;
226 do {
228 } while (--op);
229 from = out - dist;
230 }
231 }
232 else if (
wnext < op) {
235 if (op < len) {
236 len -= op;
237 do {
239 } while (--op);
243 len -= op;
244 do {
246 } while (--op);
247 from = out - dist;
248 }
249 }
250 }
251 else {
253 if (op < len) {
254 len -= op;
255 do {
257 } while (--op);
258 from = out - dist;
259 }
260 }
261 while (len > 2) {
265 len -= 3;
266 }
267 if (len) {
269 if (len > 1)
271 }
272 }
273 else {
274 from = out - dist;
275 do {
279 len -= 3;
280 } while (len > 2);
281 if (len) {
283 if (len > 1)
285 }
286 }
287 }
288 else if ((op & 64) == 0) {
289 here = dcode[here.val + (
hold & ((1U << op) - 1))];
290 goto dodist;
291 }
292 else {
293 strm->msg = (char *)"invalid distance code";
295 break;
296 }
297 }
298 else if ((op & 64) == 0) {
299 here = lcode[here.val + (
hold & ((1U << op) - 1))];
300 goto dolen;
301 }
302 else if (op & 32) {
303 Tracevv((stderr,
"inflate: end of block\n"));
305 break;
306 }
307 else {
308 strm->msg = (char *)"invalid literal/length code";
310 break;
311 }
312 }
while (in <
last && out < end);
313
314
315 len = bits >> 3;
316 in -= len;
317 bits -= len << 3;
318 hold &= (1U << bits) - 1;
319
320
321 strm->next_in = in +
OFF;
322 strm->next_out = out +
OFF;
323 strm->avail_in = (unsigned)(in <
last ? 5 + (
last - in) : 5 - (in -
last));
324 strm->avail_out = (unsigned)(out < end ?
325 257 + (end - out) : 257 - (out - end));
327 state->bits = bits;
328 return;
329}
unsigned char FAR * window