summaryrefslogtreecommitdiff
path: root/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'inflate.c')
-rw-r--r--inflate.c123
1 files changed, 78 insertions, 45 deletions
diff --git a/inflate.c b/inflate.c
index 792fdee..d3c718c 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,5 +1,5 @@
1/* inflate.c -- zlib decompression 1/* inflate.c -- zlib decompression
2 * Copyright (C) 1995-2005 Mark Adler 2 * Copyright (C) 1995-2006 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
@@ -121,6 +121,7 @@ z_streamp strm;
121 state->hold = 0; 121 state->hold = 0;
122 state->bits = 0; 122 state->bits = 0;
123 state->lencode = state->distcode = state->next = state->codes; 123 state->lencode = state->distcode = state->next = state->codes;
124 state->sane = 1;
124 Tracev((stderr, "inflate: reset\n")); 125 Tracev((stderr, "inflate: reset\n"));
125 return Z_OK; 126 return Z_OK;
126} 127}
@@ -564,7 +565,7 @@ int flush;
564 unsigned in, out; /* save starting available input and output */ 565 unsigned in, out; /* save starting available input and output */
565 unsigned copy; /* number of stored or match bytes to copy */ 566 unsigned copy; /* number of stored or match bytes to copy */
566 unsigned char FAR *from; /* where to copy match bytes from */ 567 unsigned char FAR *from; /* where to copy match bytes from */
567 code this; /* current decoding table entry */ 568 code here; /* current decoding table entry */
568 code last; /* parent table entry */ 569 code last; /* parent table entry */
569 unsigned len; /* length to copy for repeats, bits to drop */ 570 unsigned len; /* length to copy for repeats, bits to drop */
570 int ret; /* return code */ 571 int ret; /* return code */
@@ -876,19 +877,19 @@ int flush;
876 case CODELENS: 877 case CODELENS:
877 while (state->have < state->nlen + state->ndist) { 878 while (state->have < state->nlen + state->ndist) {
878 for (;;) { 879 for (;;) {
879 this = state->lencode[BITS(state->lenbits)]; 880 here = state->lencode[BITS(state->lenbits)];
880 if ((unsigned)(this.bits) <= bits) break; 881 if ((unsigned)(here.bits) <= bits) break;
881 PULLBYTE(); 882 PULLBYTE();
882 } 883 }
883 if (this.val < 16) { 884 if (here.val < 16) {
884 NEEDBITS(this.bits); 885 NEEDBITS(here.bits);
885 DROPBITS(this.bits); 886 DROPBITS(here.bits);
886 state->lens[state->have++] = this.val; 887 state->lens[state->have++] = here.val;
887 } 888 }
888 else { 889 else {
889 if (this.val == 16) { 890 if (here.val == 16) {
890 NEEDBITS(this.bits + 2); 891 NEEDBITS(here.bits + 2);
891 DROPBITS(this.bits); 892 DROPBITS(here.bits);
892 if (state->have == 0) { 893 if (state->have == 0) {
893 strm->msg = (char *)"invalid bit length repeat"; 894 strm->msg = (char *)"invalid bit length repeat";
894 state->mode = BAD; 895 state->mode = BAD;
@@ -898,16 +899,16 @@ int flush;
898 copy = 3 + BITS(2); 899 copy = 3 + BITS(2);
899 DROPBITS(2); 900 DROPBITS(2);
900 } 901 }
901 else if (this.val == 17) { 902 else if (here.val == 17) {
902 NEEDBITS(this.bits + 3); 903 NEEDBITS(here.bits + 3);
903 DROPBITS(this.bits); 904 DROPBITS(here.bits);
904 len = 0; 905 len = 0;
905 copy = 3 + BITS(3); 906 copy = 3 + BITS(3);
906 DROPBITS(3); 907 DROPBITS(3);
907 } 908 }
908 else { 909 else {
909 NEEDBITS(this.bits + 7); 910 NEEDBITS(here.bits + 7);
910 DROPBITS(this.bits); 911 DROPBITS(here.bits);
911 len = 0; 912 len = 0;
912 copy = 11 + BITS(7); 913 copy = 11 + BITS(7);
913 DROPBITS(7); 914 DROPBITS(7);
@@ -955,40 +956,40 @@ int flush;
955 break; 956 break;
956 } 957 }
957 for (;;) { 958 for (;;) {
958 this = state->lencode[BITS(state->lenbits)]; 959 here = state->lencode[BITS(state->lenbits)];
959 if ((unsigned)(this.bits) <= bits) break; 960 if ((unsigned)(here.bits) <= bits) break;
960 PULLBYTE(); 961 PULLBYTE();
961 } 962 }
962 if (this.op && (this.op & 0xf0) == 0) { 963 if (here.op && (here.op & 0xf0) == 0) {
963 last = this; 964 last = here;
964 for (;;) { 965 for (;;) {
965 this = state->lencode[last.val + 966 here = state->lencode[last.val +
966 (BITS(last.bits + last.op) >> last.bits)]; 967 (BITS(last.bits + last.op) >> last.bits)];
967 if ((unsigned)(last.bits + this.bits) <= bits) break; 968 if ((unsigned)(last.bits + here.bits) <= bits) break;
968 PULLBYTE(); 969 PULLBYTE();
969 } 970 }
970 DROPBITS(last.bits); 971 DROPBITS(last.bits);
971 } 972 }
972 DROPBITS(this.bits); 973 DROPBITS(here.bits);
973 state->length = (unsigned)this.val; 974 state->length = (unsigned)here.val;
974 if ((int)(this.op) == 0) { 975 if ((int)(here.op) == 0) {
975 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? 976 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
976 "inflate: literal '%c'\n" : 977 "inflate: literal '%c'\n" :
977 "inflate: literal 0x%02x\n", this.val)); 978 "inflate: literal 0x%02x\n", here.val));
978 state->mode = LIT; 979 state->mode = LIT;
979 break; 980 break;
980 } 981 }
981 if (this.op & 32) { 982 if (here.op & 32) {
982 Tracevv((stderr, "inflate: end of block\n")); 983 Tracevv((stderr, "inflate: end of block\n"));
983 state->mode = TYPE; 984 state->mode = TYPE;
984 break; 985 break;
985 } 986 }
986 if (this.op & 64) { 987 if (here.op & 64) {
987 strm->msg = (char *)"invalid literal/length code"; 988 strm->msg = (char *)"invalid literal/length code";
988 state->mode = BAD; 989 state->mode = BAD;
989 break; 990 break;
990 } 991 }
991 state->extra = (unsigned)(this.op) & 15; 992 state->extra = (unsigned)(here.op) & 15;
992 state->mode = LENEXT; 993 state->mode = LENEXT;
993 case LENEXT: 994 case LENEXT:
994 if (state->extra) { 995 if (state->extra) {
@@ -1000,28 +1001,28 @@ int flush;
1000 state->mode = DIST; 1001 state->mode = DIST;
1001 case DIST: 1002 case DIST:
1002 for (;;) { 1003 for (;;) {
1003 this = state->distcode[BITS(state->distbits)]; 1004 here = state->distcode[BITS(state->distbits)];
1004 if ((unsigned)(this.bits) <= bits) break; 1005 if ((unsigned)(here.bits) <= bits) break;
1005 PULLBYTE(); 1006 PULLBYTE();
1006 } 1007 }
1007 if ((this.op & 0xf0) == 0) { 1008 if ((here.op & 0xf0) == 0) {
1008 last = this; 1009 last = here;
1009 for (;;) { 1010 for (;;) {
1010 this = state->distcode[last.val + 1011 here = state->distcode[last.val +
1011 (BITS(last.bits + last.op) >> last.bits)]; 1012 (BITS(last.bits + last.op) >> last.bits)];
1012 if ((unsigned)(last.bits + this.bits) <= bits) break; 1013 if ((unsigned)(last.bits + here.bits) <= bits) break;
1013 PULLBYTE(); 1014 PULLBYTE();
1014 } 1015 }
1015 DROPBITS(last.bits); 1016 DROPBITS(last.bits);
1016 } 1017 }
1017 DROPBITS(this.bits); 1018 DROPBITS(here.bits);
1018 if (this.op & 64) { 1019 if (here.op & 64) {
1019 strm->msg = (char *)"invalid distance code"; 1020 strm->msg = (char *)"invalid distance code";
1020 state->mode = BAD; 1021 state->mode = BAD;
1021 break; 1022 break;
1022 } 1023 }
1023 state->offset = (unsigned)this.val; 1024 state->offset = (unsigned)here.val;
1024 state->extra = (unsigned)(this.op) & 15; 1025 state->extra = (unsigned)(here.op) & 15;
1025 state->mode = DISTEXT; 1026 state->mode = DISTEXT;
1026 case DISTEXT: 1027 case DISTEXT:
1027 if (state->extra) { 1028 if (state->extra) {
@@ -1036,11 +1037,6 @@ int flush;
1036 break; 1037 break;
1037 } 1038 }
1038#endif 1039#endif
1039 if (state->offset > state->whave + out - left) {
1040 strm->msg = (char *)"invalid distance too far back";
1041 state->mode = BAD;
1042 break;
1043 }
1044 Tracevv((stderr, "inflate: distance %u\n", state->offset)); 1040 Tracevv((stderr, "inflate: distance %u\n", state->offset));
1045 state->mode = MATCH; 1041 state->mode = MATCH;
1046 case MATCH: 1042 case MATCH:
@@ -1048,6 +1044,26 @@ int flush;
1048 copy = out - left; 1044 copy = out - left;
1049 if (state->offset > copy) { /* copy from window */ 1045 if (state->offset > copy) { /* copy from window */
1050 copy = state->offset - copy; 1046 copy = state->offset - copy;
1047 if (copy > state->whave) {
1048 if (state->sane) {
1049 strm->msg = (char *)"invalid distance too far back";
1050 state->mode = BAD;
1051 break;
1052 }
1053#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1054 Trace((stderr, "inflate.c too far\n"));
1055 copy -= state->whave;
1056 if (copy > state->length) copy = state->length;
1057 if (copy > left) copy = left;
1058 left -= copy;
1059 state->length -= copy;
1060 do {
1061 *put++ = 0;
1062 } while (--copy);
1063 if (state->length == 0) state->mode = LEN;
1064 break;
1065#endif
1066 }
1051 if (copy > state->write) { 1067 if (copy > state->write) {
1052 copy -= state->write; 1068 copy -= state->write;
1053 from = state->window + (state->wsize - copy); 1069 from = state->window + (state->wsize - copy);
@@ -1366,3 +1382,20 @@ z_streamp source;
1366 dest->state = (struct internal_state FAR *)copy; 1382 dest->state = (struct internal_state FAR *)copy;
1367 return Z_OK; 1383 return Z_OK;
1368} 1384}
1385
1386int ZEXPORT inflateUndermine(strm, subvert)
1387z_streamp strm;
1388int subvert;
1389{
1390 struct inflate_state FAR *state;
1391
1392 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1393 state = (struct inflate_state FAR *)strm->state;
1394#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1395 state->sane = !subvert;
1396 return Z_OK;
1397#else
1398 state->sane = 1;
1399 return Z_DATA_ERROR;
1400#endif
1401}