source: MondoRescue/branches/3.3/mindi-busybox/archival/libarchive/decompress_unxz.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: 3.8 KB
RevLine 
[2725]1/*
2 * This file uses XZ Embedded library code which is written
3 * by Lasse Collin <lasse.collin@tukaani.org>
4 * and Igor Pavlov <http://7-zip.org/>
5 *
6 * See README file in unxz/ directory for more information.
7 *
8 * This file is:
9 * Copyright (C) 2010 Denys Vlasenko <vda.linux@googlemail.com>
10 * Licensed under GPLv2, see file LICENSE in this source tree.
11 */
12#include "libbb.h"
[3232]13#include "bb_archive.h"
[2725]14
15#define XZ_FUNC FAST_FUNC
16#define XZ_EXTERN static
17
18#define XZ_DEC_DYNALLOC
19
20/* Skip check (rather than fail) of unsupported hash functions */
21#define XZ_DEC_ANY_CHECK 1
22
23/* We use our own crc32 function */
24#define XZ_INTERNAL_CRC32 0
25static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
26{
27 return ~crc32_block_endian0(~crc, buf, size, global_crc32_table);
28}
29
30/* We use arch-optimized unaligned accessors */
31#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
32#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
[3232]33#define put_unaligned_le32(val, buf) move_to_unaligned32(buf, SWAP_LE32(val))
34#define put_unaligned_be32(val, buf) move_to_unaligned32(buf, SWAP_BE32(val))
[2725]35
36#include "unxz/xz_dec_bcj.c"
37#include "unxz/xz_dec_lzma2.c"
38#include "unxz/xz_dec_stream.c"
39
40IF_DESKTOP(long long) int FAST_FUNC
[3621]41unpack_xz_stream(transformer_state_t *xstate)
[2725]42{
[3232]43 enum xz_ret xz_result;
[2725]44 struct xz_buf iobuf;
45 struct xz_dec *state;
46 unsigned char *membuf;
47 IF_DESKTOP(long long) int total = 0;
48
49 if (!global_crc32_table)
50 global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0);
51
52 memset(&iobuf, 0, sizeof(iobuf));
[3232]53 membuf = xmalloc(2 * BUFSIZ);
[2725]54 iobuf.in = membuf;
55 iobuf.out = membuf + BUFSIZ;
56 iobuf.out_size = BUFSIZ;
57
[3621]58 if (!xstate || xstate->signature_skipped) {
[3232]59 /* Preload XZ file signature */
60 strcpy((char*)membuf, HEADER_MAGIC);
61 iobuf.in_size = HEADER_MAGIC_SIZE;
62 } /* else: let xz code read & check it */
63
[2725]64 /* Limit memory usage to about 64 MiB. */
65 state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
66
[3232]67 xz_result = X_OK;
[2725]68 while (1) {
69 if (iobuf.in_pos == iobuf.in_size) {
[3621]70 int rd = safe_read(xstate->src_fd, membuf, BUFSIZ);
[2725]71 if (rd < 0) {
72 bb_error_msg(bb_msg_read_error);
73 total = -1;
74 break;
75 }
[3232]76 if (rd == 0 && xz_result == XZ_STREAM_END)
77 break;
[2725]78 iobuf.in_size = rd;
79 iobuf.in_pos = 0;
80 }
[3232]81 if (xz_result == XZ_STREAM_END) {
82 /*
83 * Try to start decoding next concatenated stream.
84 * Stream padding must always be a multiple of four
85 * bytes to preserve four-byte alignment. To keep the
86 * code slightly smaller, we aren't as strict here as
87 * the .xz spec requires. We just skip all zero-bytes
88 * without checking the alignment and thus can accept
89 * files that aren't valid, e.g. the XZ utils test
90 * files bad-0pad-empty.xz and bad-0catpad-empty.xz.
91 */
92 do {
93 if (membuf[iobuf.in_pos] != 0) {
94 xz_dec_reset(state);
95 goto do_run;
96 }
97 iobuf.in_pos++;
98 } while (iobuf.in_pos < iobuf.in_size);
99 }
100 do_run:
[2725]101// bb_error_msg(">in pos:%d size:%d out pos:%d size:%d",
102// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size);
[3232]103 xz_result = xz_dec_run(state, &iobuf);
[2725]104// bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d",
[3232]105// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result);
[2725]106 if (iobuf.out_pos) {
[3621]107 xtransformer_write(xstate, iobuf.out, iobuf.out_pos);
[2725]108 IF_DESKTOP(total += iobuf.out_pos;)
109 iobuf.out_pos = 0;
110 }
[3232]111 if (xz_result == XZ_STREAM_END) {
112 /*
113 * Can just "break;" here, if not for concatenated
114 * .xz streams.
115 * Checking for padding may require buffer
116 * replenishment. Can't do it here.
117 */
118 continue;
[2725]119 }
[3232]120 if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
[2725]121 bb_error_msg("corrupted data");
122 total = -1;
123 break;
124 }
125 }
[3232]126
[2725]127 xz_dec_end(state);
128 free(membuf);
129
130 return total;
131}
Note: See TracBrowser for help on using the repository browser.