File indexing completed on 2025-05-11 08:24:11
0001
0002
0003
0004
0005
0006 #include "zutil.h"
0007 #include "inftrees.h"
0008 #include "inflate.h"
0009 #include "inffast.h"
0010
0011 #ifdef ASMINF
0012 # pragma message("Assembler code may have bugs -- use at your own risk")
0013 #else
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 void ZLIB_INTERNAL inflate_fast(strm, start)
0051 z_streamp strm;
0052 unsigned start;
0053 {
0054 struct inflate_state FAR *state;
0055 z_const unsigned char FAR *in;
0056 z_const unsigned char FAR *last;
0057 unsigned char FAR *out;
0058 unsigned char FAR *beg;
0059 unsigned char FAR *end;
0060 #ifdef INFLATE_STRICT
0061 unsigned dmax;
0062 #endif
0063 unsigned wsize;
0064 unsigned whave;
0065 unsigned wnext;
0066 unsigned char FAR *window;
0067 unsigned long hold;
0068 unsigned bits;
0069 code const FAR *lcode;
0070 code const FAR *dcode;
0071 unsigned lmask;
0072 unsigned dmask;
0073 code const *here;
0074 unsigned op;
0075
0076 unsigned len;
0077 unsigned dist;
0078 unsigned char FAR *from;
0079
0080
0081 state = (struct inflate_state FAR *)strm->state;
0082 in = strm->next_in;
0083 last = in + (strm->avail_in - 5);
0084 out = strm->next_out;
0085 beg = out - (start - strm->avail_out);
0086 end = out + (strm->avail_out - 257);
0087 #ifdef INFLATE_STRICT
0088 dmax = state->dmax;
0089 #endif
0090 wsize = state->wsize;
0091 whave = state->whave;
0092 wnext = state->wnext;
0093 window = state->window;
0094 hold = state->hold;
0095 bits = state->bits;
0096 lcode = state->lencode;
0097 dcode = state->distcode;
0098 lmask = (1U << state->lenbits) - 1;
0099 dmask = (1U << state->distbits) - 1;
0100
0101
0102
0103 do {
0104 if (bits < 15) {
0105 hold += (unsigned long)(*in++) << bits;
0106 bits += 8;
0107 hold += (unsigned long)(*in++) << bits;
0108 bits += 8;
0109 }
0110 here = lcode + (hold & lmask);
0111 dolen:
0112 op = (unsigned)(here->bits);
0113 hold >>= op;
0114 bits -= op;
0115 op = (unsigned)(here->op);
0116 if (op == 0) {
0117 Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
0118 "inflate: literal '%c'\n" :
0119 "inflate: literal 0x%02x\n", here->val));
0120 *out++ = (unsigned char)(here->val);
0121 }
0122 else if (op & 16) {
0123 len = (unsigned)(here->val);
0124 op &= 15;
0125 if (op) {
0126 if (bits < op) {
0127 hold += (unsigned long)(*in++) << bits;
0128 bits += 8;
0129 }
0130 len += (unsigned)hold & ((1U << op) - 1);
0131 hold >>= op;
0132 bits -= op;
0133 }
0134 Tracevv((stderr, "inflate: length %u\n", len));
0135 if (bits < 15) {
0136 hold += (unsigned long)(*in++) << bits;
0137 bits += 8;
0138 hold += (unsigned long)(*in++) << bits;
0139 bits += 8;
0140 }
0141 here = dcode + (hold & dmask);
0142 dodist:
0143 op = (unsigned)(here->bits);
0144 hold >>= op;
0145 bits -= op;
0146 op = (unsigned)(here->op);
0147 if (op & 16) {
0148 dist = (unsigned)(here->val);
0149 op &= 15;
0150 if (bits < op) {
0151 hold += (unsigned long)(*in++) << bits;
0152 bits += 8;
0153 if (bits < op) {
0154 hold += (unsigned long)(*in++) << bits;
0155 bits += 8;
0156 }
0157 }
0158 dist += (unsigned)hold & ((1U << op) - 1);
0159 #ifdef INFLATE_STRICT
0160 if (dist > dmax) {
0161 strm->msg = (char *)"invalid distance too far back";
0162 state->mode = BAD;
0163 break;
0164 }
0165 #endif
0166 hold >>= op;
0167 bits -= op;
0168 Tracevv((stderr, "inflate: distance %u\n", dist));
0169 op = (unsigned)(out - beg);
0170 if (dist > op) {
0171 op = dist - op;
0172 if (op > whave) {
0173 if (state->sane) {
0174 strm->msg =
0175 (char *)"invalid distance too far back";
0176 state->mode = BAD;
0177 break;
0178 }
0179 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
0180 if (len <= op - whave) {
0181 do {
0182 *out++ = 0;
0183 } while (--len);
0184 continue;
0185 }
0186 len -= op - whave;
0187 do {
0188 *out++ = 0;
0189 } while (--op > whave);
0190 if (op == 0) {
0191 from = out - dist;
0192 do {
0193 *out++ = *from++;
0194 } while (--len);
0195 continue;
0196 }
0197 #endif
0198 }
0199 from = window;
0200 if (wnext == 0) {
0201 from += wsize - op;
0202 if (op < len) {
0203 len -= op;
0204 do {
0205 *out++ = *from++;
0206 } while (--op);
0207 from = out - dist;
0208 }
0209 }
0210 else if (wnext < op) {
0211 from += wsize + wnext - op;
0212 op -= wnext;
0213 if (op < len) {
0214 len -= op;
0215 do {
0216 *out++ = *from++;
0217 } while (--op);
0218 from = window;
0219 if (wnext < len) {
0220 op = wnext;
0221 len -= op;
0222 do {
0223 *out++ = *from++;
0224 } while (--op);
0225 from = out - dist;
0226 }
0227 }
0228 }
0229 else {
0230 from += wnext - op;
0231 if (op < len) {
0232 len -= op;
0233 do {
0234 *out++ = *from++;
0235 } while (--op);
0236 from = out - dist;
0237 }
0238 }
0239 while (len > 2) {
0240 *out++ = *from++;
0241 *out++ = *from++;
0242 *out++ = *from++;
0243 len -= 3;
0244 }
0245 if (len) {
0246 *out++ = *from++;
0247 if (len > 1)
0248 *out++ = *from++;
0249 }
0250 }
0251 else {
0252 from = out - dist;
0253 do {
0254 *out++ = *from++;
0255 *out++ = *from++;
0256 *out++ = *from++;
0257 len -= 3;
0258 } while (len > 2);
0259 if (len) {
0260 *out++ = *from++;
0261 if (len > 1)
0262 *out++ = *from++;
0263 }
0264 }
0265 }
0266 else if ((op & 64) == 0) {
0267 here = dcode + here->val + (hold & ((1U << op) - 1));
0268 goto dodist;
0269 }
0270 else {
0271 strm->msg = (char *)"invalid distance code";
0272 state->mode = BAD;
0273 break;
0274 }
0275 }
0276 else if ((op & 64) == 0) {
0277 here = lcode + here->val + (hold & ((1U << op) - 1));
0278 goto dolen;
0279 }
0280 else if (op & 32) {
0281 Tracevv((stderr, "inflate: end of block\n"));
0282 state->mode = TYPE;
0283 break;
0284 }
0285 else {
0286 strm->msg = (char *)"invalid literal/length code";
0287 state->mode = BAD;
0288 break;
0289 }
0290 } while (in < last && out < end);
0291
0292
0293 len = bits >> 3;
0294 in -= len;
0295 bits -= len << 3;
0296 hold &= (1U << bits) - 1;
0297
0298
0299 strm->next_in = in;
0300 strm->next_out = out;
0301 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
0302 strm->avail_out = (unsigned)(out < end ?
0303 257 + (end - out) : 257 - (out - end));
0304 state->hold = hold;
0305 state->bits = bits;
0306 return;
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 #endif