aboutsummaryrefslogtreecommitdiff
path: root/deflate.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2016-11-05 22:55:34 -0700
committerMark Adler <madler@alumni.caltech.edu>2016-12-04 07:39:37 -0800
commit9674807c82ae06716a678d7374362acdb6f041b5 (patch)
treed2d36ae6ece89435bfdf7b21b766866a4bbf32b4 /deflate.c
parentfc130cdd9fcb0ea4decaf003be6ddf4c5dfd5760 (diff)
downloadzlib-9674807c82ae06716a678d7374362acdb6f041b5.tar.gz
zlib-9674807c82ae06716a678d7374362acdb6f041b5.tar.bz2
zlib-9674807c82ae06716a678d7374362acdb6f041b5.zip
Fix bugs in creating a very large gzip header.
Diffstat (limited to 'deflate.c')
-rw-r--r--deflate.c339
1 files changed, 179 insertions, 160 deletions
diff --git a/deflate.c b/deflate.c
index c71c3f5..3d24cbc 100644
--- a/deflate.c
+++ b/deflate.c
@@ -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/* ========================================================================= */
680int ZEXPORT deflate (strm, flush) 699int 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 */