1 | /*
|
---|
2 | * .xz Stream decoder
|
---|
3 | *
|
---|
4 | * Author: Lasse Collin <lasse.collin@tukaani.org>
|
---|
5 | *
|
---|
6 | * This file has been put into the public domain.
|
---|
7 | * You can do whatever you want with this file.
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include "xz_private.h"
|
---|
11 | #include "xz_stream.h"
|
---|
12 |
|
---|
13 | /* Hash used to validate the Index field */
|
---|
14 | struct xz_dec_hash {
|
---|
15 | vli_type unpadded;
|
---|
16 | vli_type uncompressed;
|
---|
17 | uint32_t crc32;
|
---|
18 | };
|
---|
19 |
|
---|
20 | struct xz_dec {
|
---|
21 | /* Position in dec_main() */
|
---|
22 | enum {
|
---|
23 | SEQ_STREAM_HEADER,
|
---|
24 | SEQ_BLOCK_START,
|
---|
25 | SEQ_BLOCK_HEADER,
|
---|
26 | SEQ_BLOCK_UNCOMPRESS,
|
---|
27 | SEQ_BLOCK_PADDING,
|
---|
28 | SEQ_BLOCK_CHECK,
|
---|
29 | SEQ_INDEX,
|
---|
30 | SEQ_INDEX_PADDING,
|
---|
31 | SEQ_INDEX_CRC32,
|
---|
32 | SEQ_STREAM_FOOTER
|
---|
33 | } sequence;
|
---|
34 |
|
---|
35 | /* Position in variable-length integers and Check fields */
|
---|
36 | uint32_t pos;
|
---|
37 |
|
---|
38 | /* Variable-length integer decoded by dec_vli() */
|
---|
39 | vli_type vli;
|
---|
40 |
|
---|
41 | /* Saved in_pos and out_pos */
|
---|
42 | size_t in_start;
|
---|
43 | size_t out_start;
|
---|
44 |
|
---|
45 | /* CRC32 value in Block or Index */
|
---|
46 | uint32_t crc32;
|
---|
47 |
|
---|
48 | /* Type of the integrity check calculated from uncompressed data */
|
---|
49 | enum xz_check check_type;
|
---|
50 |
|
---|
51 | /* Operation mode */
|
---|
52 | enum xz_mode mode;
|
---|
53 |
|
---|
54 | /*
|
---|
55 | * True if the next call to xz_dec_run() is allowed to return
|
---|
56 | * XZ_BUF_ERROR.
|
---|
57 | */
|
---|
58 | bool allow_buf_error;
|
---|
59 |
|
---|
60 | /* Information stored in Block Header */
|
---|
61 | struct {
|
---|
62 | /*
|
---|
63 | * Value stored in the Compressed Size field, or
|
---|
64 | * VLI_UNKNOWN if Compressed Size is not present.
|
---|
65 | */
|
---|
66 | vli_type compressed;
|
---|
67 |
|
---|
68 | /*
|
---|
69 | * Value stored in the Uncompressed Size field, or
|
---|
70 | * VLI_UNKNOWN if Uncompressed Size is not present.
|
---|
71 | */
|
---|
72 | vli_type uncompressed;
|
---|
73 |
|
---|
74 | /* Size of the Block Header field */
|
---|
75 | uint32_t size;
|
---|
76 | } block_header;
|
---|
77 |
|
---|
78 | /* Information collected when decoding Blocks */
|
---|
79 | struct {
|
---|
80 | /* Observed compressed size of the current Block */
|
---|
81 | vli_type compressed;
|
---|
82 |
|
---|
83 | /* Observed uncompressed size of the current Block */
|
---|
84 | vli_type uncompressed;
|
---|
85 |
|
---|
86 | /* Number of Blocks decoded so far */
|
---|
87 | vli_type count;
|
---|
88 |
|
---|
89 | /*
|
---|
90 | * Hash calculated from the Block sizes. This is used to
|
---|
91 | * validate the Index field.
|
---|
92 | */
|
---|
93 | struct xz_dec_hash hash;
|
---|
94 | } block;
|
---|
95 |
|
---|
96 | /* Variables needed when verifying the Index field */
|
---|
97 | struct {
|
---|
98 | /* Position in dec_index() */
|
---|
99 | enum {
|
---|
100 | SEQ_INDEX_COUNT,
|
---|
101 | SEQ_INDEX_UNPADDED,
|
---|
102 | SEQ_INDEX_UNCOMPRESSED
|
---|
103 | } sequence;
|
---|
104 |
|
---|
105 | /* Size of the Index in bytes */
|
---|
106 | vli_type size;
|
---|
107 |
|
---|
108 | /* Number of Records (matches block.count in valid files) */
|
---|
109 | vli_type count;
|
---|
110 |
|
---|
111 | /*
|
---|
112 | * Hash calculated from the Records (matches block.hash in
|
---|
113 | * valid files).
|
---|
114 | */
|
---|
115 | struct xz_dec_hash hash;
|
---|
116 | } index;
|
---|
117 |
|
---|
118 | /*
|
---|
119 | * Temporary buffer needed to hold Stream Header, Block Header,
|
---|
120 | * and Stream Footer. The Block Header is the biggest (1 KiB)
|
---|
121 | * so we reserve space according to that. buf[] has to be aligned
|
---|
122 | * to a multiple of four bytes; the size_t variables before it
|
---|
123 | * should guarantee this.
|
---|
124 | */
|
---|
125 | struct {
|
---|
126 | size_t pos;
|
---|
127 | size_t size;
|
---|
128 | uint8_t buf[1024];
|
---|
129 | } temp;
|
---|
130 |
|
---|
131 | struct xz_dec_lzma2 *lzma2;
|
---|
132 |
|
---|
133 | #ifdef XZ_DEC_BCJ
|
---|
134 | struct xz_dec_bcj *bcj;
|
---|
135 | bool bcj_active;
|
---|
136 | #endif
|
---|
137 | };
|
---|
138 |
|
---|
139 | #ifdef XZ_DEC_ANY_CHECK
|
---|
140 | /* Sizes of the Check field with different Check IDs */
|
---|
141 | static const uint8_t check_sizes[16] = {
|
---|
142 | 0,
|
---|
143 | 4, 4, 4,
|
---|
144 | 8, 8, 8,
|
---|
145 | 16, 16, 16,
|
---|
146 | 32, 32, 32,
|
---|
147 | 64, 64, 64
|
---|
148 | };
|
---|
149 | #endif
|
---|
150 |
|
---|
151 | /*
|
---|
152 | * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller
|
---|
153 | * must have set s->temp.pos to indicate how much data we are supposed
|
---|
154 | * to copy into s->temp.buf. Return true once s->temp.pos has reached
|
---|
155 | * s->temp.size.
|
---|
156 | */
|
---|
157 | static bool XZ_FUNC fill_temp(struct xz_dec *s, struct xz_buf *b)
|
---|
158 | {
|
---|
159 | size_t copy_size = min_t(size_t,
|
---|
160 | b->in_size - b->in_pos, s->temp.size - s->temp.pos);
|
---|
161 |
|
---|
162 | memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
|
---|
163 | b->in_pos += copy_size;
|
---|
164 | s->temp.pos += copy_size;
|
---|
165 |
|
---|
166 | if (s->temp.pos == s->temp.size) {
|
---|
167 | s->temp.pos = 0;
|
---|
168 | return true;
|
---|
169 | }
|
---|
170 |
|
---|
171 | return false;
|
---|
172 | }
|
---|
173 |
|
---|
174 | /* Decode a variable-length integer (little-endian base-128 encoding) */
|
---|
175 | static enum xz_ret XZ_FUNC dec_vli(struct xz_dec *s,
|
---|
176 | const uint8_t *in, size_t *in_pos, size_t in_size)
|
---|
177 | {
|
---|
178 | uint8_t byte;
|
---|
179 |
|
---|
180 | if (s->pos == 0)
|
---|
181 | s->vli = 0;
|
---|
182 |
|
---|
183 | while (*in_pos < in_size) {
|
---|
184 | byte = in[*in_pos];
|
---|
185 | ++*in_pos;
|
---|
186 |
|
---|
187 | s->vli |= (vli_type)(byte & 0x7F) << s->pos;
|
---|
188 |
|
---|
189 | if ((byte & 0x80) == 0) {
|
---|
190 | /* Don't allow non-minimal encodings. */
|
---|
191 | if (byte == 0 && s->pos != 0)
|
---|
192 | return XZ_DATA_ERROR;
|
---|
193 |
|
---|
194 | s->pos = 0;
|
---|
195 | return XZ_STREAM_END;
|
---|
196 | }
|
---|
197 |
|
---|
198 | s->pos += 7;
|
---|
199 | if (s->pos == 7 * VLI_BYTES_MAX)
|
---|
200 | return XZ_DATA_ERROR;
|
---|
201 | }
|
---|
202 |
|
---|
203 | return XZ_OK;
|
---|
204 | }
|
---|
205 |
|
---|
206 | /*
|
---|
207 | * Decode the Compressed Data field from a Block. Update and validate
|
---|
208 | * the observed compressed and uncompressed sizes of the Block so that
|
---|
209 | * they don't exceed the values possibly stored in the Block Header
|
---|
210 | * (validation assumes that no integer overflow occurs, since vli_type
|
---|
211 | * is normally uint64_t). Update the CRC32 if presence of the CRC32
|
---|
212 | * field was indicated in Stream Header.
|
---|
213 | *
|
---|
214 | * Once the decoding is finished, validate that the observed sizes match
|
---|
215 | * the sizes possibly stored in the Block Header. Update the hash and
|
---|
216 | * Block count, which are later used to validate the Index field.
|
---|
217 | */
|
---|
218 | static enum xz_ret XZ_FUNC dec_block(struct xz_dec *s, struct xz_buf *b)
|
---|
219 | {
|
---|
220 | enum xz_ret ret;
|
---|
221 |
|
---|
222 | s->in_start = b->in_pos;
|
---|
223 | s->out_start = b->out_pos;
|
---|
224 |
|
---|
225 | #ifdef XZ_DEC_BCJ
|
---|
226 | if (s->bcj_active)
|
---|
227 | ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
|
---|
228 | else
|
---|
229 | #endif
|
---|
230 | ret = xz_dec_lzma2_run(s->lzma2, b);
|
---|
231 |
|
---|
232 | s->block.compressed += b->in_pos - s->in_start;
|
---|
233 | s->block.uncompressed += b->out_pos - s->out_start;
|
---|
234 |
|
---|
235 | /*
|
---|
236 | * There is no need to separately check for VLI_UNKNOWN, since
|
---|
237 | * the observed sizes are always smaller than VLI_UNKNOWN.
|
---|
238 | */
|
---|
239 | if (s->block.compressed > s->block_header.compressed
|
---|
240 | || s->block.uncompressed
|
---|
241 | > s->block_header.uncompressed)
|
---|
242 | return XZ_DATA_ERROR;
|
---|
243 |
|
---|
244 | if (s->check_type == XZ_CHECK_CRC32)
|
---|
245 | s->crc32 = xz_crc32(b->out + s->out_start,
|
---|
246 | b->out_pos - s->out_start, s->crc32);
|
---|
247 |
|
---|
248 | if (ret == XZ_STREAM_END) {
|
---|
249 | if (s->block_header.compressed != VLI_UNKNOWN
|
---|
250 | && s->block_header.compressed
|
---|
251 | != s->block.compressed)
|
---|
252 | return XZ_DATA_ERROR;
|
---|
253 |
|
---|
254 | if (s->block_header.uncompressed != VLI_UNKNOWN
|
---|
255 | && s->block_header.uncompressed
|
---|
256 | != s->block.uncompressed)
|
---|
257 | return XZ_DATA_ERROR;
|
---|
258 |
|
---|
259 | s->block.hash.unpadded += s->block_header.size
|
---|
260 | + s->block.compressed;
|
---|
261 |
|
---|
262 | #ifdef XZ_DEC_ANY_CHECK
|
---|
263 | s->block.hash.unpadded += check_sizes[s->check_type];
|
---|
264 | #else
|
---|
265 | if (s->check_type == XZ_CHECK_CRC32)
|
---|
266 | s->block.hash.unpadded += 4;
|
---|
267 | #endif
|
---|
268 |
|
---|
269 | s->block.hash.uncompressed += s->block.uncompressed;
|
---|
270 | s->block.hash.crc32 = xz_crc32(
|
---|
271 | (const uint8_t *)&s->block.hash,
|
---|
272 | sizeof(s->block.hash), s->block.hash.crc32);
|
---|
273 |
|
---|
274 | ++s->block.count;
|
---|
275 | }
|
---|
276 |
|
---|
277 | return ret;
|
---|
278 | }
|
---|
279 |
|
---|
280 | /* Update the Index size and the CRC32 value. */
|
---|
281 | static void XZ_FUNC index_update(struct xz_dec *s, const struct xz_buf *b)
|
---|
282 | {
|
---|
283 | size_t in_used = b->in_pos - s->in_start;
|
---|
284 | s->index.size += in_used;
|
---|
285 | s->crc32 = xz_crc32(b->in + s->in_start, in_used, s->crc32);
|
---|
286 | }
|
---|
287 |
|
---|
288 | /*
|
---|
289 | * Decode the Number of Records, Unpadded Size, and Uncompressed Size
|
---|
290 | * fields from the Index field. That is, Index Padding and CRC32 are not
|
---|
291 | * decoded by this function.
|
---|
292 | *
|
---|
293 | * This can return XZ_OK (more input needed), XZ_STREAM_END (everything
|
---|
294 | * successfully decoded), or XZ_DATA_ERROR (input is corrupt).
|
---|
295 | */
|
---|
296 | static enum xz_ret XZ_FUNC dec_index(struct xz_dec *s, struct xz_buf *b)
|
---|
297 | {
|
---|
298 | enum xz_ret ret;
|
---|
299 |
|
---|
300 | do {
|
---|
301 | ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
|
---|
302 | if (ret != XZ_STREAM_END) {
|
---|
303 | index_update(s, b);
|
---|
304 | return ret;
|
---|
305 | }
|
---|
306 |
|
---|
307 | switch (s->index.sequence) {
|
---|
308 | case SEQ_INDEX_COUNT:
|
---|
309 | s->index.count = s->vli;
|
---|
310 |
|
---|
311 | /*
|
---|
312 | * Validate that the Number of Records field
|
---|
313 | * indicates the same number of Records as
|
---|
314 | * there were Blocks in the Stream.
|
---|
315 | */
|
---|
316 | if (s->index.count != s->block.count)
|
---|
317 | return XZ_DATA_ERROR;
|
---|
318 |
|
---|
319 | s->index.sequence = SEQ_INDEX_UNPADDED;
|
---|
320 | break;
|
---|
321 |
|
---|
322 | case SEQ_INDEX_UNPADDED:
|
---|
323 | s->index.hash.unpadded += s->vli;
|
---|
324 | s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
|
---|
325 | break;
|
---|
326 |
|
---|
327 | case SEQ_INDEX_UNCOMPRESSED:
|
---|
328 | s->index.hash.uncompressed += s->vli;
|
---|
329 | s->index.hash.crc32 = xz_crc32(
|
---|
330 | (const uint8_t *)&s->index.hash,
|
---|
331 | sizeof(s->index.hash),
|
---|
332 | s->index.hash.crc32);
|
---|
333 | --s->index.count;
|
---|
334 | s->index.sequence = SEQ_INDEX_UNPADDED;
|
---|
335 | break;
|
---|
336 | }
|
---|
337 | } while (s->index.count > 0);
|
---|
338 |
|
---|
339 | return XZ_STREAM_END;
|
---|
340 | }
|
---|
341 |
|
---|
342 | /*
|
---|
343 | * Validate that the next four input bytes match the value of s->crc32.
|
---|
344 | * s->pos must be zero when starting to validate the first byte.
|
---|
345 | */
|
---|
346 | static enum xz_ret XZ_FUNC crc32_validate(struct xz_dec *s, struct xz_buf *b)
|
---|
347 | {
|
---|
348 | do {
|
---|
349 | if (b->in_pos == b->in_size)
|
---|
350 | return XZ_OK;
|
---|
351 |
|
---|
352 | if (((s->crc32 >> s->pos) & 0xFF) != b->in[b->in_pos++])
|
---|
353 | return XZ_DATA_ERROR;
|
---|
354 |
|
---|
355 | s->pos += 8;
|
---|
356 | } while (s->pos < 32);
|
---|
357 |
|
---|
358 | s->crc32 = 0;
|
---|
359 | s->pos = 0;
|
---|
360 |
|
---|
361 | return XZ_STREAM_END;
|
---|
362 | }
|
---|
363 |
|
---|
364 | #ifdef XZ_DEC_ANY_CHECK
|
---|
365 | /*
|
---|
366 | * Skip over the Check field when the Check ID is not supported.
|
---|
367 | * Returns true once the whole Check field has been skipped over.
|
---|
368 | */
|
---|
369 | static bool XZ_FUNC check_skip(struct xz_dec *s, struct xz_buf *b)
|
---|
370 | {
|
---|
371 | while (s->pos < check_sizes[s->check_type]) {
|
---|
372 | if (b->in_pos == b->in_size)
|
---|
373 | return false;
|
---|
374 |
|
---|
375 | ++b->in_pos;
|
---|
376 | ++s->pos;
|
---|
377 | }
|
---|
378 |
|
---|
379 | s->pos = 0;
|
---|
380 |
|
---|
381 | return true;
|
---|
382 | }
|
---|
383 | #endif
|
---|
384 |
|
---|
385 | /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
|
---|
386 | static enum xz_ret XZ_FUNC dec_stream_header(struct xz_dec *s)
|
---|
387 | {
|
---|
388 | if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
|
---|
389 | return XZ_FORMAT_ERROR;
|
---|
390 |
|
---|
391 | if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
|
---|
392 | != get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
|
---|
393 | return XZ_DATA_ERROR;
|
---|
394 |
|
---|
395 | if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
|
---|
396 | return XZ_OPTIONS_ERROR;
|
---|
397 |
|
---|
398 | /*
|
---|
399 | * Of integrity checks, we support only none (Check ID = 0) and
|
---|
400 | * CRC32 (Check ID = 1). However, if XZ_DEC_ANY_CHECK is defined,
|
---|
401 | * we will accept other check types too, but then the check won't
|
---|
402 | * be verified and a warning (XZ_UNSUPPORTED_CHECK) will be given.
|
---|
403 | */
|
---|
404 | s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
|
---|
405 |
|
---|
406 | #ifdef XZ_DEC_ANY_CHECK
|
---|
407 | if (s->check_type > XZ_CHECK_MAX)
|
---|
408 | return XZ_OPTIONS_ERROR;
|
---|
409 |
|
---|
410 | if (s->check_type > XZ_CHECK_CRC32)
|
---|
411 | return XZ_UNSUPPORTED_CHECK;
|
---|
412 | #else
|
---|
413 | if (s->check_type > XZ_CHECK_CRC32)
|
---|
414 | return XZ_OPTIONS_ERROR;
|
---|
415 | #endif
|
---|
416 |
|
---|
417 | return XZ_OK;
|
---|
418 | }
|
---|
419 |
|
---|
420 | /* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
|
---|
421 | static enum xz_ret XZ_FUNC dec_stream_footer(struct xz_dec *s)
|
---|
422 | {
|
---|
423 | if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
|
---|
424 | return XZ_DATA_ERROR;
|
---|
425 |
|
---|
426 | if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
|
---|
427 | return XZ_DATA_ERROR;
|
---|
428 |
|
---|
429 | /*
|
---|
430 | * Validate Backward Size. Note that we never added the size of the
|
---|
431 | * Index CRC32 field to s->index.size, thus we use s->index.size / 4
|
---|
432 | * instead of s->index.size / 4 - 1.
|
---|
433 | */
|
---|
434 | if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
|
---|
435 | return XZ_DATA_ERROR;
|
---|
436 |
|
---|
437 | if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
|
---|
438 | return XZ_DATA_ERROR;
|
---|
439 |
|
---|
440 | /*
|
---|
441 | * Use XZ_STREAM_END instead of XZ_OK to be more convenient
|
---|
442 | * for the caller.
|
---|
443 | */
|
---|
444 | return XZ_STREAM_END;
|
---|
445 | }
|
---|
446 |
|
---|
447 | /* Decode the Block Header and initialize the filter chain. */
|
---|
448 | static enum xz_ret XZ_FUNC dec_block_header(struct xz_dec *s)
|
---|
449 | {
|
---|
450 | enum xz_ret ret;
|
---|
451 |
|
---|
452 | /*
|
---|
453 | * Validate the CRC32. We know that the temp buffer is at least
|
---|
454 | * eight bytes so this is safe.
|
---|
455 | */
|
---|
456 | s->temp.size -= 4;
|
---|
457 | if (xz_crc32(s->temp.buf, s->temp.size, 0)
|
---|
458 | != get_le32(s->temp.buf + s->temp.size))
|
---|
459 | return XZ_DATA_ERROR;
|
---|
460 |
|
---|
461 | s->temp.pos = 2;
|
---|
462 |
|
---|
463 | /*
|
---|
464 | * Catch unsupported Block Flags. We support only one or two filters
|
---|
465 | * in the chain, so we catch that with the same test.
|
---|
466 | */
|
---|
467 | #ifdef XZ_DEC_BCJ
|
---|
468 | if (s->temp.buf[1] & 0x3E)
|
---|
469 | #else
|
---|
470 | if (s->temp.buf[1] & 0x3F)
|
---|
471 | #endif
|
---|
472 | return XZ_OPTIONS_ERROR;
|
---|
473 |
|
---|
474 | /* Compressed Size */
|
---|
475 | if (s->temp.buf[1] & 0x40) {
|
---|
476 | if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
|
---|
477 | != XZ_STREAM_END)
|
---|
478 | return XZ_DATA_ERROR;
|
---|
479 |
|
---|
480 | s->block_header.compressed = s->vli;
|
---|
481 | } else {
|
---|
482 | s->block_header.compressed = VLI_UNKNOWN;
|
---|
483 | }
|
---|
484 |
|
---|
485 | /* Uncompressed Size */
|
---|
486 | if (s->temp.buf[1] & 0x80) {
|
---|
487 | if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
|
---|
488 | != XZ_STREAM_END)
|
---|
489 | return XZ_DATA_ERROR;
|
---|
490 |
|
---|
491 | s->block_header.uncompressed = s->vli;
|
---|
492 | } else {
|
---|
493 | s->block_header.uncompressed = VLI_UNKNOWN;
|
---|
494 | }
|
---|
495 |
|
---|
496 | #ifdef XZ_DEC_BCJ
|
---|
497 | /* If there are two filters, the first one must be a BCJ filter. */
|
---|
498 | s->bcj_active = s->temp.buf[1] & 0x01;
|
---|
499 | if (s->bcj_active) {
|
---|
500 | if (s->temp.size - s->temp.pos < 2)
|
---|
501 | return XZ_OPTIONS_ERROR;
|
---|
502 |
|
---|
503 | ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
|
---|
504 | if (ret != XZ_OK)
|
---|
505 | return ret;
|
---|
506 |
|
---|
507 | /*
|
---|
508 | * We don't support custom start offset,
|
---|
509 | * so Size of Properties must be zero.
|
---|
510 | */
|
---|
511 | if (s->temp.buf[s->temp.pos++] != 0x00)
|
---|
512 | return XZ_OPTIONS_ERROR;
|
---|
513 | }
|
---|
514 | #endif
|
---|
515 |
|
---|
516 | /* Valid Filter Flags always take at least two bytes. */
|
---|
517 | if (s->temp.size - s->temp.pos < 2)
|
---|
518 | return XZ_DATA_ERROR;
|
---|
519 |
|
---|
520 | /* Filter ID = LZMA2 */
|
---|
521 | if (s->temp.buf[s->temp.pos++] != 0x21)
|
---|
522 | return XZ_OPTIONS_ERROR;
|
---|
523 |
|
---|
524 | /* Size of Properties = 1-byte Filter Properties */
|
---|
525 | if (s->temp.buf[s->temp.pos++] != 0x01)
|
---|
526 | return XZ_OPTIONS_ERROR;
|
---|
527 |
|
---|
528 | /* Filter Properties contains LZMA2 dictionary size. */
|
---|
529 | if (s->temp.size - s->temp.pos < 1)
|
---|
530 | return XZ_DATA_ERROR;
|
---|
531 |
|
---|
532 | ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
|
---|
533 | if (ret != XZ_OK)
|
---|
534 | return ret;
|
---|
535 |
|
---|
536 | /* The rest must be Header Padding. */
|
---|
537 | while (s->temp.pos < s->temp.size)
|
---|
538 | if (s->temp.buf[s->temp.pos++] != 0x00)
|
---|
539 | return XZ_OPTIONS_ERROR;
|
---|
540 |
|
---|
541 | s->temp.pos = 0;
|
---|
542 | s->block.compressed = 0;
|
---|
543 | s->block.uncompressed = 0;
|
---|
544 |
|
---|
545 | return XZ_OK;
|
---|
546 | }
|
---|
547 |
|
---|
548 | static enum xz_ret XZ_FUNC dec_main(struct xz_dec *s, struct xz_buf *b)
|
---|
549 | {
|
---|
550 | enum xz_ret ret;
|
---|
551 |
|
---|
552 | /*
|
---|
553 | * Store the start position for the case when we are in the middle
|
---|
554 | * of the Index field.
|
---|
555 | */
|
---|
556 | s->in_start = b->in_pos;
|
---|
557 |
|
---|
558 | while (true) {
|
---|
559 | switch (s->sequence) {
|
---|
560 | case SEQ_STREAM_HEADER:
|
---|
561 | /*
|
---|
562 | * Stream Header is copied to s->temp, and then
|
---|
563 | * decoded from there. This way if the caller
|
---|
564 | * gives us only little input at a time, we can
|
---|
565 | * still keep the Stream Header decoding code
|
---|
566 | * simple. Similar approach is used in many places
|
---|
567 | * in this file.
|
---|
568 | */
|
---|
569 | if (!fill_temp(s, b))
|
---|
570 | return XZ_OK;
|
---|
571 |
|
---|
572 | /*
|
---|
573 | * If dec_stream_header() returns
|
---|
574 | * XZ_UNSUPPORTED_CHECK, it is still possible
|
---|
575 | * to continue decoding if working in multi-call
|
---|
576 | * mode. Thus, update s->sequence before calling
|
---|
577 | * dec_stream_header().
|
---|
578 | */
|
---|
579 | s->sequence = SEQ_BLOCK_START;
|
---|
580 |
|
---|
581 | ret = dec_stream_header(s);
|
---|
582 | if (ret != XZ_OK)
|
---|
583 | return ret;
|
---|
584 |
|
---|
585 | case SEQ_BLOCK_START:
|
---|
586 | /* We need one byte of input to continue. */
|
---|
587 | if (b->in_pos == b->in_size)
|
---|
588 | return XZ_OK;
|
---|
589 |
|
---|
590 | /* See if this is the beginning of the Index field. */
|
---|
591 | if (b->in[b->in_pos] == 0) {
|
---|
592 | s->in_start = b->in_pos++;
|
---|
593 | s->sequence = SEQ_INDEX;
|
---|
594 | break;
|
---|
595 | }
|
---|
596 |
|
---|
597 | /*
|
---|
598 | * Calculate the size of the Block Header and
|
---|
599 | * prepare to decode it.
|
---|
600 | */
|
---|
601 | s->block_header.size
|
---|
602 | = ((uint32_t)b->in[b->in_pos] + 1) * 4;
|
---|
603 |
|
---|
604 | s->temp.size = s->block_header.size;
|
---|
605 | s->temp.pos = 0;
|
---|
606 | s->sequence = SEQ_BLOCK_HEADER;
|
---|
607 |
|
---|
608 | case SEQ_BLOCK_HEADER:
|
---|
609 | if (!fill_temp(s, b))
|
---|
610 | return XZ_OK;
|
---|
611 |
|
---|
612 | ret = dec_block_header(s);
|
---|
613 | if (ret != XZ_OK)
|
---|
614 | return ret;
|
---|
615 |
|
---|
616 | s->sequence = SEQ_BLOCK_UNCOMPRESS;
|
---|
617 |
|
---|
618 | case SEQ_BLOCK_UNCOMPRESS:
|
---|
619 | ret = dec_block(s, b);
|
---|
620 | if (ret != XZ_STREAM_END)
|
---|
621 | return ret;
|
---|
622 |
|
---|
623 | s->sequence = SEQ_BLOCK_PADDING;
|
---|
624 |
|
---|
625 | case SEQ_BLOCK_PADDING:
|
---|
626 | /*
|
---|
627 | * Size of Compressed Data + Block Padding
|
---|
628 | * must be a multiple of four. We don't need
|
---|
629 | * s->block.compressed for anything else
|
---|
630 | * anymore, so we use it here to test the size
|
---|
631 | * of the Block Padding field.
|
---|
632 | */
|
---|
633 | while (s->block.compressed & 3) {
|
---|
634 | if (b->in_pos == b->in_size)
|
---|
635 | return XZ_OK;
|
---|
636 |
|
---|
637 | if (b->in[b->in_pos++] != 0)
|
---|
638 | return XZ_DATA_ERROR;
|
---|
639 |
|
---|
640 | ++s->block.compressed;
|
---|
641 | }
|
---|
642 |
|
---|
643 | s->sequence = SEQ_BLOCK_CHECK;
|
---|
644 |
|
---|
645 | case SEQ_BLOCK_CHECK:
|
---|
646 | if (s->check_type == XZ_CHECK_CRC32) {
|
---|
647 | ret = crc32_validate(s, b);
|
---|
648 | if (ret != XZ_STREAM_END)
|
---|
649 | return ret;
|
---|
650 | }
|
---|
651 | #ifdef XZ_DEC_ANY_CHECK
|
---|
652 | else if (!check_skip(s, b)) {
|
---|
653 | return XZ_OK;
|
---|
654 | }
|
---|
655 | #endif
|
---|
656 |
|
---|
657 | s->sequence = SEQ_BLOCK_START;
|
---|
658 | break;
|
---|
659 |
|
---|
660 | case SEQ_INDEX:
|
---|
661 | ret = dec_index(s, b);
|
---|
662 | if (ret != XZ_STREAM_END)
|
---|
663 | return ret;
|
---|
664 |
|
---|
665 | s->sequence = SEQ_INDEX_PADDING;
|
---|
666 |
|
---|
667 | case SEQ_INDEX_PADDING:
|
---|
668 | while ((s->index.size + (b->in_pos - s->in_start))
|
---|
669 | & 3) {
|
---|
670 | if (b->in_pos == b->in_size) {
|
---|
671 | index_update(s, b);
|
---|
672 | return XZ_OK;
|
---|
673 | }
|
---|
674 |
|
---|
675 | if (b->in[b->in_pos++] != 0)
|
---|
676 | return XZ_DATA_ERROR;
|
---|
677 | }
|
---|
678 |
|
---|
679 | /* Finish the CRC32 value and Index size. */
|
---|
680 | index_update(s, b);
|
---|
681 |
|
---|
682 | /* Compare the hashes to validate the Index field. */
|
---|
683 | if (!memeq(&s->block.hash, &s->index.hash,
|
---|
684 | sizeof(s->block.hash)))
|
---|
685 | return XZ_DATA_ERROR;
|
---|
686 |
|
---|
687 | s->sequence = SEQ_INDEX_CRC32;
|
---|
688 |
|
---|
689 | case SEQ_INDEX_CRC32:
|
---|
690 | ret = crc32_validate(s, b);
|
---|
691 | if (ret != XZ_STREAM_END)
|
---|
692 | return ret;
|
---|
693 |
|
---|
694 | s->temp.size = STREAM_HEADER_SIZE;
|
---|
695 | s->sequence = SEQ_STREAM_FOOTER;
|
---|
696 |
|
---|
697 | case SEQ_STREAM_FOOTER:
|
---|
698 | if (!fill_temp(s, b))
|
---|
699 | return XZ_OK;
|
---|
700 |
|
---|
701 | return dec_stream_footer(s);
|
---|
702 | }
|
---|
703 | }
|
---|
704 |
|
---|
705 | /* Never reached */
|
---|
706 | }
|
---|
707 |
|
---|
708 | /*
|
---|
709 | * xz_dec_run() is a wrapper for dec_main() to handle some special cases in
|
---|
710 | * multi-call and single-call decoding.
|
---|
711 | *
|
---|
712 | * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we
|
---|
713 | * are not going to make any progress anymore. This is to prevent the caller
|
---|
714 | * from calling us infinitely when the input file is truncated or otherwise
|
---|
715 | * corrupt. Since zlib-style API allows that the caller fills the input buffer
|
---|
716 | * only when the decoder doesn't produce any new output, we have to be careful
|
---|
717 | * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only
|
---|
718 | * after the second consecutive call to xz_dec_run() that makes no progress.
|
---|
719 | *
|
---|
720 | * In single-call mode, if we couldn't decode everything and no error
|
---|
721 | * occurred, either the input is truncated or the output buffer is too small.
|
---|
722 | * Since we know that the last input byte never produces any output, we know
|
---|
723 | * that if all the input was consumed and decoding wasn't finished, the file
|
---|
724 | * must be corrupt. Otherwise the output buffer has to be too small or the
|
---|
725 | * file is corrupt in a way that decoding it produces too big output.
|
---|
726 | *
|
---|
727 | * If single-call decoding fails, we reset b->in_pos and b->out_pos back to
|
---|
728 | * their original values. This is because with some filter chains there won't
|
---|
729 | * be any valid uncompressed data in the output buffer unless the decoding
|
---|
730 | * actually succeeds (that's the price to pay of using the output buffer as
|
---|
731 | * the workspace).
|
---|
732 | */
|
---|
733 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b)
|
---|
734 | {
|
---|
735 | size_t in_start;
|
---|
736 | size_t out_start;
|
---|
737 | enum xz_ret ret;
|
---|
738 |
|
---|
739 | if (DEC_IS_SINGLE(s->mode))
|
---|
740 | xz_dec_reset(s);
|
---|
741 |
|
---|
742 | in_start = b->in_pos;
|
---|
743 | out_start = b->out_pos;
|
---|
744 | ret = dec_main(s, b);
|
---|
745 |
|
---|
746 | if (DEC_IS_SINGLE(s->mode)) {
|
---|
747 | if (ret == XZ_OK)
|
---|
748 | ret = b->in_pos == b->in_size
|
---|
749 | ? XZ_DATA_ERROR : XZ_BUF_ERROR;
|
---|
750 |
|
---|
751 | if (ret != XZ_STREAM_END) {
|
---|
752 | b->in_pos = in_start;
|
---|
753 | b->out_pos = out_start;
|
---|
754 | }
|
---|
755 | } else if (ret == XZ_OK && in_start == b->in_pos
|
---|
756 | && out_start == b->out_pos) {
|
---|
757 | if (s->allow_buf_error)
|
---|
758 | ret = XZ_BUF_ERROR;
|
---|
759 |
|
---|
760 | s->allow_buf_error = true;
|
---|
761 | } else {
|
---|
762 | s->allow_buf_error = false;
|
---|
763 | }
|
---|
764 |
|
---|
765 | return ret;
|
---|
766 | }
|
---|
767 |
|
---|
768 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(
|
---|
769 | enum xz_mode mode, uint32_t dict_max)
|
---|
770 | {
|
---|
771 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
---|
772 | if (s == NULL)
|
---|
773 | return NULL;
|
---|
774 |
|
---|
775 | s->mode = mode;
|
---|
776 |
|
---|
777 | #ifdef XZ_DEC_BCJ
|
---|
778 | s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode));
|
---|
779 | if (s->bcj == NULL)
|
---|
780 | goto error_bcj;
|
---|
781 | #endif
|
---|
782 |
|
---|
783 | s->lzma2 = xz_dec_lzma2_create(mode, dict_max);
|
---|
784 | if (s->lzma2 == NULL)
|
---|
785 | goto error_lzma2;
|
---|
786 |
|
---|
787 | xz_dec_reset(s);
|
---|
788 | return s;
|
---|
789 |
|
---|
790 | error_lzma2:
|
---|
791 | #ifdef XZ_DEC_BCJ
|
---|
792 | xz_dec_bcj_end(s->bcj);
|
---|
793 | error_bcj:
|
---|
794 | #endif
|
---|
795 | kfree(s);
|
---|
796 | return NULL;
|
---|
797 | }
|
---|
798 |
|
---|
799 | XZ_EXTERN void XZ_FUNC xz_dec_reset(struct xz_dec *s)
|
---|
800 | {
|
---|
801 | s->sequence = SEQ_STREAM_HEADER;
|
---|
802 | s->allow_buf_error = false;
|
---|
803 | s->pos = 0;
|
---|
804 | s->crc32 = 0;
|
---|
805 | memzero(&s->block, sizeof(s->block));
|
---|
806 | memzero(&s->index, sizeof(s->index));
|
---|
807 | s->temp.pos = 0;
|
---|
808 | s->temp.size = STREAM_HEADER_SIZE;
|
---|
809 | }
|
---|
810 |
|
---|
811 | XZ_EXTERN void XZ_FUNC xz_dec_end(struct xz_dec *s)
|
---|
812 | {
|
---|
813 | if (s != NULL) {
|
---|
814 | xz_dec_lzma2_end(s->lzma2);
|
---|
815 | #ifdef XZ_DEC_BCJ
|
---|
816 | xz_dec_bcj_end(s->bcj);
|
---|
817 | #endif
|
---|
818 | kfree(s);
|
---|
819 | }
|
---|
820 | }
|
---|