diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-05-02 19:27:15 +0200 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 19:27:15 +0200 |
commit | 39b7ee06859b07ca5fd4fabb44c4600316532574 (patch) | |
tree | 938d2e25cdf8068e9604dc40775aede665f6e98b /lib | |
parent | 35c7422649ee7a3d0eb4ebd32c997eeb45f81046 (diff) | |
download | lwn-39b7ee06859b07ca5fd4fabb44c4600316532574.tar.gz lwn-39b7ee06859b07ca5fd4fabb44c4600316532574.zip |
[PATCH] x86-64: deflate inflate_dynamic too
inflate_dynamic() has piggy stack usage too, so heap allocate it too.
I'm not sure it actually gets used, but it shows up large in "make
checkstack".
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/inflate.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/lib/inflate.c b/lib/inflate.c index 88a22f4a49df..845f91d3ac12 100644 --- a/lib/inflate.c +++ b/lib/inflate.c @@ -798,16 +798,19 @@ STATIC int noinline INIT inflate_dynamic(void) unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ -#ifdef PKZIP_BUG_WORKAROUND - unsigned ll[288+32]; /* literal/length and distance code lengths */ -#else - unsigned ll[286+30]; /* literal/length and distance code lengths */ -#endif + unsigned *ll; /* literal/length and distance code lengths */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ + int ret; DEBG("<dyn"); +#ifdef PKZIP_BUG_WORKAROUND + ll = malloc(sizeof(*ll) * (288+32)); /* literal/length and distance code lengths */ +#else + ll = malloc(sizeof(*ll) * (286+30)); /* literal/length and distance code lengths */ +#endif + /* make local bit buffer */ b = bb; k = bk; @@ -828,7 +831,10 @@ DEBG("<dyn"); #else if (nl > 286 || nd > 30) #endif - return 1; /* bad lengths */ + { + ret = 1; /* bad lengths */ + goto out; + } DEBG("dyn1 "); @@ -850,7 +856,8 @@ DEBG("dyn2 "); { if (i == 1) huft_free(tl); - return i; /* incomplete code set */ + ret = i; /* incomplete code set */ + goto out; } DEBG("dyn3 "); @@ -872,8 +879,10 @@ DEBG("dyn3 "); NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) - if ((unsigned)i + j > n) - return 1; + if ((unsigned)i + j > n) { + ret = 1; + goto out; + } while (j--) ll[i++] = l; } @@ -882,8 +891,10 @@ DEBG("dyn3 "); NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) - if ((unsigned)i + j > n) - return 1; + if ((unsigned)i + j > n) { + ret = 1; + goto out; + } while (j--) ll[i++] = 0; l = 0; @@ -893,8 +904,10 @@ DEBG("dyn3 "); NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) - if ((unsigned)i + j > n) - return 1; + if ((unsigned)i + j > n) { + ret = 1; + goto out; + } while (j--) ll[i++] = 0; l = 0; @@ -923,7 +936,8 @@ DEBG("dyn5b "); error("incomplete literal tree"); huft_free(tl); } - return i; /* incomplete code set */ + ret = i; /* incomplete code set */ + goto out; } DEBG("dyn5c "); bd = dbits; @@ -939,15 +953,18 @@ DEBG("dyn5d "); huft_free(td); } huft_free(tl); - return i; /* incomplete code set */ + ret = i; /* incomplete code set */ + goto out; #endif } DEBG("dyn6 "); /* decompress until an end-of-block code */ - if (inflate_codes(tl, td, bl, bd)) - return 1; + if (inflate_codes(tl, td, bl, bd)) { + ret = 1; + goto out; + } DEBG("dyn7 "); @@ -956,10 +973,14 @@ DEBG("dyn7 "); huft_free(td); DEBG(">"); - return 0; + ret = 0; +out: + free(ll); + return ret; - underrun: - return 4; /* Input underrun */ +underrun: + ret = 4; /* Input underrun */ + goto out; } |