aboutsummaryrefslogtreecommitdiff
path: root/inffast.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:29 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:29 -0700
commit639be997883d9016baaf46017a2802b2ce1698bd (patch)
treedb90fc577d10564b335980824111e8d11c5527e2 /inffast.c
parentd6231142d2b883a8c3b253fa34992b5cdb4ac2fe (diff)
downloadzlib-639be997883d9016baaf46017a2802b2ce1698bd.tar.gz
zlib-639be997883d9016baaf46017a2802b2ce1698bd.tar.bz2
zlib-639be997883d9016baaf46017a2802b2ce1698bd.zip
zlib 1.2.3.3v1.2.3.3
Diffstat (limited to 'inffast.c')
-rw-r--r--inffast.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/inffast.c b/inffast.c
index bbee92e..0b919bb 100644
--- a/inffast.c
+++ b/inffast.c
@@ -1,5 +1,5 @@
1/* inffast.c -- fast decoding 1/* inffast.c -- fast decoding
2 * Copyright (C) 1995-2004 Mark Adler 2 * Copyright (C) 1995-2006 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
@@ -87,7 +87,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
87 code const FAR *dcode; /* local strm->distcode */ 87 code const FAR *dcode; /* local strm->distcode */
88 unsigned lmask; /* mask for first level of length codes */ 88 unsigned lmask; /* mask for first level of length codes */
89 unsigned dmask; /* mask for first level of distance codes */ 89 unsigned dmask; /* mask for first level of distance codes */
90 code this; /* retrieved table entry */ 90 code here; /* retrieved table entry */
91 unsigned op; /* code bits, operation, extra bits, or */ 91 unsigned op; /* code bits, operation, extra bits, or */
92 /* window position, window bytes to copy */ 92 /* window position, window bytes to copy */
93 unsigned len; /* match length, unused bytes */ 93 unsigned len; /* match length, unused bytes */
@@ -124,20 +124,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
124 hold += (unsigned long)(PUP(in)) << bits; 124 hold += (unsigned long)(PUP(in)) << bits;
125 bits += 8; 125 bits += 8;
126 } 126 }
127 this = lcode[hold & lmask]; 127 here = lcode[hold & lmask];
128 dolen: 128 dolen:
129 op = (unsigned)(this.bits); 129 op = (unsigned)(here.bits);
130 hold >>= op; 130 hold >>= op;
131 bits -= op; 131 bits -= op;
132 op = (unsigned)(this.op); 132 op = (unsigned)(here.op);
133 if (op == 0) { /* literal */ 133 if (op == 0) { /* literal */
134 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? 134 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
135 "inflate: literal '%c'\n" : 135 "inflate: literal '%c'\n" :
136 "inflate: literal 0x%02x\n", this.val)); 136 "inflate: literal 0x%02x\n", here.val));
137 PUP(out) = (unsigned char)(this.val); 137 PUP(out) = (unsigned char)(here.val);
138 } 138 }
139 else if (op & 16) { /* length base */ 139 else if (op & 16) { /* length base */
140 len = (unsigned)(this.val); 140 len = (unsigned)(here.val);
141 op &= 15; /* number of extra bits */ 141 op &= 15; /* number of extra bits */
142 if (op) { 142 if (op) {
143 if (bits < op) { 143 if (bits < op) {
@@ -155,14 +155,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
155 hold += (unsigned long)(PUP(in)) << bits; 155 hold += (unsigned long)(PUP(in)) << bits;
156 bits += 8; 156 bits += 8;
157 } 157 }
158 this = dcode[hold & dmask]; 158 here = dcode[hold & dmask];
159 dodist: 159 dodist:
160 op = (unsigned)(this.bits); 160 op = (unsigned)(here.bits);
161 hold >>= op; 161 hold >>= op;
162 bits -= op; 162 bits -= op;
163 op = (unsigned)(this.op); 163 op = (unsigned)(here.op);
164 if (op & 16) { /* distance base */ 164 if (op & 16) { /* distance base */
165 dist = (unsigned)(this.val); 165 dist = (unsigned)(here.val);
166 op &= 15; /* number of extra bits */ 166 op &= 15; /* number of extra bits */
167 if (bits < op) { 167 if (bits < op) {
168 hold += (unsigned long)(PUP(in)) << bits; 168 hold += (unsigned long)(PUP(in)) << bits;
@@ -187,9 +187,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
187 if (dist > op) { /* see if copy from window */ 187 if (dist > op) { /* see if copy from window */
188 op = dist - op; /* distance back in window */ 188 op = dist - op; /* distance back in window */
189 if (op > whave) { 189 if (op > whave) {
190 strm->msg = (char *)"invalid distance too far back"; 190 if (state->sane) {
191 state->mode = BAD; 191 strm->msg = (char *)"invalid distance too far back";
192 break; 192 state->mode = BAD;
193 break;
194 }
195#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
196 if (len <= op - whave) {
197 do {
198 PUP(out) = 0;
199 } while (--len);
200 continue;
201 }
202 len -= op - whave;
203 do {
204 PUP(out) = 0;
205 } while (--op > whave);
206 if (op == 0) {
207 from = out - dist;
208 do {
209 PUP(out) = PUP(from);
210 } while (--len);
211 continue;
212 }
213#endif
193 } 214 }
194 from = window - OFF; 215 from = window - OFF;
195 if (write == 0) { /* very common case */ 216 if (write == 0) { /* very common case */
@@ -259,7 +280,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
259 } 280 }
260 } 281 }
261 else if ((op & 64) == 0) { /* 2nd level distance code */ 282 else if ((op & 64) == 0) { /* 2nd level distance code */
262 this = dcode[this.val + (hold & ((1U << op) - 1))]; 283 here = dcode[here.val + (hold & ((1U << op) - 1))];
263 goto dodist; 284 goto dodist;
264 } 285 }
265 else { 286 else {
@@ -269,7 +290,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
269 } 290 }
270 } 291 }
271 else if ((op & 64) == 0) { /* 2nd level length code */ 292 else if ((op & 64) == 0) { /* 2nd level length code */
272 this = lcode[this.val + (hold & ((1U << op) - 1))]; 293 here = lcode[here.val + (hold & ((1U << op) - 1))];
273 goto dolen; 294 goto dolen;
274 } 295 }
275 else if (op & 32) { /* end-of-block */ 296 else if (op & 32) { /* end-of-block */