Index: third_party/zlib/inffast.c |
=================================================================== |
--- third_party/zlib/inffast.c (revision 113739) |
+++ third_party/zlib/inffast.c (working copy) |
@@ -1,5 +1,5 @@ |
/* inffast.c -- fast decoding |
- * Copyright (C) 1995-2004 Mark Adler |
+ * Copyright (C) 1995-2008, 2010 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
@@ -64,7 +64,7 @@ |
requires strm->avail_out >= 258 for each loop to avoid checking for |
output space. |
*/ |
-void inflate_fast(strm, start) |
+void ZLIB_INTERNAL inflate_fast(strm, start) |
z_streamp strm; |
unsigned start; /* inflate()'s starting value for strm->avail_out */ |
{ |
@@ -79,7 +79,7 @@ |
#endif |
unsigned wsize; /* window size or zero if not using window */ |
unsigned whave; /* valid bytes in the window */ |
- unsigned write; /* window write index */ |
+ unsigned wnext; /* window write index */ |
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ |
unsigned long hold; /* local strm->hold */ |
unsigned bits; /* local strm->bits */ |
@@ -87,7 +87,7 @@ |
code const FAR *dcode; /* local strm->distcode */ |
unsigned lmask; /* mask for first level of length codes */ |
unsigned dmask; /* mask for first level of distance codes */ |
- code this; /* retrieved table entry */ |
+ code here; /* retrieved table entry */ |
unsigned op; /* code bits, operation, extra bits, or */ |
/* window position, window bytes to copy */ |
unsigned len; /* match length, unused bytes */ |
@@ -106,7 +106,7 @@ |
#endif |
wsize = state->wsize; |
whave = state->whave; |
- write = state->write; |
+ wnext = state->wnext; |
window = state->window; |
hold = state->hold; |
bits = state->bits; |
@@ -124,20 +124,20 @@ |
hold += (unsigned long)(PUP(in)) << bits; |
bits += 8; |
} |
- this = lcode[hold & lmask]; |
+ here = lcode[hold & lmask]; |
dolen: |
- op = (unsigned)(this.bits); |
+ op = (unsigned)(here.bits); |
hold >>= op; |
bits -= op; |
- op = (unsigned)(this.op); |
+ op = (unsigned)(here.op); |
if (op == 0) { /* literal */ |
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? |
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
"inflate: literal '%c'\n" : |
- "inflate: literal 0x%02x\n", this.val)); |
- PUP(out) = (unsigned char)(this.val); |
+ "inflate: literal 0x%02x\n", here.val)); |
+ PUP(out) = (unsigned char)(here.val); |
} |
else if (op & 16) { /* length base */ |
- len = (unsigned)(this.val); |
+ len = (unsigned)(here.val); |
op &= 15; /* number of extra bits */ |
if (op) { |
if (bits < op) { |
@@ -155,14 +155,14 @@ |
hold += (unsigned long)(PUP(in)) << bits; |
bits += 8; |
} |
- this = dcode[hold & dmask]; |
+ here = dcode[hold & dmask]; |
dodist: |
- op = (unsigned)(this.bits); |
+ op = (unsigned)(here.bits); |
hold >>= op; |
bits -= op; |
- op = (unsigned)(this.op); |
+ op = (unsigned)(here.op); |
if (op & 16) { /* distance base */ |
- dist = (unsigned)(this.val); |
+ dist = (unsigned)(here.val); |
op &= 15; /* number of extra bits */ |
if (bits < op) { |
hold += (unsigned long)(PUP(in)) << bits; |
@@ -187,12 +187,34 @@ |
if (dist > op) { /* see if copy from window */ |
op = dist - op; /* distance back in window */ |
if (op > whave) { |
- strm->msg = (char *)"invalid distance too far back"; |
- state->mode = BAD; |
- break; |
+ if (state->sane) { |
+ strm->msg = |
+ (char *)"invalid distance too far back"; |
+ state->mode = BAD; |
+ break; |
+ } |
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR |
+ if (len <= op - whave) { |
+ do { |
+ PUP(out) = 0; |
+ } while (--len); |
+ continue; |
+ } |
+ len -= op - whave; |
+ do { |
+ PUP(out) = 0; |
+ } while (--op > whave); |
+ if (op == 0) { |
+ from = out - dist; |
+ do { |
+ PUP(out) = PUP(from); |
+ } while (--len); |
+ continue; |
+ } |
+#endif |
} |
from = window - OFF; |
- if (write == 0) { /* very common case */ |
+ if (wnext == 0) { /* very common case */ |
from += wsize - op; |
if (op < len) { /* some from window */ |
len -= op; |
@@ -202,17 +224,17 @@ |
from = out - dist; /* rest from output */ |
} |
} |
- else if (write < op) { /* wrap around window */ |
- from += wsize + write - op; |
- op -= write; |
+ else if (wnext < op) { /* wrap around window */ |
+ from += wsize + wnext - op; |
+ op -= wnext; |
if (op < len) { /* some from end of window */ |
len -= op; |
do { |
PUP(out) = PUP(from); |
} while (--op); |
from = window - OFF; |
- if (write < len) { /* some from start of window */ |
- op = write; |
+ if (wnext < len) { /* some from start of window */ |
+ op = wnext; |
len -= op; |
do { |
PUP(out) = PUP(from); |
@@ -222,7 +244,7 @@ |
} |
} |
else { /* contiguous in window */ |
- from += write - op; |
+ from += wnext - op; |
if (op < len) { /* some from window */ |
len -= op; |
do { |
@@ -259,7 +281,7 @@ |
} |
} |
else if ((op & 64) == 0) { /* 2nd level distance code */ |
- this = dcode[this.val + (hold & ((1U << op) - 1))]; |
+ here = dcode[here.val + (hold & ((1U << op) - 1))]; |
goto dodist; |
} |
else { |
@@ -269,7 +291,7 @@ |
} |
} |
else if ((op & 64) == 0) { /* 2nd level length code */ |
- this = lcode[this.val + (hold & ((1U << op) - 1))]; |
+ here = lcode[here.val + (hold & ((1U << op) - 1))]; |
goto dolen; |
} |
else if (op & 32) { /* end-of-block */ |
@@ -305,7 +327,7 @@ |
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): |
- Using bit fields for code structure |
- Different op definition to avoid & for extra bits (do & for table bits) |
- - Three separate decoding do-loops for direct, window, and write == 0 |
+ - Three separate decoding do-loops for direct, window, and wnext == 0 |
- Special case for distance > 1 copies to do overlapped load and store copy |
- Explicit branch predictions (based on measured branch probabilities) |
- Deferring match copy and interspersed it with decoding subsequent codes |