X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=lib%2Finflate.c;h=845f91d3ac1226ad6bee1e87e1fc74169ccd36cf;hb=c48cbb405c4f338ce3263c44d621eff41d9a95fc;hp=6db6e98d1637b58764d3356a52ecff7216dfe3ed;hpb=c0d6f9663b30a09ed725229b2d50391268c8538e;p=sfrench%2Fcifs-2.6.git diff --git a/lib/inflate.c b/lib/inflate.c index 6db6e98d1637..845f91d3ac12 100644 --- a/lib/inflate.c +++ b/lib/inflate.c @@ -292,7 +292,6 @@ STATIC int INIT huft_build( oversubscribed set of lengths), and three if not enough memory. */ { unsigned a; /* counter for codes of length k */ - unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ @@ -303,18 +302,33 @@ STATIC int INIT huft_build( register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ - struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ - unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ + struct { + unsigned c[BMAX+1]; /* bit length count table */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + unsigned x[BMAX+1]; /* bit offsets, then code stack */ + } *stk; + unsigned *c, *v, *x; + struct huft **u; + int ret; DEBG("huft1 "); + stk = malloc(sizeof(*stk)); + if (stk == NULL) + return 3; /* out of memory */ + + c = stk->c; + v = stk->v; + x = stk->x; + u = stk->u; + /* Generate counts for each bit length */ - memzero(c, sizeof(c)); + memzero(stk->c, sizeof(stk->c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), @@ -326,7 +340,8 @@ DEBG("huft1 "); { *t = (struct huft *)NULL; *m = 0; - return 2; + ret = 2; + goto out; } DEBG("huft2 "); @@ -351,10 +366,14 @@ DEBG("huft3 "); /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return 2; /* bad input: more codes than bits */ - if ((y -= c[i]) < 0) - return 2; + if ((y -= c[j]) < 0) { + ret = 2; /* bad input: more codes than bits */ + goto out; + } + if ((y -= c[i]) < 0) { + ret = 2; + goto out; + } c[i] += y; DEBG("huft4 "); @@ -428,7 +447,8 @@ DEBG1("3 "); { if (h) huft_free(u[0]); - return 3; /* not enough memory */ + ret = 3; /* not enough memory */ + goto out; } DEBG1("4 "); hufts += z + 1; /* track memory usage */ @@ -492,7 +512,11 @@ DEBG("h6f "); DEBG("huft7 "); /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; + ret = y != 0 && g != 1; + + out: + free(stk); + return ret; } @@ -705,10 +729,14 @@ STATIC int noinline INIT inflate_fixed(void) struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ - unsigned l[288]; /* length list for huft_build */ + unsigned *l; /* length list for huft_build */ DEBG(" 1) { huft_free(tl); + free(l); DEBG(">"); return i; @@ -737,11 +767,13 @@ DEBG(" 286 || nd > 30) #endif - return 1; /* bad lengths */ + { + ret = 1; /* bad lengths */ + goto out; + } DEBG("dyn1 "); @@ -818,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 "); @@ -840,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; } @@ -850,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; @@ -861,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; @@ -891,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; @@ -907,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 "); @@ -924,10 +973,14 @@ DEBG("dyn7 "); huft_free(td); DEBG(">"); - return 0; - - underrun: - return 4; /* Input underrun */ + ret = 0; +out: + free(ll); + return ret; + +underrun: + ret = 4; /* Input underrun */ + goto out; }