diff options
Diffstat (limited to 'inflate.c')
-rw-r--r-- | inflate.c | 75 |
1 files changed, 68 insertions, 7 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* inflate.c -- zlib decompression | 1 | /* inflate.c -- zlib decompression |
2 | * Copyright (C) 1995-2003 Mark Adler | 2 | * Copyright (C) 1995-2004 Mark Adler |
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -113,6 +113,7 @@ z_streamp strm; | |||
113 | state->mode = HEAD; | 113 | state->mode = HEAD; |
114 | state->last = 0; | 114 | state->last = 0; |
115 | state->havedict = 0; | 115 | state->havedict = 0; |
116 | state->head = Z_NULL; | ||
116 | state->wsize = 0; | 117 | state->wsize = 0; |
117 | state->whave = 0; | 118 | state->whave = 0; |
118 | state->hold = 0; | 119 | state->hold = 0; |
@@ -582,6 +583,8 @@ int flush; | |||
582 | break; | 583 | break; |
583 | } | 584 | } |
584 | state->flags = 0; /* expect zlib header */ | 585 | state->flags = 0; /* expect zlib header */ |
586 | if (state->head != Z_NULL) | ||
587 | state->head->done = -1; | ||
585 | if (!(state->wrap & 1) || /* check if zlib header allowed */ | 588 | if (!(state->wrap & 1) || /* check if zlib header allowed */ |
586 | #else | 589 | #else |
587 | if ( | 590 | if ( |
@@ -621,16 +624,24 @@ int flush; | |||
621 | state->mode = BAD; | 624 | state->mode = BAD; |
622 | break; | 625 | break; |
623 | } | 626 | } |
627 | if (state->head != Z_NULL) | ||
628 | state->head->text = (int)((hold >> 8) & 1); | ||
624 | if (state->flags & 0x0200) CRC2(state->check, hold); | 629 | if (state->flags & 0x0200) CRC2(state->check, hold); |
625 | INITBITS(); | 630 | INITBITS(); |
626 | state->mode = TIME; | 631 | state->mode = TIME; |
627 | case TIME: | 632 | case TIME: |
628 | NEEDBITS(32); | 633 | NEEDBITS(32); |
634 | if (state->head != Z_NULL) | ||
635 | state->head->time = hold; | ||
629 | if (state->flags & 0x0200) CRC4(state->check, hold); | 636 | if (state->flags & 0x0200) CRC4(state->check, hold); |
630 | INITBITS(); | 637 | INITBITS(); |
631 | state->mode = OS; | 638 | state->mode = OS; |
632 | case OS: | 639 | case OS: |
633 | NEEDBITS(16); | 640 | NEEDBITS(16); |
641 | if (state->head != Z_NULL) { | ||
642 | state->head->xflags = (int)(hold & 0xff); | ||
643 | state->head->os = (int)(hold >> 8); | ||
644 | } | ||
634 | if (state->flags & 0x0200) CRC2(state->check, hold); | 645 | if (state->flags & 0x0200) CRC2(state->check, hold); |
635 | INITBITS(); | 646 | INITBITS(); |
636 | state->mode = EXLEN; | 647 | state->mode = EXLEN; |
@@ -638,15 +649,26 @@ int flush; | |||
638 | if (state->flags & 0x0400) { | 649 | if (state->flags & 0x0400) { |
639 | NEEDBITS(16); | 650 | NEEDBITS(16); |
640 | state->length = (unsigned)(hold); | 651 | state->length = (unsigned)(hold); |
652 | if (state->head != Z_NULL) | ||
653 | state->head->extra_len = (unsigned)hold; | ||
641 | if (state->flags & 0x0200) CRC2(state->check, hold); | 654 | if (state->flags & 0x0200) CRC2(state->check, hold); |
642 | INITBITS(); | 655 | INITBITS(); |
643 | } | 656 | } |
657 | else if (state->head != Z_NULL) | ||
658 | state->head->extra = Z_NULL; | ||
644 | state->mode = EXTRA; | 659 | state->mode = EXTRA; |
645 | case EXTRA: | 660 | case EXTRA: |
646 | if (state->flags & 0x0400) { | 661 | if (state->flags & 0x0400) { |
647 | copy = state->length; | 662 | copy = state->length; |
648 | if (copy > have) copy = have; | 663 | if (copy > have) copy = have; |
649 | if (copy) { | 664 | if (copy) { |
665 | if (state->head != Z_NULL && | ||
666 | state->head->extra != Z_NULL) { | ||
667 | len = state->head->extra_len - state->length; | ||
668 | zmemcpy(state->head->extra + len, next, | ||
669 | len + copy > state->head->extra_max ? | ||
670 | state->head->extra_max - len : copy); | ||
671 | } | ||
650 | if (state->flags & 0x0200) | 672 | if (state->flags & 0x0200) |
651 | state->check = crc32(state->check, next, copy); | 673 | state->check = crc32(state->check, next, copy); |
652 | have -= copy; | 674 | have -= copy; |
@@ -655,6 +677,7 @@ int flush; | |||
655 | } | 677 | } |
656 | if (state->length) goto inf_leave; | 678 | if (state->length) goto inf_leave; |
657 | } | 679 | } |
680 | state->length = 0; | ||
658 | state->mode = NAME; | 681 | state->mode = NAME; |
659 | case NAME: | 682 | case NAME: |
660 | if (state->flags & 0x0800) { | 683 | if (state->flags & 0x0800) { |
@@ -662,13 +685,20 @@ int flush; | |||
662 | copy = 0; | 685 | copy = 0; |
663 | do { | 686 | do { |
664 | len = (unsigned)(next[copy++]); | 687 | len = (unsigned)(next[copy++]); |
688 | if (state->head != Z_NULL && | ||
689 | state->head->name != Z_NULL && | ||
690 | state->length < state->head->name_max) | ||
691 | state->head->name[state->length++] = len; | ||
665 | } while (len && copy < have); | 692 | } while (len && copy < have); |
666 | if (state->flags & 0x02000) | 693 | if (state->flags & 0x0200) |
667 | state->check = crc32(state->check, next, copy); | 694 | state->check = crc32(state->check, next, copy); |
668 | have -= copy; | 695 | have -= copy; |
669 | next += copy; | 696 | next += copy; |
670 | if (len) goto inf_leave; | 697 | if (len) goto inf_leave; |
671 | } | 698 | } |
699 | else if (state->head != Z_NULL) | ||
700 | state->head->name = Z_NULL; | ||
701 | state->length = 0; | ||
672 | state->mode = COMMENT; | 702 | state->mode = COMMENT; |
673 | case COMMENT: | 703 | case COMMENT: |
674 | if (state->flags & 0x1000) { | 704 | if (state->flags & 0x1000) { |
@@ -676,13 +706,19 @@ int flush; | |||
676 | copy = 0; | 706 | copy = 0; |
677 | do { | 707 | do { |
678 | len = (unsigned)(next[copy++]); | 708 | len = (unsigned)(next[copy++]); |
709 | if (state->head != Z_NULL && | ||
710 | state->head->comment != Z_NULL && | ||
711 | state->length < state->head->comm_max) | ||
712 | state->head->comment[state->length++] = len; | ||
679 | } while (len && copy < have); | 713 | } while (len && copy < have); |
680 | if (state->flags & 0x02000) | 714 | if (state->flags & 0x0200) |
681 | state->check = crc32(state->check, next, copy); | 715 | state->check = crc32(state->check, next, copy); |
682 | have -= copy; | 716 | have -= copy; |
683 | next += copy; | 717 | next += copy; |
684 | if (len) goto inf_leave; | 718 | if (len) goto inf_leave; |
685 | } | 719 | } |
720 | else if (state->head != Z_NULL) | ||
721 | state->head->comment = Z_NULL; | ||
686 | state->mode = HCRC; | 722 | state->mode = HCRC; |
687 | case HCRC: | 723 | case HCRC: |
688 | if (state->flags & 0x0200) { | 724 | if (state->flags & 0x0200) { |
@@ -694,6 +730,10 @@ int flush; | |||
694 | } | 730 | } |
695 | INITBITS(); | 731 | INITBITS(); |
696 | } | 732 | } |
733 | if (state->head != Z_NULL) { | ||
734 | state->head->hcrc = (int)((state->flags >> 9) & 1); | ||
735 | state->head->done = 1; | ||
736 | } | ||
697 | strm->adler = state->check = crc32(0L, Z_NULL, 0); | 737 | strm->adler = state->check = crc32(0L, Z_NULL, 0); |
698 | state->mode = TYPE; | 738 | state->mode = TYPE; |
699 | break; | 739 | break; |
@@ -1110,12 +1150,16 @@ uInt dictLength; | |||
1110 | /* check state */ | 1150 | /* check state */ |
1111 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 1151 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
1112 | state = (struct inflate_state FAR *)strm->state; | 1152 | state = (struct inflate_state FAR *)strm->state; |
1113 | if (state->mode != DICT) return Z_STREAM_ERROR; | 1153 | if (state->wrap != 0 && state->mode != DICT) |
1154 | return Z_STREAM_ERROR; | ||
1114 | 1155 | ||
1115 | /* check for correct dictionary id */ | 1156 | /* check for correct dictionary id */ |
1116 | id = adler32(0L, Z_NULL, 0); | 1157 | if (state->mode == DICT) { |
1117 | id = adler32(id, dictionary, dictLength); | 1158 | id = adler32(0L, Z_NULL, 0); |
1118 | if (id != state->check) return Z_DATA_ERROR; | 1159 | id = adler32(id, dictionary, dictLength); |
1160 | if (id != state->check) | ||
1161 | return Z_DATA_ERROR; | ||
1162 | } | ||
1119 | 1163 | ||
1120 | /* copy dictionary to window */ | 1164 | /* copy dictionary to window */ |
1121 | if (updatewindow(strm, strm->avail_out)) { | 1165 | if (updatewindow(strm, strm->avail_out)) { |
@@ -1137,6 +1181,23 @@ uInt dictLength; | |||
1137 | return Z_OK; | 1181 | return Z_OK; |
1138 | } | 1182 | } |
1139 | 1183 | ||
1184 | int ZEXPORT inflateGetHeader(strm, head) | ||
1185 | z_streamp strm; | ||
1186 | gz_headerp head; | ||
1187 | { | ||
1188 | struct inflate_state FAR *state; | ||
1189 | |||
1190 | /* check state */ | ||
1191 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | ||
1192 | state = (struct inflate_state FAR *)strm->state; | ||
1193 | if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; | ||
1194 | |||
1195 | /* save header structure */ | ||
1196 | state->head = head; | ||
1197 | head->done = 0; | ||
1198 | return Z_OK; | ||
1199 | } | ||
1200 | |||
1140 | /* | 1201 | /* |
1141 | Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found | 1202 | Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found |
1142 | or when out of input. When called, *have is the number of pattern bytes | 1203 | or when out of input. When called, *have is the number of pattern bytes |