diff options
| author | Mark Adler <madler@alumni.caltech.edu> | 2016-11-05 22:55:34 -0700 |
|---|---|---|
| committer | Mark Adler <madler@alumni.caltech.edu> | 2016-12-04 07:39:37 -0800 |
| commit | 9674807c82ae06716a678d7374362acdb6f041b5 (patch) | |
| tree | d2d36ae6ece89435bfdf7b21b766866a4bbf32b4 | |
| parent | fc130cdd9fcb0ea4decaf003be6ddf4c5dfd5760 (diff) | |
| download | zlib-9674807c82ae06716a678d7374362acdb6f041b5.tar.gz zlib-9674807c82ae06716a678d7374362acdb6f041b5.tar.bz2 zlib-9674807c82ae06716a678d7374362acdb6f041b5.zip | |
Fix bugs in creating a very large gzip header.
| -rw-r--r-- | deflate.c | 339 | ||||
| -rw-r--r-- | deflate.h | 21 |
2 files changed, 191 insertions, 169 deletions
| @@ -326,6 +326,9 @@ local int deflateStateCheck (strm) | |||
| 326 | return 1; | 326 | return 1; |
| 327 | s = strm->state; | 327 | s = strm->state; |
| 328 | if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && | 328 | if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && |
| 329 | #ifdef GZIP | ||
| 330 | s->status != GZIP_STATE && | ||
| 331 | #endif | ||
| 329 | s->status != EXTRA_STATE && | 332 | s->status != EXTRA_STATE && |
| 330 | s->status != NAME_STATE && | 333 | s->status != NAME_STATE && |
| 331 | s->status != COMMENT_STATE && | 334 | s->status != COMMENT_STATE && |
| @@ -426,7 +429,11 @@ int ZEXPORT deflateResetKeep (strm) | |||
| 426 | if (s->wrap < 0) { | 429 | if (s->wrap < 0) { |
| 427 | s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ | 430 | s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ |
| 428 | } | 431 | } |
| 429 | s->status = s->wrap ? INIT_STATE : BUSY_STATE; | 432 | s->status = |
| 433 | #ifdef GZIP | ||
| 434 | s->wrap == 2 ? GZIP_STATE : | ||
| 435 | #endif | ||
| 436 | s->wrap ? INIT_STATE : BUSY_STATE; | ||
| 430 | strm->adler = | 437 | strm->adler = |
| 431 | #ifdef GZIP | 438 | #ifdef GZIP |
| 432 | s->wrap == 2 ? crc32(0L, Z_NULL, 0) : | 439 | s->wrap == 2 ? crc32(0L, Z_NULL, 0) : |
| @@ -584,7 +591,6 @@ uLong ZEXPORT deflateBound(strm, sourceLen) | |||
| 584 | { | 591 | { |
| 585 | deflate_state *s; | 592 | deflate_state *s; |
| 586 | uLong complen, wraplen; | 593 | uLong complen, wraplen; |
| 587 | Bytef *str; | ||
| 588 | 594 | ||
| 589 | /* conservative upper bound for compressed data */ | 595 | /* conservative upper bound for compressed data */ |
| 590 | complen = sourceLen + | 596 | complen = sourceLen + |
| @@ -603,9 +609,11 @@ uLong ZEXPORT deflateBound(strm, sourceLen) | |||
| 603 | case 1: /* zlib wrapper */ | 609 | case 1: /* zlib wrapper */ |
| 604 | wraplen = 6 + (s->strstart ? 4 : 0); | 610 | wraplen = 6 + (s->strstart ? 4 : 0); |
| 605 | break; | 611 | break; |
| 612 | #ifdef GZIP | ||
| 606 | case 2: /* gzip wrapper */ | 613 | case 2: /* gzip wrapper */ |
| 607 | wraplen = 18; | 614 | wraplen = 18; |
| 608 | if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ | 615 | if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ |
| 616 | Bytef *str; | ||
| 609 | if (s->gzhead->extra != Z_NULL) | 617 | if (s->gzhead->extra != Z_NULL) |
| 610 | wraplen += 2 + s->gzhead->extra_len; | 618 | wraplen += 2 + s->gzhead->extra_len; |
| 611 | str = s->gzhead->name; | 619 | str = s->gzhead->name; |
| @@ -622,6 +630,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) | |||
| 622 | wraplen += 2; | 630 | wraplen += 2; |
| 623 | } | 631 | } |
| 624 | break; | 632 | break; |
| 633 | #endif | ||
| 625 | default: /* for compiler happiness */ | 634 | default: /* for compiler happiness */ |
| 626 | wraplen = 6; | 635 | wraplen = 6; |
| 627 | } | 636 | } |
| @@ -669,13 +678,23 @@ local void flush_pending(strm) | |||
| 669 | strm->next_out += len; | 678 | strm->next_out += len; |
| 670 | s->pending_out += len; | 679 | s->pending_out += len; |
| 671 | strm->total_out += len; | 680 | strm->total_out += len; |
| 672 | strm->avail_out -= len; | 681 | strm->avail_out -= len; |
| 673 | s->pending -= len; | 682 | s->pending -= len; |
| 674 | if (s->pending == 0) { | 683 | if (s->pending == 0) { |
| 675 | s->pending_out = s->pending_buf; | 684 | s->pending_out = s->pending_buf; |
| 676 | } | 685 | } |
| 677 | } | 686 | } |
| 678 | 687 | ||
| 688 | /* =========================================================================== | ||
| 689 | * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. | ||
| 690 | */ | ||
| 691 | #define HCRC_UPDATE(beg) \ | ||
| 692 | do { \ | ||
| 693 | if (s->gzhead->hcrc && s->pending > (beg)) \ | ||
| 694 | strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ | ||
| 695 | s->pending - (beg)); \ | ||
| 696 | } while (0) | ||
| 697 | |||
| 679 | /* ========================================================================= */ | 698 | /* ========================================================================= */ |
| 680 | int ZEXPORT deflate (strm, flush) | 699 | int ZEXPORT deflate (strm, flush) |
| 681 | z_streamp strm; | 700 | z_streamp strm; |
| @@ -696,217 +715,217 @@ int ZEXPORT deflate (strm, flush) | |||
| 696 | } | 715 | } |
| 697 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); | 716 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); |
| 698 | 717 | ||
| 699 | s->strm = strm; /* just in case */ | ||
| 700 | old_flush = s->last_flush; | 718 | old_flush = s->last_flush; |
| 701 | s->last_flush = flush; | 719 | s->last_flush = flush; |
| 702 | 720 | ||
| 721 | /* Flush as much pending output as possible */ | ||
| 722 | if (s->pending != 0) { | ||
| 723 | flush_pending(strm); | ||
| 724 | if (strm->avail_out == 0) { | ||
| 725 | /* Since avail_out is 0, deflate will be called again with | ||
| 726 | * more output space, but possibly with both pending and | ||
| 727 | * avail_in equal to zero. There won't be anything to do, | ||
| 728 | * but this is not an error situation so make sure we | ||
| 729 | * return OK instead of BUF_ERROR at next call of deflate: | ||
| 730 | */ | ||
| 731 | s->last_flush = -1; | ||
| 732 | return Z_OK; | ||
| 733 | } | ||
| 734 | |||
| 735 | /* Make sure there is something to do and avoid duplicate consecutive | ||
| 736 | * flushes. For repeated and useless calls with Z_FINISH, we keep | ||
| 737 | * returning Z_STREAM_END instead of Z_BUF_ERROR. | ||
| 738 | */ | ||
| 739 | } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && | ||
| 740 | flush != Z_FINISH) { | ||
| 741 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 742 | } | ||
| 743 | |||
| 744 | /* User must not provide more input after the first FINISH: */ | ||
| 745 | if (s->status == FINISH_STATE && strm->avail_in != 0) { | ||
| 746 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 747 | } | ||
| 748 | |||
| 703 | /* Write the header */ | 749 | /* Write the header */ |
| 704 | if (s->status == INIT_STATE) { | 750 | if (s->status == INIT_STATE) { |
| 705 | #ifdef GZIP | 751 | /* zlib header */ |
| 706 | if (s->wrap == 2) { | 752 | uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; |
| 707 | strm->adler = crc32(0L, Z_NULL, 0); | 753 | uInt level_flags; |
| 708 | put_byte(s, 31); | 754 | |
| 709 | put_byte(s, 139); | 755 | if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) |
| 710 | put_byte(s, 8); | 756 | level_flags = 0; |
| 711 | if (s->gzhead == Z_NULL) { | 757 | else if (s->level < 6) |
| 712 | put_byte(s, 0); | 758 | level_flags = 1; |
| 713 | put_byte(s, 0); | 759 | else if (s->level == 6) |
| 714 | put_byte(s, 0); | 760 | level_flags = 2; |
| 715 | put_byte(s, 0); | ||
| 716 | put_byte(s, 0); | ||
| 717 | put_byte(s, s->level == 9 ? 2 : | ||
| 718 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 719 | 4 : 0)); | ||
| 720 | put_byte(s, OS_CODE); | ||
| 721 | s->status = BUSY_STATE; | ||
| 722 | } | ||
| 723 | else { | ||
| 724 | put_byte(s, (s->gzhead->text ? 1 : 0) + | ||
| 725 | (s->gzhead->hcrc ? 2 : 0) + | ||
| 726 | (s->gzhead->extra == Z_NULL ? 0 : 4) + | ||
| 727 | (s->gzhead->name == Z_NULL ? 0 : 8) + | ||
| 728 | (s->gzhead->comment == Z_NULL ? 0 : 16) | ||
| 729 | ); | ||
| 730 | put_byte(s, (Byte)(s->gzhead->time & 0xff)); | ||
| 731 | put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); | ||
| 732 | put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); | ||
| 733 | put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); | ||
| 734 | put_byte(s, s->level == 9 ? 2 : | ||
| 735 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 736 | 4 : 0)); | ||
| 737 | put_byte(s, s->gzhead->os & 0xff); | ||
| 738 | if (s->gzhead->extra != Z_NULL) { | ||
| 739 | put_byte(s, s->gzhead->extra_len & 0xff); | ||
| 740 | put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); | ||
| 741 | } | ||
| 742 | if (s->gzhead->hcrc) | ||
| 743 | strm->adler = crc32(strm->adler, s->pending_buf, | ||
| 744 | s->pending); | ||
| 745 | s->gzindex = 0; | ||
| 746 | s->status = EXTRA_STATE; | ||
| 747 | } | ||
| 748 | } | ||
| 749 | else | 761 | else |
| 750 | #endif | 762 | level_flags = 3; |
| 751 | { | 763 | header |= (level_flags << 6); |
| 752 | uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; | 764 | if (s->strstart != 0) header |= PRESET_DICT; |
| 753 | uInt level_flags; | 765 | header += 31 - (header % 31); |
| 754 | 766 | ||
| 755 | if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) | 767 | putShortMSB(s, header); |
| 756 | level_flags = 0; | 768 | |
| 757 | else if (s->level < 6) | 769 | /* Save the adler32 of the preset dictionary: */ |
| 758 | level_flags = 1; | 770 | if (s->strstart != 0) { |
| 759 | else if (s->level == 6) | 771 | putShortMSB(s, (uInt)(strm->adler >> 16)); |
| 760 | level_flags = 2; | 772 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); |
| 761 | else | 773 | } |
| 762 | level_flags = 3; | 774 | strm->adler = adler32(0L, Z_NULL, 0); |
| 763 | header |= (level_flags << 6); | 775 | s->status = BUSY_STATE; |
| 764 | if (s->strstart != 0) header |= PRESET_DICT; | ||
| 765 | header += 31 - (header % 31); | ||
| 766 | 776 | ||
| 777 | /* Compression must start with an empty pending buffer */ | ||
| 778 | flush_pending(strm); | ||
| 779 | if (s->pending != 0) { | ||
| 780 | s->last_flush = -1; | ||
| 781 | return Z_OK; | ||
| 782 | } | ||
| 783 | } | ||
| 784 | #ifdef GZIP | ||
| 785 | if (s->status == GZIP_STATE) { | ||
| 786 | /* gzip header */ | ||
| 787 | strm->adler = crc32(0L, Z_NULL, 0); | ||
| 788 | put_byte(s, 31); | ||
| 789 | put_byte(s, 139); | ||
| 790 | put_byte(s, 8); | ||
| 791 | if (s->gzhead == Z_NULL) { | ||
| 792 | put_byte(s, 0); | ||
| 793 | put_byte(s, 0); | ||
| 794 | put_byte(s, 0); | ||
| 795 | put_byte(s, 0); | ||
| 796 | put_byte(s, 0); | ||
| 797 | put_byte(s, s->level == 9 ? 2 : | ||
| 798 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 799 | 4 : 0)); | ||
| 800 | put_byte(s, OS_CODE); | ||
| 767 | s->status = BUSY_STATE; | 801 | s->status = BUSY_STATE; |
| 768 | putShortMSB(s, header); | ||
| 769 | 802 | ||
| 770 | /* Save the adler32 of the preset dictionary: */ | 803 | /* Compression must start with an empty pending buffer */ |
| 771 | if (s->strstart != 0) { | 804 | flush_pending(strm); |
| 772 | putShortMSB(s, (uInt)(strm->adler >> 16)); | 805 | if (s->pending != 0) { |
| 773 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); | 806 | s->last_flush = -1; |
| 807 | return Z_OK; | ||
| 774 | } | 808 | } |
| 775 | strm->adler = adler32(0L, Z_NULL, 0); | 809 | } |
| 810 | else { | ||
| 811 | put_byte(s, (s->gzhead->text ? 1 : 0) + | ||
| 812 | (s->gzhead->hcrc ? 2 : 0) + | ||
| 813 | (s->gzhead->extra == Z_NULL ? 0 : 4) + | ||
| 814 | (s->gzhead->name == Z_NULL ? 0 : 8) + | ||
| 815 | (s->gzhead->comment == Z_NULL ? 0 : 16) | ||
| 816 | ); | ||
| 817 | put_byte(s, (Byte)(s->gzhead->time & 0xff)); | ||
| 818 | put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); | ||
| 819 | put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); | ||
| 820 | put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); | ||
| 821 | put_byte(s, s->level == 9 ? 2 : | ||
| 822 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 823 | 4 : 0)); | ||
| 824 | put_byte(s, s->gzhead->os & 0xff); | ||
| 825 | if (s->gzhead->extra != Z_NULL) { | ||
| 826 | put_byte(s, s->gzhead->extra_len & 0xff); | ||
| 827 | put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); | ||
| 828 | } | ||
| 829 | if (s->gzhead->hcrc) | ||
| 830 | strm->adler = crc32(strm->adler, s->pending_buf, | ||
| 831 | s->pending); | ||
| 832 | s->gzindex = 0; | ||
| 833 | s->status = EXTRA_STATE; | ||
| 776 | } | 834 | } |
| 777 | } | 835 | } |
| 778 | #ifdef GZIP | ||
| 779 | if (s->status == EXTRA_STATE) { | 836 | if (s->status == EXTRA_STATE) { |
| 780 | if (s->gzhead->extra != Z_NULL) { | 837 | if (s->gzhead->extra != Z_NULL) { |
| 781 | uInt beg = s->pending; /* start of bytes to update crc */ | 838 | ulg beg = s->pending; /* start of bytes to update crc */ |
| 782 | 839 | uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; | |
| 783 | while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { | 840 | while (s->pending + left > s->pending_buf_size) { |
| 784 | if (s->pending == s->pending_buf_size) { | 841 | uInt copy = s->pending_buf_size - s->pending; |
| 785 | if (s->gzhead->hcrc && s->pending > beg) | 842 | zmemcpy(s->pending_buf + s->pending, |
| 786 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | 843 | s->gzhead->extra + s->gzindex, copy); |
| 787 | s->pending - beg); | 844 | s->pending = s->pending_buf_size; |
| 788 | flush_pending(strm); | 845 | HCRC_UPDATE(beg); |
| 789 | beg = s->pending; | 846 | s->gzindex += copy; |
| 790 | if (s->pending == s->pending_buf_size) | 847 | flush_pending(strm); |
| 791 | break; | 848 | if (s->pending != 0) { |
| 849 | s->last_flush = -1; | ||
| 850 | return Z_OK; | ||
| 792 | } | 851 | } |
| 793 | put_byte(s, s->gzhead->extra[s->gzindex]); | 852 | beg = 0; |
| 794 | s->gzindex++; | 853 | left -= copy; |
| 795 | } | ||
| 796 | if (s->gzhead->hcrc && s->pending > beg) | ||
| 797 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
| 798 | s->pending - beg); | ||
| 799 | if (s->gzindex == s->gzhead->extra_len) { | ||
| 800 | s->gzindex = 0; | ||
| 801 | s->status = NAME_STATE; | ||
| 802 | } | 854 | } |
| 855 | zmemcpy(s->pending_buf + s->pending, | ||
| 856 | s->gzhead->extra + s->gzindex, left); | ||
| 857 | s->pending += left; | ||
| 858 | HCRC_UPDATE(beg); | ||
| 859 | s->gzindex = 0; | ||
| 803 | } | 860 | } |
| 804 | else | 861 | s->status = NAME_STATE; |
| 805 | s->status = NAME_STATE; | ||
| 806 | } | 862 | } |
| 807 | if (s->status == NAME_STATE) { | 863 | if (s->status == NAME_STATE) { |
| 808 | if (s->gzhead->name != Z_NULL) { | 864 | if (s->gzhead->name != Z_NULL) { |
| 809 | uInt beg = s->pending; /* start of bytes to update crc */ | 865 | ulg beg = s->pending; /* start of bytes to update crc */ |
| 810 | int val; | 866 | int val; |
| 811 | |||
| 812 | do { | 867 | do { |
| 813 | if (s->pending == s->pending_buf_size) { | 868 | if (s->pending == s->pending_buf_size) { |
| 814 | if (s->gzhead->hcrc && s->pending > beg) | 869 | HCRC_UPDATE(beg); |
| 815 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
| 816 | s->pending - beg); | ||
| 817 | flush_pending(strm); | 870 | flush_pending(strm); |
| 818 | beg = s->pending; | 871 | if (s->pending != 0) { |
| 819 | if (s->pending == s->pending_buf_size) { | 872 | s->last_flush = -1; |
| 820 | val = 1; | 873 | return Z_OK; |
| 821 | break; | ||
| 822 | } | 874 | } |
| 875 | beg = 0; | ||
| 823 | } | 876 | } |
| 824 | val = s->gzhead->name[s->gzindex++]; | 877 | val = s->gzhead->name[s->gzindex++]; |
| 825 | put_byte(s, val); | 878 | put_byte(s, val); |
| 826 | } while (val != 0); | 879 | } while (val != 0); |
| 827 | if (s->gzhead->hcrc && s->pending > beg) | 880 | HCRC_UPDATE(beg); |
| 828 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | 881 | s->gzindex = 0; |
| 829 | s->pending - beg); | ||
| 830 | if (val == 0) { | ||
| 831 | s->gzindex = 0; | ||
| 832 | s->status = COMMENT_STATE; | ||
| 833 | } | ||
| 834 | } | 882 | } |
| 835 | else | 883 | s->status = COMMENT_STATE; |
| 836 | s->status = COMMENT_STATE; | ||
| 837 | } | 884 | } |
| 838 | if (s->status == COMMENT_STATE) { | 885 | if (s->status == COMMENT_STATE) { |
| 839 | if (s->gzhead->comment != Z_NULL) { | 886 | if (s->gzhead->comment != Z_NULL) { |
| 840 | uInt beg = s->pending; /* start of bytes to update crc */ | 887 | ulg beg = s->pending; /* start of bytes to update crc */ |
| 841 | int val; | 888 | int val; |
| 842 | |||
| 843 | do { | 889 | do { |
| 844 | if (s->pending == s->pending_buf_size) { | 890 | if (s->pending == s->pending_buf_size) { |
| 845 | if (s->gzhead->hcrc && s->pending > beg) | 891 | HCRC_UPDATE(beg); |
| 846 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
| 847 | s->pending - beg); | ||
| 848 | flush_pending(strm); | 892 | flush_pending(strm); |
| 849 | beg = s->pending; | 893 | if (s->pending != 0) { |
| 850 | if (s->pending == s->pending_buf_size) { | 894 | s->last_flush = -1; |
| 851 | val = 1; | 895 | return Z_OK; |
| 852 | break; | ||
| 853 | } | 896 | } |
| 897 | beg = 0; | ||
| 854 | } | 898 | } |
| 855 | val = s->gzhead->comment[s->gzindex++]; | 899 | val = s->gzhead->comment[s->gzindex++]; |
| 856 | put_byte(s, val); | 900 | put_byte(s, val); |
| 857 | } while (val != 0); | 901 | } while (val != 0); |
| 858 | if (s->gzhead->hcrc && s->pending > beg) | 902 | HCRC_UPDATE(beg); |
| 859 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
| 860 | s->pending - beg); | ||
| 861 | if (val == 0) | ||
| 862 | s->status = HCRC_STATE; | ||
| 863 | } | 903 | } |
| 864 | else | 904 | s->status = HCRC_STATE; |
| 865 | s->status = HCRC_STATE; | ||
| 866 | } | 905 | } |
| 867 | if (s->status == HCRC_STATE) { | 906 | if (s->status == HCRC_STATE) { |
| 868 | if (s->gzhead->hcrc) { | 907 | if (s->gzhead->hcrc) { |
| 869 | if (s->pending + 2 > s->pending_buf_size) | 908 | if (s->pending + 2 > s->pending_buf_size) { |
| 870 | flush_pending(strm); | 909 | flush_pending(strm); |
| 871 | if (s->pending + 2 <= s->pending_buf_size) { | 910 | if (s->pending != 0) { |
| 872 | put_byte(s, (Byte)(strm->adler & 0xff)); | 911 | s->last_flush = -1; |
| 873 | put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); | 912 | return Z_OK; |
| 874 | strm->adler = crc32(0L, Z_NULL, 0); | 913 | } |
| 875 | s->status = BUSY_STATE; | ||
| 876 | } | 914 | } |
| 915 | put_byte(s, (Byte)(strm->adler & 0xff)); | ||
| 916 | put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); | ||
| 917 | strm->adler = crc32(0L, Z_NULL, 0); | ||
| 877 | } | 918 | } |
| 878 | else | 919 | s->status = BUSY_STATE; |
| 879 | s->status = BUSY_STATE; | ||
| 880 | } | ||
| 881 | #endif | ||
| 882 | 920 | ||
| 883 | /* Flush as much pending output as possible */ | 921 | /* Compression must start with an empty pending buffer */ |
| 884 | if (s->pending != 0) { | ||
| 885 | flush_pending(strm); | 922 | flush_pending(strm); |
| 886 | if (strm->avail_out == 0) { | 923 | if (s->pending != 0) { |
| 887 | /* Since avail_out is 0, deflate will be called again with | ||
| 888 | * more output space, but possibly with both pending and | ||
| 889 | * avail_in equal to zero. There won't be anything to do, | ||
| 890 | * but this is not an error situation so make sure we | ||
| 891 | * return OK instead of BUF_ERROR at next call of deflate: | ||
| 892 | */ | ||
| 893 | s->last_flush = -1; | 924 | s->last_flush = -1; |
| 894 | return Z_OK; | 925 | return Z_OK; |
| 895 | } | 926 | } |
| 896 | |||
| 897 | /* Make sure there is something to do and avoid duplicate consecutive | ||
| 898 | * flushes. For repeated and useless calls with Z_FINISH, we keep | ||
| 899 | * returning Z_STREAM_END instead of Z_BUF_ERROR. | ||
| 900 | */ | ||
| 901 | } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && | ||
| 902 | flush != Z_FINISH) { | ||
| 903 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 904 | } | ||
| 905 | |||
| 906 | /* User must not provide more input after the first FINISH: */ | ||
| 907 | if (s->status == FINISH_STATE && strm->avail_in != 0) { | ||
| 908 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 909 | } | 927 | } |
| 928 | #endif | ||
| 910 | 929 | ||
| 911 | /* Start a new block or continue the current one. | 930 | /* Start a new block or continue the current one. |
| 912 | */ | 931 | */ |
| @@ -51,13 +51,16 @@ | |||
| 51 | #define Buf_size 16 | 51 | #define Buf_size 16 |
| 52 | /* size of bit buffer in bi_buf */ | 52 | /* size of bit buffer in bi_buf */ |
| 53 | 53 | ||
| 54 | #define INIT_STATE 42 | 54 | #define INIT_STATE 42 /* zlib header -> BUSY_STATE */ |
| 55 | #define EXTRA_STATE 69 | 55 | #ifdef GZIP |
| 56 | #define NAME_STATE 73 | 56 | # define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ |
| 57 | #define COMMENT_STATE 91 | 57 | #endif |
| 58 | #define HCRC_STATE 103 | 58 | #define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ |
| 59 | #define BUSY_STATE 113 | 59 | #define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ |
| 60 | #define FINISH_STATE 666 | 60 | #define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ |
| 61 | #define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ | ||
| 62 | #define BUSY_STATE 113 /* deflate -> FINISH_STATE */ | ||
| 63 | #define FINISH_STATE 666 /* stream complete */ | ||
| 61 | /* Stream status */ | 64 | /* Stream status */ |
| 62 | 65 | ||
| 63 | 66 | ||
| @@ -100,10 +103,10 @@ typedef struct internal_state { | |||
| 100 | Bytef *pending_buf; /* output still pending */ | 103 | Bytef *pending_buf; /* output still pending */ |
| 101 | ulg pending_buf_size; /* size of pending_buf */ | 104 | ulg pending_buf_size; /* size of pending_buf */ |
| 102 | Bytef *pending_out; /* next pending byte to output to the stream */ | 105 | Bytef *pending_out; /* next pending byte to output to the stream */ |
| 103 | uInt pending; /* nb of bytes in the pending buffer */ | 106 | ulg pending; /* nb of bytes in the pending buffer */ |
| 104 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ | 107 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ |
| 105 | gz_headerp gzhead; /* gzip header information to write */ | 108 | gz_headerp gzhead; /* gzip header information to write */ |
| 106 | uInt gzindex; /* where in extra, name, or comment */ | 109 | ulg gzindex; /* where in extra, name, or comment */ |
| 107 | Byte method; /* can only be DEFLATED */ | 110 | Byte method; /* can only be DEFLATED */ |
| 108 | int last_flush; /* value of flush param for previous deflate call */ | 111 | int last_flush; /* value of flush param for previous deflate call */ |
| 109 | 112 | ||
