| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: zopen.c,v 1.14 2011/08/16 03:24:47 christos Exp $ */ | | 1 | /* $NetBSD: zopen.c,v 1.15 2011/08/16 13:55:01 joerg Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1985, 1986, 1992, 1993 | | 4 | * Copyright (c) 1985, 1986, 1992, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Diomidis Spinellis and James A. Woods, derived from original | | 8 | * Diomidis Spinellis and James A. Woods, derived from original |
9 | * work by Spencer Thomas and Joseph Orost. | | 9 | * work by Spencer Thomas and Joseph Orost. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
33 | * SUCH DAMAGE. | | 33 | * SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #if defined(LIBC_SCCS) && !defined(lint) | | 36 | #if defined(LIBC_SCCS) && !defined(lint) |
37 | #if 0 | | 37 | #if 0 |
38 | static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; | | 38 | static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; |
39 | #else | | 39 | #else |
40 | static char rcsid[] = "$NetBSD: zopen.c,v 1.14 2011/08/16 03:24:47 christos Exp $"; | | 40 | static char rcsid[] = "$NetBSD: zopen.c,v 1.15 2011/08/16 13:55:01 joerg Exp $"; |
41 | #endif | | 41 | #endif |
42 | #endif /* LIBC_SCCS and not lint */ | | 42 | #endif /* LIBC_SCCS and not lint */ |
43 | | | 43 | |
44 | /*- | | 44 | /*- |
45 | * fcompress.c - File compression ala IEEE Computer, June 1984. | | 45 | * fcompress.c - File compression ala IEEE Computer, June 1984. |
46 | * | | 46 | * |
47 | * Compress authors: | | 47 | * Compress authors: |
48 | * Spencer W. Thomas (decvax!utah-cs!thomas) | | 48 | * Spencer W. Thomas (decvax!utah-cs!thomas) |
49 | * Jim McKie (decvax!mcvax!jim) | | 49 | * Jim McKie (decvax!mcvax!jim) |
50 | * Steve Davies (decvax!vax135!petsd!peora!srd) | | 50 | * Steve Davies (decvax!vax135!petsd!peora!srd) |
51 | * Ken Turkowski (decvax!decwrl!turtlevax!ken) | | 51 | * Ken Turkowski (decvax!decwrl!turtlevax!ken) |
52 | * James A. Woods (decvax!ihnp4!ames!jaw) | | 52 | * James A. Woods (decvax!ihnp4!ames!jaw) |
53 | * Joe Orost (decvax!vax135!petsd!joe) | | 53 | * Joe Orost (decvax!vax135!petsd!joe) |
| @@ -476,85 +476,85 @@ zread(void *cookie, char *rbp, int num) | | | @@ -476,85 +476,85 @@ zread(void *cookie, char *rbp, int num) |
476 | } | | 476 | } |
477 | | | 477 | |
478 | /* Check the magic number */ | | 478 | /* Check the magic number */ |
479 | if (fread(header, | | 479 | if (fread(header, |
480 | sizeof(char), sizeof(header), fp) != sizeof(header) || | | 480 | sizeof(char), sizeof(header), fp) != sizeof(header) || |
481 | memcmp(header, magic_header, sizeof(magic_header)) != 0) { | | 481 | memcmp(header, magic_header, sizeof(magic_header)) != 0) { |
482 | errno = EFTYPE; | | 482 | errno = EFTYPE; |
483 | return (-1); | | 483 | return (-1); |
484 | } | | 484 | } |
485 | maxbits = header[2]; /* Set -b from file. */ | | 485 | maxbits = header[2]; /* Set -b from file. */ |
486 | block_compress = maxbits & BLOCK_MASK; | | 486 | block_compress = maxbits & BLOCK_MASK; |
487 | maxbits &= BIT_MASK; | | 487 | maxbits &= BIT_MASK; |
488 | maxmaxcode = 1L << maxbits; | | 488 | maxmaxcode = 1L << maxbits; |
489 | if (maxbits > BITS) { | | 489 | if (maxbits > BITS || maxbits < 12) { |
490 | errno = EFTYPE; | | 490 | errno = EFTYPE; |
491 | return (-1); | | 491 | return (-1); |
492 | } | | 492 | } |
493 | /* As above, initialize the first 256 entries in the table. */ | | 493 | /* As above, initialize the first 256 entries in the table. */ |
494 | maxcode = MAXCODE(n_bits = INIT_BITS); | | 494 | maxcode = MAXCODE(n_bits = INIT_BITS); |
495 | for (code = 255; code >= 0; code--) { | | 495 | for (code = 255; code >= 0; code--) { |
496 | tab_prefixof(code) = 0; | | 496 | tab_prefixof(code) = 0; |
497 | tab_suffixof(code) = (char_type) code; | | 497 | tab_suffixof(code) = (char_type) code; |
498 | } | | 498 | } |
499 | free_ent = block_compress ? FIRST : 256; | | 499 | free_ent = block_compress ? FIRST : 256; |
500 | | | 500 | oldcode = -1; |
501 | finchar = oldcode = getcode(zs); | | | |
502 | if (oldcode == -1) /* EOF already? */ | | | |
503 | return (0); /* Get out of here */ | | | |
504 | | | | |
505 | /* First code must be 8 bits = char. */ | | | |
506 | *bp++ = (u_char)finchar; | | | |
507 | count--; | | | |
508 | stackp = de_stack; | | 501 | stackp = de_stack; |
509 | | | 502 | |
510 | while ((code = getcode(zs)) > -1) { | | 503 | while ((code = getcode(zs)) > -1) { |
511 | | | 504 | |
512 | if ((code == CLEAR) && block_compress) { | | 505 | if ((code == CLEAR) && block_compress) { |
513 | for (code = 255; code >= 0; code--) | | 506 | for (code = 255; code >= 0; code--) |
514 | tab_prefixof(code) = 0; | | 507 | tab_prefixof(code) = 0; |
515 | clear_flg = 1; | | 508 | clear_flg = 1; |
516 | free_ent = FIRST - 1; | | 509 | free_ent = FIRST; |
517 | if ((code = getcode(zs)) == -1) /* O, untimely death! */ | | 510 | oldcode = -1; |
518 | break; | | 511 | continue; |
519 | } | | 512 | } |
520 | incode = code; | | 513 | incode = code; |
521 | | | 514 | |
522 | /* Special case FOR kWkWk string. */ | | 515 | /* Special case for kWkWk string. */ |
523 | if (code >= free_ent) { | | 516 | if (code >= free_ent) { |
| | | 517 | if (code > free_ent || oldcode == -1) { |
| | | 518 | /* Bad stream. */ |
| | | 519 | errno = EINVAL; |
| | | 520 | return (-1); |
| | | 521 | } |
524 | *stackp++ = finchar; | | 522 | *stackp++ = finchar; |
525 | code = oldcode; | | 523 | code = oldcode; |
526 | } | | 524 | } |
| | | 525 | /* |
| | | 526 | * The above condition ensures that code < free_ent. |
| | | 527 | * The construction of tab_prefixof in turn guarantees that |
| | | 528 | * each iteration decreases code and therefore stack usage is |
| | | 529 | * bound by 1 << BITS - 256. |
| | | 530 | */ |
527 | | | 531 | |
528 | /* Generate output characters in reverse order. */ | | 532 | /* Generate output characters in reverse order. */ |
529 | while (code >= 256) { | | 533 | while (code >= 256) { |
530 | if (stackp - de_stack >= HSIZE - 1) { | | | |
531 | errno = EOVERFLOW; | | | |
532 | return -1; | | | |
533 | } | | | |
534 | *stackp++ = tab_suffixof(code); | | 534 | *stackp++ = tab_suffixof(code); |
535 | code = tab_prefixof(code); | | 535 | code = tab_prefixof(code); |
536 | } | | 536 | } |
537 | *stackp++ = finchar = tab_suffixof(code); | | 537 | *stackp++ = finchar = tab_suffixof(code); |
538 | | | 538 | |
539 | /* And put them out in forward order. */ | | 539 | /* And put them out in forward order. */ |
540 | middle: do { | | 540 | middle: do { |
541 | if (count-- == 0) | | 541 | if (count-- == 0) |
542 | return (num); | | 542 | return (num); |
543 | *bp++ = *--stackp; | | 543 | *bp++ = *--stackp; |
544 | } while (stackp > de_stack); | | 544 | } while (stackp > de_stack); |
545 | | | 545 | |
546 | /* Generate the new entry. */ | | 546 | /* Generate the new entry. */ |
547 | if ((code = free_ent) < maxmaxcode) { | | 547 | if ((code = free_ent) < maxmaxcode && oldcode != -1) { |
548 | tab_prefixof(code) = (u_short) oldcode; | | 548 | tab_prefixof(code) = (u_short) oldcode; |
549 | tab_suffixof(code) = finchar; | | 549 | tab_suffixof(code) = finchar; |
550 | free_ent = code + 1; | | 550 | free_ent = code + 1; |
551 | } | | 551 | } |
552 | | | 552 | |
553 | /* Remember previous code. */ | | 553 | /* Remember previous code. */ |
554 | oldcode = incode; | | 554 | oldcode = incode; |
555 | } | | 555 | } |
556 | state = S_EOF; | | 556 | state = S_EOF; |
557 | eof: return (num - count); | | 557 | eof: return (num - count); |
558 | } | | 558 | } |
559 | | | 559 | |
560 | /*- | | 560 | /*- |