diff options
Diffstat (limited to 'inflate.c')
-rw-r--r-- | inflate.c | 96 |
1 files changed, 77 insertions, 19 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* inflate.c -- zlib interface to inflate modules | 1 | /* inflate.c -- zlib interface to inflate modules |
2 | * Copyright (C) 1995 Mark Adler | 2 | * Copyright (C) 1995-1996 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 | ||
@@ -15,6 +15,11 @@ struct internal_state { | |||
15 | enum { | 15 | enum { |
16 | METHOD, /* waiting for method byte */ | 16 | METHOD, /* waiting for method byte */ |
17 | FLAG, /* waiting for flag byte */ | 17 | FLAG, /* waiting for flag byte */ |
18 | DICT4, /* four dictionary check bytes to go */ | ||
19 | DICT3, /* three dictionary check bytes to go */ | ||
20 | DICT2, /* two dictionary check bytes to go */ | ||
21 | DICT1, /* one dictionary check byte to go */ | ||
22 | DICT0, /* waiting for inflateSetDictionary */ | ||
18 | BLOCKS, /* decompressing blocks */ | 23 | BLOCKS, /* decompressing blocks */ |
19 | CHECK4, /* four check bytes to go */ | 24 | CHECK4, /* four check bytes to go */ |
20 | CHECK3, /* three check bytes to go */ | 25 | CHECK3, /* three check bytes to go */ |
@@ -75,10 +80,16 @@ z_stream *z; | |||
75 | } | 80 | } |
76 | 81 | ||
77 | 82 | ||
78 | int inflateInit2(z, w) | 83 | int inflateInit2_(z, w, version, stream_size) |
79 | z_stream *z; | 84 | z_stream *z; |
80 | int w; | 85 | int w; |
86 | const char *version; | ||
87 | int stream_size; | ||
81 | { | 88 | { |
89 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || | ||
90 | stream_size != sizeof(z_stream)) | ||
91 | return Z_VERSION_ERROR; | ||
92 | |||
82 | /* initialize state */ | 93 | /* initialize state */ |
83 | if (z == Z_NULL) | 94 | if (z == Z_NULL) |
84 | return Z_STREAM_ERROR; | 95 | return Z_STREAM_ERROR; |
@@ -112,7 +123,7 @@ int w; | |||
112 | 123 | ||
113 | /* create inflate_blocks state */ | 124 | /* create inflate_blocks state */ |
114 | if ((z->state->blocks = | 125 | if ((z->state->blocks = |
115 | inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) | 126 | inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) |
116 | == Z_NULL) | 127 | == Z_NULL) |
117 | { | 128 | { |
118 | inflateEnd(z); | 129 | inflateEnd(z); |
@@ -126,10 +137,12 @@ int w; | |||
126 | } | 137 | } |
127 | 138 | ||
128 | 139 | ||
129 | int inflateInit(z) | 140 | int inflateInit_(z, version, stream_size) |
130 | z_stream *z; | 141 | z_stream *z; |
142 | const char *version; | ||
143 | int stream_size; | ||
131 | { | 144 | { |
132 | return inflateInit2(z, DEF_WBITS); | 145 | return inflateInit2_(z, DEF_WBITS, version, stream_size); |
133 | } | 146 | } |
134 | 147 | ||
135 | 148 | ||
@@ -140,10 +153,10 @@ int inflate(z, f) | |||
140 | z_stream *z; | 153 | z_stream *z; |
141 | int f; | 154 | int f; |
142 | { | 155 | { |
143 | int r = f; /* to avoid warning about unused f */ | 156 | int r; |
144 | uInt b; | 157 | uInt b; |
145 | 158 | ||
146 | if (z == Z_NULL || z->next_in == Z_NULL) | 159 | if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) |
147 | return Z_STREAM_ERROR; | 160 | return Z_STREAM_ERROR; |
148 | r = Z_BUF_ERROR; | 161 | r = Z_BUF_ERROR; |
149 | while (1) switch (z->state->mode) | 162 | while (1) switch (z->state->mode) |
@@ -153,36 +166,58 @@ int f; | |||
153 | if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) | 166 | if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) |
154 | { | 167 | { |
155 | z->state->mode = BAD; | 168 | z->state->mode = BAD; |
156 | z->msg = "unknown compression method"; | 169 | z->msg = (char*)"unknown compression method"; |
157 | z->state->sub.marker = 5; /* can't try inflateSync */ | 170 | z->state->sub.marker = 5; /* can't try inflateSync */ |
158 | break; | 171 | break; |
159 | } | 172 | } |
160 | if ((z->state->sub.method >> 4) + 8 > z->state->wbits) | 173 | if ((z->state->sub.method >> 4) + 8 > z->state->wbits) |
161 | { | 174 | { |
162 | z->state->mode = BAD; | 175 | z->state->mode = BAD; |
163 | z->msg = "invalid window size"; | 176 | z->msg = (char*)"invalid window size"; |
164 | z->state->sub.marker = 5; /* can't try inflateSync */ | 177 | z->state->sub.marker = 5; /* can't try inflateSync */ |
165 | break; | 178 | break; |
166 | } | 179 | } |
167 | z->state->mode = FLAG; | 180 | z->state->mode = FLAG; |
168 | case FLAG: | 181 | case FLAG: |
169 | NEEDBYTE | 182 | NEEDBYTE |
170 | if ((b = NEXTBYTE) & 0x20) | 183 | b = NEXTBYTE; |
171 | { | ||
172 | z->state->mode = BAD; | ||
173 | z->msg = "invalid reserved bit"; | ||
174 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
175 | break; | ||
176 | } | ||
177 | if (((z->state->sub.method << 8) + b) % 31) | 184 | if (((z->state->sub.method << 8) + b) % 31) |
178 | { | 185 | { |
179 | z->state->mode = BAD; | 186 | z->state->mode = BAD; |
180 | z->msg = "incorrect header check"; | 187 | z->msg = (char*)"incorrect header check"; |
181 | z->state->sub.marker = 5; /* can't try inflateSync */ | 188 | z->state->sub.marker = 5; /* can't try inflateSync */ |
182 | break; | 189 | break; |
183 | } | 190 | } |
184 | Trace((stderr, "inflate: zlib header ok\n")); | 191 | Trace((stderr, "inflate: zlib header ok\n")); |
185 | z->state->mode = BLOCKS; | 192 | if (!(b & PRESET_DICT)) |
193 | { | ||
194 | z->state->mode = BLOCKS; | ||
195 | break; | ||
196 | } | ||
197 | z->state->mode = DICT4; | ||
198 | case DICT4: | ||
199 | NEEDBYTE | ||
200 | z->state->sub.check.need = (uLong)NEXTBYTE << 24; | ||
201 | z->state->mode = DICT3; | ||
202 | case DICT3: | ||
203 | NEEDBYTE | ||
204 | z->state->sub.check.need += (uLong)NEXTBYTE << 16; | ||
205 | z->state->mode = DICT2; | ||
206 | case DICT2: | ||
207 | NEEDBYTE | ||
208 | z->state->sub.check.need += (uLong)NEXTBYTE << 8; | ||
209 | z->state->mode = DICT1; | ||
210 | case DICT1: | ||
211 | NEEDBYTE | ||
212 | z->state->sub.check.need += (uLong)NEXTBYTE; | ||
213 | z->adler = z->state->sub.check.need; | ||
214 | z->state->mode = DICT0; | ||
215 | return Z_NEED_DICT; | ||
216 | case DICT0: | ||
217 | z->state->mode = BAD; | ||
218 | z->msg = (char*)"need dictionary"; | ||
219 | z->state->sub.marker = 0; /* can try inflateSync */ | ||
220 | return Z_STREAM_ERROR; | ||
186 | case BLOCKS: | 221 | case BLOCKS: |
187 | r = inflate_blocks(z->state->blocks, z, r); | 222 | r = inflate_blocks(z->state->blocks, z, r); |
188 | if (r == Z_DATA_ERROR) | 223 | if (r == Z_DATA_ERROR) |
@@ -220,7 +255,7 @@ int f; | |||
220 | if (z->state->sub.check.was != z->state->sub.check.need) | 255 | if (z->state->sub.check.was != z->state->sub.check.need) |
221 | { | 256 | { |
222 | z->state->mode = BAD; | 257 | z->state->mode = BAD; |
223 | z->msg = "incorrect data check"; | 258 | z->msg = (char*)"incorrect data check"; |
224 | z->state->sub.marker = 5; /* can't try inflateSync */ | 259 | z->state->sub.marker = 5; /* can't try inflateSync */ |
225 | break; | 260 | break; |
226 | } | 261 | } |
@@ -236,6 +271,29 @@ int f; | |||
236 | } | 271 | } |
237 | 272 | ||
238 | 273 | ||
274 | int inflateSetDictionary(z, dictionary, dictLength) | ||
275 | z_stream *z; | ||
276 | const Bytef *dictionary; | ||
277 | uInt dictLength; | ||
278 | { | ||
279 | uInt length = dictLength; | ||
280 | |||
281 | if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) | ||
282 | return Z_STREAM_ERROR; | ||
283 | if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; | ||
284 | z->adler = 1L; | ||
285 | |||
286 | if (length >= ((uInt)1<<z->state->wbits)) | ||
287 | { | ||
288 | length = (1<<z->state->wbits)-1; | ||
289 | dictionary += dictLength - length; | ||
290 | } | ||
291 | inflate_set_dictionary(z->state->blocks, dictionary, length); | ||
292 | z->state->mode = BLOCKS; | ||
293 | return Z_OK; | ||
294 | } | ||
295 | |||
296 | |||
239 | int inflateSync(z) | 297 | int inflateSync(z) |
240 | z_stream *z; | 298 | z_stream *z; |
241 | { | 299 | { |