source: MondoRescue/branches/3.3/mindi-busybox/archival/libarchive/unxz/xz_dec_stream.c@ 3884

Last change on this file since 3884 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 19.4 KB
Line 
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 */
14struct xz_dec_hash {
15 vli_type unpadded;
16 vli_type uncompressed;
17 uint32_t crc32;
18};
19
20struct 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 */
141static 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 */
157static 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) */
175static 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 */
218static 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. */
281static 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 */
296static 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 */
346static 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 */
369static 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). */
386static 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) */
421static 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. */
448static 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
548static 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 */
733XZ_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
768XZ_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
790error_lzma2:
791#ifdef XZ_DEC_BCJ
792 xz_dec_bcj_end(s->bcj);
793error_bcj:
794#endif
795 kfree(s);
796 return NULL;
797}
798
799XZ_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
811XZ_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}
Note: See TracBrowser for help on using the repository browser.