diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-08-15 01:07:28 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-08-15 01:07:28 +0200 |
commit | 5af0a7ce737f9f42d5fb153a84aa986850c97d62 (patch) | |
tree | ad9ffb86eb384cad93d827eb61d45d767aeb60fb /sys/src/libflate | |
parent | 75a8003a8afb22e8557da98ad5dae63efa365d5e (diff) |
libflate: add bounds checking on decode array, add sanity checks in hufftab()
Diffstat (limited to 'sys/src/libflate')
-rw-r--r-- | sys/src/libflate/inflate.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/src/libflate/inflate.c b/sys/src/libflate/inflate.c index f979084c2..df6568048 100644 --- a/sys/src/libflate/inflate.c +++ b/sys/src/libflate/inflate.c @@ -48,6 +48,7 @@ struct Huff ulong maxcode[MaxHuffBits]; ulong last[MaxHuffBits]; ulong decode[MaxLeaf]; + int maxleaf; }; /* litlen code words 257-285 extra bits */ @@ -565,14 +566,16 @@ hufftab(Huff *h, char *hb, int maxleaf, int flatbits) maxbits = b; } } - - h->maxbits = maxbits; if(maxbits <= 0){ h->maxbits = 0; h->minbits = 0; h->flatmask = 0; + h->maxleaf = 0; return 1; } + h->maxbits = maxbits; + if(maxbits >= MaxHuffBits || minbits <= 0) + return 0; code = 0; c = 0; for(b = 0; b <= maxbits; b++){ @@ -613,6 +616,7 @@ hufftab(Huff *h, char *hb, int maxleaf, int flatbits) h->flat[revcode(mincode, flatbits)] = (b << 8) | 0xff; } + h->maxleaf = maxleaf; for(i = 0; i < maxleaf; i++){ b = hb[i]; if(b <= 0) @@ -639,7 +643,7 @@ hufftab(Huff *h, char *hb, int maxleaf, int flatbits) static int hdecsym(Input *in, Huff *h, int nb) { - long c; + ulong c; if((nb & 0xff) == 0xff) nb = nb >> 8; @@ -652,9 +656,12 @@ hdecsym(Input *in, Huff *h, int nb) c |= revtab[(in->sreg>>8)&0xff]; c >>= (16-nb); if(c <= h->maxcode[nb]){ + c = h->last[nb] - c; + if(c >= h->maxleaf) + break; in->sreg >>= nb; in->nbits -= nb; - return h->decode[h->last[nb] - c]; + return h->decode[c]; } } in->error = FlateCorrupted; |