diff options
Diffstat (limited to 'infblock.c')
-rw-r--r-- | infblock.c | 74 |
1 files changed, 53 insertions, 21 deletions
@@ -60,6 +60,28 @@ local uInt border[] = { /* Order of the bit length code lengths */ | |||
60 | the two sets of lengths. | 60 | the two sets of lengths. |
61 | */ | 61 | */ |
62 | 62 | ||
63 | |||
64 | void inflate_blocks_reset(s, z, c) | ||
65 | struct inflate_blocks_state *s; | ||
66 | z_stream *z; | ||
67 | uLong *c; | ||
68 | { | ||
69 | if (s->checkfn != Z_NULL) | ||
70 | *c = s->check; | ||
71 | if (s->mode == BTREE || s->mode == DTREE) | ||
72 | ZFREE(z, s->sub.trees.blens); | ||
73 | if (s->mode == CODES) | ||
74 | inflate_codes_free(s->sub.codes, z); | ||
75 | s->mode = TYPE; | ||
76 | s->bitk = 0; | ||
77 | s->bitb = 0; | ||
78 | s->read = s->write = s->window; | ||
79 | if (s->checkfn != Z_NULL) | ||
80 | s->check = (*s->checkfn)(0L, Z_NULL, 0); | ||
81 | Trace((stderr, "inflate: blocks reset\n")); | ||
82 | } | ||
83 | |||
84 | |||
63 | struct inflate_blocks_state *inflate_blocks_new(z, c, w) | 85 | struct inflate_blocks_state *inflate_blocks_new(z, c, w) |
64 | z_stream *z; | 86 | z_stream *z; |
65 | check_func c; | 87 | check_func c; |
@@ -75,13 +97,11 @@ uInt w; | |||
75 | ZFREE(z, s); | 97 | ZFREE(z, s); |
76 | return Z_NULL; | 98 | return Z_NULL; |
77 | } | 99 | } |
78 | s->mode = TYPE; | ||
79 | s->bitk = 0; | ||
80 | s->read = s->write = s->window; | ||
81 | s->end = s->window + w; | 100 | s->end = s->window + w; |
82 | s->checkfn = c; | 101 | s->checkfn = c; |
83 | if (s->checkfn != Z_NULL) | 102 | s->mode = TYPE; |
84 | s->check = (*s->checkfn)(0L, Z_NULL, 0); | 103 | Trace((stderr, "inflate: blocks allocated\n")); |
104 | inflate_blocks_reset(s, z, &s->check); | ||
85 | return s; | 105 | return s; |
86 | } | 106 | } |
87 | 107 | ||
@@ -112,12 +132,16 @@ int r; | |||
112 | switch (t >> 1) | 132 | switch (t >> 1) |
113 | { | 133 | { |
114 | case 0: /* stored */ | 134 | case 0: /* stored */ |
135 | Trace((stderr, "inflate: stored block%s\n", | ||
136 | s->last ? " (last)" : "")); | ||
115 | DUMPBITS(3) | 137 | DUMPBITS(3) |
116 | t = k & 7; /* go to byte boundary */ | 138 | t = k & 7; /* go to byte boundary */ |
117 | DUMPBITS(t) | 139 | DUMPBITS(t) |
118 | s->mode = LENS; /* get length of stored block */ | 140 | s->mode = LENS; /* get length of stored block */ |
119 | break; | 141 | break; |
120 | case 1: /* fixed */ | 142 | case 1: /* fixed */ |
143 | Trace((stderr, "inflate: fixed codes block%s\n", | ||
144 | s->last ? " (last)" : "")); | ||
121 | { | 145 | { |
122 | uInt bl, bd; | 146 | uInt bl, bd; |
123 | inflate_huft *tl, *td; | 147 | inflate_huft *tl, *td; |
@@ -134,12 +158,14 @@ int r; | |||
134 | s->mode = CODES; | 158 | s->mode = CODES; |
135 | break; | 159 | break; |
136 | case 2: /* dynamic */ | 160 | case 2: /* dynamic */ |
161 | Trace((stderr, "inflate: dynamic codes block%s\n", | ||
162 | s->last ? " (last)" : "")); | ||
137 | DUMPBITS(3) | 163 | DUMPBITS(3) |
138 | s->mode = TABLE; | 164 | s->mode = TABLE; |
139 | break; | 165 | break; |
140 | case 3: /* illegal */ | 166 | case 3: /* illegal */ |
141 | DUMPBITS(3) | 167 | DUMPBITS(3) |
142 | s->mode = INF_ERROR; | 168 | s->mode = BAD; |
143 | z->msg = "invalid block type"; | 169 | z->msg = "invalid block type"; |
144 | r = Z_DATA_ERROR; | 170 | r = Z_DATA_ERROR; |
145 | LEAVE | 171 | LEAVE |
@@ -149,13 +175,14 @@ int r; | |||
149 | NEEDBITS(32) | 175 | NEEDBITS(32) |
150 | if ((~b) >> 16 != (b & 0xffff)) | 176 | if ((~b) >> 16 != (b & 0xffff)) |
151 | { | 177 | { |
152 | s->mode = INF_ERROR; | 178 | s->mode = BAD; |
153 | z->msg = "invalid stored block lengths"; | 179 | z->msg = "invalid stored block lengths"; |
154 | r = Z_DATA_ERROR; | 180 | r = Z_DATA_ERROR; |
155 | LEAVE | 181 | LEAVE |
156 | } | 182 | } |
157 | k = 0; /* dump bits */ | 183 | k = 0; /* dump bits */ |
158 | s->sub.left = (uInt)b & 0xffff; | 184 | s->sub.left = (uInt)b & 0xffff; |
185 | Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); | ||
159 | s->mode = s->sub.left ? STORED : TYPE; | 186 | s->mode = s->sub.left ? STORED : TYPE; |
160 | break; | 187 | break; |
161 | case STORED: | 188 | case STORED: |
@@ -164,6 +191,9 @@ int r; | |||
164 | NEEDOUT | 191 | NEEDOUT |
165 | OUTBYTE(NEXTBYTE) | 192 | OUTBYTE(NEXTBYTE) |
166 | } while (--s->sub.left); | 193 | } while (--s->sub.left); |
194 | Tracev((stderr, "inflate: stored end, %lu total out\n", | ||
195 | z->total_out + (q >= s->read ? q - s->read : | ||
196 | (s->end - s->read) + (q - s->window)))); | ||
167 | s->mode = s->last ? DRY : TYPE; | 197 | s->mode = s->last ? DRY : TYPE; |
168 | break; | 198 | break; |
169 | case TABLE: | 199 | case TABLE: |
@@ -172,7 +202,7 @@ int r; | |||
172 | #ifndef PKZIP_BUG_WORKAROUND | 202 | #ifndef PKZIP_BUG_WORKAROUND |
173 | if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) | 203 | if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) |
174 | { | 204 | { |
175 | s->mode = INF_ERROR; | 205 | s->mode = BAD; |
176 | z->msg = "too many length or distance symbols"; | 206 | z->msg = "too many length or distance symbols"; |
177 | r = Z_DATA_ERROR; | 207 | r = Z_DATA_ERROR; |
178 | LEAVE | 208 | LEAVE |
@@ -188,6 +218,7 @@ int r; | |||
188 | } | 218 | } |
189 | DUMPBITS(14) | 219 | DUMPBITS(14) |
190 | s->sub.trees.index = 0; | 220 | s->sub.trees.index = 0; |
221 | Tracev((stderr, "inflate: table sizes ok\n")); | ||
191 | s->mode = BTREE; | 222 | s->mode = BTREE; |
192 | case BTREE: | 223 | case BTREE: |
193 | while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) | 224 | while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) |
@@ -205,10 +236,11 @@ int r; | |||
205 | { | 236 | { |
206 | r = t; | 237 | r = t; |
207 | if (r == Z_DATA_ERROR) | 238 | if (r == Z_DATA_ERROR) |
208 | s->mode = INF_ERROR; | 239 | s->mode = BAD; |
209 | LEAVE | 240 | LEAVE |
210 | } | 241 | } |
211 | s->sub.trees.index = 0; | 242 | s->sub.trees.index = 0; |
243 | Tracev((stderr, "inflate: bits tree ok\n")); | ||
212 | s->mode = DTREE; | 244 | s->mode = DTREE; |
213 | case DTREE: | 245 | case DTREE: |
214 | while (t = s->sub.trees.table, | 246 | while (t = s->sub.trees.table, |
@@ -240,7 +272,7 @@ int r; | |||
240 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || | 272 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || |
241 | (c == 16 && i < 1)) | 273 | (c == 16 && i < 1)) |
242 | { | 274 | { |
243 | s->mode = INF_ERROR; | 275 | s->mode = BAD; |
244 | z->msg = "invalid bit length repeat"; | 276 | z->msg = "invalid bit length repeat"; |
245 | r = Z_DATA_ERROR; | 277 | r = Z_DATA_ERROR; |
246 | LEAVE | 278 | LEAVE |
@@ -267,10 +299,11 @@ int r; | |||
267 | if (t != Z_OK) | 299 | if (t != Z_OK) |
268 | { | 300 | { |
269 | if (t == (uInt)Z_DATA_ERROR) | 301 | if (t == (uInt)Z_DATA_ERROR) |
270 | s->mode = INF_ERROR; | 302 | s->mode = BAD; |
271 | r = t; | 303 | r = t; |
272 | LEAVE | 304 | LEAVE |
273 | } | 305 | } |
306 | Tracev((stderr, "inflate: trees ok\n")); | ||
274 | if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) | 307 | if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) |
275 | { | 308 | { |
276 | inflate_trees_free(td, z); | 309 | inflate_trees_free(td, z); |
@@ -289,17 +322,20 @@ int r; | |||
289 | r = Z_OK; | 322 | r = Z_OK; |
290 | inflate_codes_free(s->sub.codes, z); | 323 | inflate_codes_free(s->sub.codes, z); |
291 | LOAD | 324 | LOAD |
325 | Tracev((stderr, "inflate: codes end, %lu total out\n", | ||
326 | z->total_out + (q >= s->read ? q - s->read : | ||
327 | (s->end - s->read) + (q - s->window)))); | ||
292 | if (!s->last) | 328 | if (!s->last) |
293 | { | 329 | { |
294 | s->mode = TYPE; | 330 | s->mode = TYPE; |
295 | break; | 331 | break; |
296 | } | 332 | } |
297 | if (k > 7) /* return unused byte, if any */ | 333 | if (k > 7) /* return unused byte, if any */ |
298 | { | 334 | { |
299 | Assert(k < 16, "inflate_codes grabbed too many bytes") | 335 | Assert(k < 16, "inflate_codes grabbed too many bytes") |
300 | k -= 8; | 336 | k -= 8; |
301 | n++; | 337 | n++; |
302 | p--; /* can always return one */ | 338 | p--; /* can always return one */ |
303 | } | 339 | } |
304 | s->mode = DRY; | 340 | s->mode = DRY; |
305 | case DRY: | 341 | case DRY: |
@@ -310,7 +346,7 @@ int r; | |||
310 | case DONE: | 346 | case DONE: |
311 | r = Z_STREAM_END; | 347 | r = Z_STREAM_END; |
312 | LEAVE | 348 | LEAVE |
313 | case INF_ERROR: | 349 | case BAD: |
314 | r = Z_DATA_ERROR; | 350 | r = Z_DATA_ERROR; |
315 | LEAVE | 351 | LEAVE |
316 | default: | 352 | default: |
@@ -325,13 +361,9 @@ struct inflate_blocks_state *s; | |||
325 | z_stream *z; | 361 | z_stream *z; |
326 | uLong *c; | 362 | uLong *c; |
327 | { | 363 | { |
328 | if (s->checkfn != Z_NULL) | 364 | inflate_blocks_reset(s, z, c); |
329 | *c = s->check; | ||
330 | if (s->mode == BTREE || s->mode == DTREE) | ||
331 | ZFREE(z, s->sub.trees.blens); | ||
332 | if (s->mode == CODES) | ||
333 | inflate_codes_free(s->sub.codes, z); | ||
334 | ZFREE(z, s->window); | 365 | ZFREE(z, s->window); |
335 | ZFREE(z, s); | 366 | ZFREE(z, s); |
367 | Trace((stderr, "inflate: blocks freed\n")); | ||
336 | return Z_OK; | 368 | return Z_OK; |
337 | } | 369 | } |