diff options
Diffstat (limited to 'inflate.c')
-rw-r--r-- | inflate.c | 56 |
1 files changed, 33 insertions, 23 deletions
@@ -25,10 +25,6 @@ struct internal_state { | |||
25 | ERROR} /* got an error--stay here */ | 25 | ERROR} /* got an error--stay here */ |
26 | mode; /* current inflate mode */ | 26 | mode; /* current inflate mode */ |
27 | 27 | ||
28 | int no_header; | ||
29 | uInt w_size; /* LZ77 window size (32K by default) */ | ||
30 | uInt w_bits; /* log2(w_size) (8..16) */ | ||
31 | |||
32 | /* mode dependent information */ | 28 | /* mode dependent information */ |
33 | union { | 29 | union { |
34 | uInt method; /* if FLAGS, method byte */ | 30 | uInt method; /* if FLAGS, method byte */ |
@@ -39,19 +35,26 @@ struct internal_state { | |||
39 | uLong need; /* stream check value */ | 35 | uLong need; /* stream check value */ |
40 | } check; /* if CHECK, check values to compare */ | 36 | } check; /* if CHECK, check values to compare */ |
41 | } sub; /* submode */ | 37 | } sub; /* submode */ |
38 | |||
39 | /* mode independent information */ | ||
40 | int nowrap; /* flag for no wrapper */ | ||
41 | uInt wbits; /* log2(window size) (8..15, defaults to 15) */ | ||
42 | |||
42 | }; | 43 | }; |
43 | 44 | ||
44 | 45 | ||
45 | int inflateInit (strm) | 46 | int inflateInit(z) |
46 | z_stream *strm; | 47 | z_stream *z; |
47 | { | 48 | { |
48 | return inflateInit2(strm, WBITS); | 49 | return inflateInit2(z, WBITS); |
49 | } | 50 | } |
50 | 51 | ||
51 | int inflateInit2(z, windowBits) | 52 | |
53 | int inflateInit2(z, w) | ||
52 | z_stream *z; | 54 | z_stream *z; |
53 | int windowBits; | 55 | int w; |
54 | { | 56 | { |
57 | /* initialize state */ | ||
55 | if (z == Z_NULL) | 58 | if (z == Z_NULL) |
56 | return Z_STREAM_ERROR; | 59 | return Z_STREAM_ERROR; |
57 | if (z->zalloc == Z_NULL) z->zalloc = zcalloc; | 60 | if (z->zalloc == Z_NULL) z->zalloc = zcalloc; |
@@ -63,19 +66,22 @@ int windowBits; | |||
63 | return Z_MEM_ERROR; | 66 | return Z_MEM_ERROR; |
64 | z->state->mode = METHOD; | 67 | z->state->mode = METHOD; |
65 | 68 | ||
66 | z->state->no_header = 0; | 69 | /* handle undocumented nowrap option (no zlib header or check) */ |
67 | if (windowBits < 0) { /* undocumented feature: no zlib header */ | 70 | z->state->nowrap = 0; |
68 | windowBits = - windowBits; | 71 | if (w < 0) |
69 | z->state->no_header = 1; | 72 | { |
70 | z->state->sub.method = DEFLATED; | 73 | w = - w; |
74 | z->state->nowrap = 1; | ||
71 | z->state->mode = START; | 75 | z->state->mode = START; |
72 | } | 76 | } |
73 | if (windowBits < 8 || windowBits > 15) { | 77 | |
78 | /* set window size */ | ||
79 | if (w < 8 || w > 15) | ||
80 | { | ||
74 | inflateEnd(z); | 81 | inflateEnd(z); |
75 | return Z_STREAM_ERROR; | 82 | return Z_STREAM_ERROR; |
76 | } | 83 | } |
77 | z->state->w_bits = windowBits; | 84 | z->state->wbits = w; |
78 | z->state->w_size = 1<<windowBits; | ||
79 | return Z_OK; | 85 | return Z_OK; |
80 | } | 86 | } |
81 | 87 | ||
@@ -103,7 +109,7 @@ int f; | |||
103 | z->msg = "unknown compression method"; | 109 | z->msg = "unknown compression method"; |
104 | return Z_DATA_ERROR; | 110 | return Z_DATA_ERROR; |
105 | } | 111 | } |
106 | if ((z->state->sub.method >> 4) > z->state->w_bits) | 112 | if ((z->state->sub.method >> 4) + 8 > z->state->wbits) |
107 | { | 113 | { |
108 | z->state->mode = ERROR; | 114 | z->state->mode = ERROR; |
109 | z->msg = "invalid window size"; | 115 | z->msg = "invalid window size"; |
@@ -126,17 +132,21 @@ int f; | |||
126 | } | 132 | } |
127 | z->state->mode = START; | 133 | z->state->mode = START; |
128 | case START: | 134 | case START: |
129 | if ((z->state->sub.blocks = inflate_blocks_new(z,z->state->w_size)) | 135 | if ((z->state->sub.blocks = inflate_blocks_new(z, |
130 | == Z_NULL) | 136 | z->state->nowrap ? Z_NULL : adler32, |
137 | 1<< z->state->wbits)) == Z_NULL) | ||
131 | return Z_MEM_ERROR; | 138 | return Z_MEM_ERROR; |
132 | z->state->mode = BLOCKS; | 139 | z->state->mode = BLOCKS; |
133 | case BLOCKS: | 140 | case BLOCKS: |
134 | if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END) | 141 | if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END) |
135 | return r; | 142 | return r; |
136 | inflate_blocks_free(z->state->sub.blocks, z, &c, &r); | 143 | inflate_blocks_free(z->state->sub.blocks, z, &c, &r); |
137 | if (z->state->no_header) { | 144 | if (z->state->nowrap) |
138 | z->state->mode = DONE; | 145 | { |
139 | return Z_STREAM_END; | 146 | if (r != -1) |
147 | z->msg = "inflate bug--took one too many bytes"; | ||
148 | z->state->mode = r == -1 ? DONE : ERROR; | ||
149 | break; | ||
140 | } | 150 | } |
141 | z->state->sub.check.was = c; | 151 | z->state->sub.check.was = c; |
142 | if (r != -1) | 152 | if (r != -1) |