| Index: usr.bin/compress/zopen.c |
| =================================================================== |
| --- usr.bin/compress/zopen.c (revision 225020) |
| +++ usr.bin/compress/zopen.c (working copy) |
| @@ -486,7 +486,7 @@ zread(void *cookie, char *rbp, int num) |
| block_compress = maxbits & BLOCK_MASK; |
| maxbits &= BIT_MASK; |
| maxmaxcode = 1L << maxbits; |
| - if (maxbits > BITS) { |
| + if (maxbits > BITS || maxbits < 12) { |
| errno = EFTYPE; |
| return (-1); |
| } |
| @@ -513,17 +513,28 @@ zread(void *cookie, char *rbp, int num) |
| for (code = 255; code >= 0; code--) |
| tab_prefixof(code) = 0; |
| clear_flg = 1; |
| - free_ent = FIRST - 1; |
| - if ((code = getcode(zs)) == -1) /* O, untimely death! */ |
| - break; |
| + free_ent = FIRST; |
| + oldcode = -1; |
| + continue; |
| } |
| incode = code; |
| |
| - /* Special case for KwKwK string. */ |
| + /* Special case for kWkWk string. */ |
| if (code >= free_ent) { |
| + if (code > free_ent || oldcode == -1) { |
| + /* Bad stream. */ |
| + errno = EINVAL; |
| + return (-1); |
| + } |
| *stackp++ = finchar; |
| code = oldcode; |
| } |
| + /* |
| + * The above condition ensures that code < free_ent. |
| + * The construction of tab_prefixof in turn guarantees that |
| + * each iteration decreases code and therefore stack usage is |
| + * bound by 1 << BITS - 256. |
| + */ |
| |
| /* Generate output characters in reverse order. */ |
| while (code >= 256) { |
| @@ -540,7 +551,7 @@ middle: do { |
| } while (stackp > de_stack); |
| |
| /* Generate the new entry. */ |
| - if ((code = free_ent) < maxmaxcode) { |
| + if ((code = free_ent) < maxmaxcode && oldcode != -1) { |
| tab_prefixof(code) = (u_short) oldcode; |
| tab_suffixof(code) = finchar; |
| free_ent = code + 1; |