1*cf5a6c84SAndroid Build Coastguard Worker /* xzcat.c - Simple XZ decoder command line tool
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Author: Lasse Collin <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * This file has been put into the public domain.
6*cf5a6c84SAndroid Build Coastguard Worker * You can do whatever you want with this file.
7*cf5a6c84SAndroid Build Coastguard Worker * Modified for toybox by Isaac Dunham
8*cf5a6c84SAndroid Build Coastguard Worker *
9*cf5a6c84SAndroid Build Coastguard Worker * See http://tukaani.org/xz/xz-file-format.txt
10*cf5a6c84SAndroid Build Coastguard Worker USE_XZCAT(NEWTOY(xzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
11*cf5a6c84SAndroid Build Coastguard Worker
12*cf5a6c84SAndroid Build Coastguard Worker config XZCAT
13*cf5a6c84SAndroid Build Coastguard Worker bool "xzcat"
14*cf5a6c84SAndroid Build Coastguard Worker default n
15*cf5a6c84SAndroid Build Coastguard Worker help
16*cf5a6c84SAndroid Build Coastguard Worker usage: xzcat [FILE...]
17*cf5a6c84SAndroid Build Coastguard Worker
18*cf5a6c84SAndroid Build Coastguard Worker Decompress listed files to stdout. Use stdin if no files listed.
19*cf5a6c84SAndroid Build Coastguard Worker
20*cf5a6c84SAndroid Build Coastguard Worker */
21*cf5a6c84SAndroid Build Coastguard Worker #define FOR_xzcat
22*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
23*cf5a6c84SAndroid Build Coastguard Worker
24*cf5a6c84SAndroid Build Coastguard Worker // BEGIN xz.h
25*cf5a6c84SAndroid Build Coastguard Worker
26*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret {
27*cf5a6c84SAndroid Build Coastguard Worker // Doing fine, More input or output space needed
28*cf5a6c84SAndroid Build Coastguard Worker XZ_OK,
29*cf5a6c84SAndroid Build Coastguard Worker // EOF, Everything went fine
30*cf5a6c84SAndroid Build Coastguard Worker XZ_STREAM_END,
31*cf5a6c84SAndroid Build Coastguard Worker // Integrity check type is not supported. Decoding is still possible in
32*cf5a6c84SAndroid Build Coastguard Worker // multi-call mode by simply calling xz_dec_run() again. Note that this
33*cf5a6c84SAndroid Build Coastguard Worker // return value is used only if XZ_DEC_ANY_CHECK was defined at build
34*cf5a6c84SAndroid Build Coastguard Worker // time, which is not used in the kernel. Unsupported check types return
35*cf5a6c84SAndroid Build Coastguard Worker // XZ_OPTIONS_ERROR if XZ_DEC_ANY_CHECK was not defined at build time.
36*cf5a6c84SAndroid Build Coastguard Worker XZ_UNSUPPORTED_CHECK,
37*cf5a6c84SAndroid Build Coastguard Worker // Cant allocate memory
38*cf5a6c84SAndroid Build Coastguard Worker XZ_MEM_ERROR,
39*cf5a6c84SAndroid Build Coastguard Worker // OOM
40*cf5a6c84SAndroid Build Coastguard Worker XZ_MEMLIMIT_ERROR,
41*cf5a6c84SAndroid Build Coastguard Worker // Not a xz file
42*cf5a6c84SAndroid Build Coastguard Worker XZ_FORMAT_ERROR,
43*cf5a6c84SAndroid Build Coastguard Worker // Compression option not available
44*cf5a6c84SAndroid Build Coastguard Worker XZ_OPTIONS_ERROR,
45*cf5a6c84SAndroid Build Coastguard Worker // Corrupt Data
46*cf5a6c84SAndroid Build Coastguard Worker XZ_DATA_ERROR,
47*cf5a6c84SAndroid Build Coastguard Worker // Can't make progress
48*cf5a6c84SAndroid Build Coastguard Worker XZ_BUF_ERROR,
49*cf5a6c84SAndroid Build Coastguard Worker // XZ_BUF_ERROR is returned when two consecutive calls to XZ code cannot
50*cf5a6c84SAndroid Build Coastguard Worker // consume any input and cannot produce any new output. This happens when
51*cf5a6c84SAndroid Build Coastguard Worker // there is no new input available, or the output buffer is full while at
52*cf5a6c84SAndroid Build Coastguard Worker // least one output byte is still pending. Assuming your code is not buggy,
53*cf5a6c84SAndroid Build Coastguard Worker // you can get this error only when decoding a compressed stream that is
54*cf5a6c84SAndroid Build Coastguard Worker // truncated or otherwise corrupt.
55*cf5a6c84SAndroid Build Coastguard Worker };
56*cf5a6c84SAndroid Build Coastguard Worker
57*cf5a6c84SAndroid Build Coastguard Worker // Passing input and output buffers to XZ code
58*cf5a6c84SAndroid Build Coastguard Worker // Only the contents of the output buffer from out[out_pos] onward, and
59*cf5a6c84SAndroid Build Coastguard Worker // the variables in_pos and out_pos are modified by the XZ code.
60*cf5a6c84SAndroid Build Coastguard Worker struct xz_buf {
61*cf5a6c84SAndroid Build Coastguard Worker // buffer begins (Can be 0 IF pos == size)
62*cf5a6c84SAndroid Build Coastguard Worker const char *in;
63*cf5a6c84SAndroid Build Coastguard Worker // buffer position
64*cf5a6c84SAndroid Build Coastguard Worker size_t in_pos;
65*cf5a6c84SAndroid Build Coastguard Worker // buffer size
66*cf5a6c84SAndroid Build Coastguard Worker size_t in_size;
67*cf5a6c84SAndroid Build Coastguard Worker
68*cf5a6c84SAndroid Build Coastguard Worker char *out;
69*cf5a6c84SAndroid Build Coastguard Worker size_t out_pos;
70*cf5a6c84SAndroid Build Coastguard Worker size_t out_size;
71*cf5a6c84SAndroid Build Coastguard Worker };
72*cf5a6c84SAndroid Build Coastguard Worker
73*cf5a6c84SAndroid Build Coastguard Worker // Opaque type to hold the XZ decoder state
74*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec;
75*cf5a6c84SAndroid Build Coastguard Worker
76*cf5a6c84SAndroid Build Coastguard Worker // Update CRC32 value using the polynomial from IEEE-802.3. To start a new
77*cf5a6c84SAndroid Build Coastguard Worker // calculation, the third argument must be zero. To continue the calculation,
78*cf5a6c84SAndroid Build Coastguard Worker // the previously returned value is passed as the third argument.
79*cf5a6c84SAndroid Build Coastguard Worker static unsigned xz_crc32_table[256];
80*cf5a6c84SAndroid Build Coastguard Worker
xz_crc32(const char * buf,size_t size,unsigned crc)81*cf5a6c84SAndroid Build Coastguard Worker unsigned xz_crc32(const char *buf, size_t size, unsigned crc)
82*cf5a6c84SAndroid Build Coastguard Worker {
83*cf5a6c84SAndroid Build Coastguard Worker crc = ~crc;
84*cf5a6c84SAndroid Build Coastguard Worker
85*cf5a6c84SAndroid Build Coastguard Worker while (size) {
86*cf5a6c84SAndroid Build Coastguard Worker crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
87*cf5a6c84SAndroid Build Coastguard Worker --size;
88*cf5a6c84SAndroid Build Coastguard Worker }
89*cf5a6c84SAndroid Build Coastguard Worker
90*cf5a6c84SAndroid Build Coastguard Worker return ~crc;
91*cf5a6c84SAndroid Build Coastguard Worker }
92*cf5a6c84SAndroid Build Coastguard Worker
93*cf5a6c84SAndroid Build Coastguard Worker static uint64_t xz_crc64_table[256];
94*cf5a6c84SAndroid Build Coastguard Worker
95*cf5a6c84SAndroid Build Coastguard Worker
96*cf5a6c84SAndroid Build Coastguard Worker // END xz.h
97*cf5a6c84SAndroid Build Coastguard Worker // BEGIN xz_private.h
98*cf5a6c84SAndroid Build Coastguard Worker
99*cf5a6c84SAndroid Build Coastguard Worker #define memeq(a, b, size) (!memcmp(a, b, size))
100*cf5a6c84SAndroid Build Coastguard Worker
101*cf5a6c84SAndroid Build Coastguard Worker /* Inline functions to access unaligned unsigned 32-bit integers */
get_unaligned_le32(const char * buf)102*cf5a6c84SAndroid Build Coastguard Worker static unsigned get_unaligned_le32(const char *buf)
103*cf5a6c84SAndroid Build Coastguard Worker {
104*cf5a6c84SAndroid Build Coastguard Worker return (unsigned)buf[0]
105*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[1] << 8)
106*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[2] << 16)
107*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[3] << 24);
108*cf5a6c84SAndroid Build Coastguard Worker }
109*cf5a6c84SAndroid Build Coastguard Worker
get_unaligned_be32(const char * buf)110*cf5a6c84SAndroid Build Coastguard Worker static unsigned get_unaligned_be32(const char *buf)
111*cf5a6c84SAndroid Build Coastguard Worker {
112*cf5a6c84SAndroid Build Coastguard Worker return (unsigned)(buf[0] << 24)
113*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[1] << 16)
114*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[2] << 8)
115*cf5a6c84SAndroid Build Coastguard Worker | (unsigned)buf[3];
116*cf5a6c84SAndroid Build Coastguard Worker }
117*cf5a6c84SAndroid Build Coastguard Worker
put_unaligned_le32(unsigned val,char * buf)118*cf5a6c84SAndroid Build Coastguard Worker static void put_unaligned_le32(unsigned val, char *buf)
119*cf5a6c84SAndroid Build Coastguard Worker {
120*cf5a6c84SAndroid Build Coastguard Worker buf[0] = (char)val;
121*cf5a6c84SAndroid Build Coastguard Worker buf[1] = (char)(val >> 8);
122*cf5a6c84SAndroid Build Coastguard Worker buf[2] = (char)(val >> 16);
123*cf5a6c84SAndroid Build Coastguard Worker buf[3] = (char)(val >> 24);
124*cf5a6c84SAndroid Build Coastguard Worker }
125*cf5a6c84SAndroid Build Coastguard Worker
put_unaligned_be32(unsigned val,char * buf)126*cf5a6c84SAndroid Build Coastguard Worker static void put_unaligned_be32(unsigned val, char *buf)
127*cf5a6c84SAndroid Build Coastguard Worker {
128*cf5a6c84SAndroid Build Coastguard Worker buf[0] = (char)(val >> 24);
129*cf5a6c84SAndroid Build Coastguard Worker buf[1] = (char)(val >> 16);
130*cf5a6c84SAndroid Build Coastguard Worker buf[2] = (char)(val >> 8);
131*cf5a6c84SAndroid Build Coastguard Worker buf[3] = (char)val;
132*cf5a6c84SAndroid Build Coastguard Worker }
133*cf5a6c84SAndroid Build Coastguard Worker
134*cf5a6c84SAndroid Build Coastguard Worker // Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
135*cf5a6c84SAndroid Build Coastguard Worker // before calling xz_dec_lzma2_run().
136*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_lzma2 *xz_dec_lzma2_create(unsigned dict_max);
137*cf5a6c84SAndroid Build Coastguard Worker
138*cf5a6c84SAndroid Build Coastguard Worker // Decode the LZMA2 properties (one byte) and reset the decoder. Return
139*cf5a6c84SAndroid Build Coastguard Worker // XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not
140*cf5a6c84SAndroid Build Coastguard Worker // big enough, and XZ_OPTIONS_ERROR if props indicates something that this
141*cf5a6c84SAndroid Build Coastguard Worker // decoder doesn't support.
142*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s,
143*cf5a6c84SAndroid Build Coastguard Worker char props);
144*cf5a6c84SAndroid Build Coastguard Worker
145*cf5a6c84SAndroid Build Coastguard Worker /* Decode raw LZMA2 stream from b->in to b->out. */
146*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
147*cf5a6c84SAndroid Build Coastguard Worker struct xz_buf *b);
148*cf5a6c84SAndroid Build Coastguard Worker
149*cf5a6c84SAndroid Build Coastguard Worker // END "xz_private.h"
150*cf5a6c84SAndroid Build Coastguard Worker
151*cf5a6c84SAndroid Build Coastguard Worker
152*cf5a6c84SAndroid Build Coastguard Worker
153*cf5a6c84SAndroid Build Coastguard Worker
154*cf5a6c84SAndroid Build Coastguard Worker // Branch/Call/Jump (BCJ) filter decoders
155*cf5a6c84SAndroid Build Coastguard Worker
156*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_bcj {
157*cf5a6c84SAndroid Build Coastguard Worker /* Type of the BCJ filter being used */
158*cf5a6c84SAndroid Build Coastguard Worker enum {
159*cf5a6c84SAndroid Build Coastguard Worker BCJ_X86 = 4, /* x86 or x86-64 */
160*cf5a6c84SAndroid Build Coastguard Worker BCJ_POWERPC = 5, /* Big endian only */
161*cf5a6c84SAndroid Build Coastguard Worker BCJ_IA64 = 6, /* Big or little endian */
162*cf5a6c84SAndroid Build Coastguard Worker BCJ_ARM = 7, /* Little endian only */
163*cf5a6c84SAndroid Build Coastguard Worker BCJ_ARMTHUMB = 8, /* Little endian only */
164*cf5a6c84SAndroid Build Coastguard Worker BCJ_SPARC = 9 /* Big or little endian */
165*cf5a6c84SAndroid Build Coastguard Worker } type;
166*cf5a6c84SAndroid Build Coastguard Worker
167*cf5a6c84SAndroid Build Coastguard Worker /* Return value of the next filter in the chain. We need to preserve
168*cf5a6c84SAndroid Build Coastguard Worker * this information across calls, because we must not call the next
169*cf5a6c84SAndroid Build Coastguard Worker * filter anymore once it has returned XZ_STREAM_END.
170*cf5a6c84SAndroid Build Coastguard Worker */
171*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
172*cf5a6c84SAndroid Build Coastguard Worker
173*cf5a6c84SAndroid Build Coastguard Worker /* Absolute position relative to the beginning of the uncompressed
174*cf5a6c84SAndroid Build Coastguard Worker * data (in a single .xz Block). We care only about the lowest 32
175*cf5a6c84SAndroid Build Coastguard Worker * bits so this doesn't need to be uint64_t even with big files.
176*cf5a6c84SAndroid Build Coastguard Worker */
177*cf5a6c84SAndroid Build Coastguard Worker unsigned pos;
178*cf5a6c84SAndroid Build Coastguard Worker
179*cf5a6c84SAndroid Build Coastguard Worker /* x86 filter state */
180*cf5a6c84SAndroid Build Coastguard Worker unsigned x86_prev_mask;
181*cf5a6c84SAndroid Build Coastguard Worker
182*cf5a6c84SAndroid Build Coastguard Worker /* Temporary space to hold the variables from struct xz_buf */
183*cf5a6c84SAndroid Build Coastguard Worker char *out;
184*cf5a6c84SAndroid Build Coastguard Worker size_t out_pos;
185*cf5a6c84SAndroid Build Coastguard Worker size_t out_size;
186*cf5a6c84SAndroid Build Coastguard Worker
187*cf5a6c84SAndroid Build Coastguard Worker struct {
188*cf5a6c84SAndroid Build Coastguard Worker /* Amount of already filtered data in the beginning of buf */
189*cf5a6c84SAndroid Build Coastguard Worker size_t filtered;
190*cf5a6c84SAndroid Build Coastguard Worker
191*cf5a6c84SAndroid Build Coastguard Worker /* Total amount of data currently stored in buf */
192*cf5a6c84SAndroid Build Coastguard Worker size_t size;
193*cf5a6c84SAndroid Build Coastguard Worker
194*cf5a6c84SAndroid Build Coastguard Worker /*
195*cf5a6c84SAndroid Build Coastguard Worker * Buffer to hold a mix of filtered and unfiltered data. This
196*cf5a6c84SAndroid Build Coastguard Worker * needs to be big enough to hold Alignment + 2 * Look-ahead:
197*cf5a6c84SAndroid Build Coastguard Worker *
198*cf5a6c84SAndroid Build Coastguard Worker * Type Alignment Look-ahead
199*cf5a6c84SAndroid Build Coastguard Worker * x86 1 4
200*cf5a6c84SAndroid Build Coastguard Worker * PowerPC 4 0
201*cf5a6c84SAndroid Build Coastguard Worker * IA-64 16 0
202*cf5a6c84SAndroid Build Coastguard Worker * ARM 4 0
203*cf5a6c84SAndroid Build Coastguard Worker * ARM-Thumb 2 2
204*cf5a6c84SAndroid Build Coastguard Worker * SPARC 4 0
205*cf5a6c84SAndroid Build Coastguard Worker */
206*cf5a6c84SAndroid Build Coastguard Worker char buf[16];
207*cf5a6c84SAndroid Build Coastguard Worker } temp;
208*cf5a6c84SAndroid Build Coastguard Worker };
209*cf5a6c84SAndroid Build Coastguard Worker
210*cf5a6c84SAndroid Build Coastguard Worker // This is used to test the most significant byte of a memory address
211*cf5a6c84SAndroid Build Coastguard Worker // in an x86 instruction.
bcj_x86_test_msbyte(char b)212*cf5a6c84SAndroid Build Coastguard Worker static int bcj_x86_test_msbyte(char b)
213*cf5a6c84SAndroid Build Coastguard Worker {
214*cf5a6c84SAndroid Build Coastguard Worker return !b || !~b;
215*cf5a6c84SAndroid Build Coastguard Worker }
216*cf5a6c84SAndroid Build Coastguard Worker
bcj_x86(struct xz_dec_bcj * s,char * buf,size_t size)217*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_x86(struct xz_dec_bcj *s, char *buf, size_t size)
218*cf5a6c84SAndroid Build Coastguard Worker {
219*cf5a6c84SAndroid Build Coastguard Worker static const int mask_to_allowed_status[8]
220*cf5a6c84SAndroid Build Coastguard Worker = { 1,1,1,0,1,0,0,0 };
221*cf5a6c84SAndroid Build Coastguard Worker
222*cf5a6c84SAndroid Build Coastguard Worker static const char mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
223*cf5a6c84SAndroid Build Coastguard Worker
224*cf5a6c84SAndroid Build Coastguard Worker size_t i;
225*cf5a6c84SAndroid Build Coastguard Worker size_t prev_pos = (size_t)-1;
226*cf5a6c84SAndroid Build Coastguard Worker unsigned prev_mask = s->x86_prev_mask;
227*cf5a6c84SAndroid Build Coastguard Worker unsigned src;
228*cf5a6c84SAndroid Build Coastguard Worker unsigned dest;
229*cf5a6c84SAndroid Build Coastguard Worker unsigned j;
230*cf5a6c84SAndroid Build Coastguard Worker char b;
231*cf5a6c84SAndroid Build Coastguard Worker
232*cf5a6c84SAndroid Build Coastguard Worker if (size <= 4)
233*cf5a6c84SAndroid Build Coastguard Worker return 0;
234*cf5a6c84SAndroid Build Coastguard Worker
235*cf5a6c84SAndroid Build Coastguard Worker size -= 4;
236*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i < size; ++i) {
237*cf5a6c84SAndroid Build Coastguard Worker if ((buf[i] & 0xFE) != 0xE8)
238*cf5a6c84SAndroid Build Coastguard Worker continue;
239*cf5a6c84SAndroid Build Coastguard Worker
240*cf5a6c84SAndroid Build Coastguard Worker prev_pos = i - prev_pos;
241*cf5a6c84SAndroid Build Coastguard Worker if (prev_pos > 3) {
242*cf5a6c84SAndroid Build Coastguard Worker prev_mask = 0;
243*cf5a6c84SAndroid Build Coastguard Worker } else {
244*cf5a6c84SAndroid Build Coastguard Worker prev_mask = (prev_mask << (prev_pos - 1)) & 7;
245*cf5a6c84SAndroid Build Coastguard Worker if (prev_mask) {
246*cf5a6c84SAndroid Build Coastguard Worker b = buf[i + 4 - mask_to_bit_num[prev_mask]];
247*cf5a6c84SAndroid Build Coastguard Worker if (!mask_to_allowed_status[prev_mask]
248*cf5a6c84SAndroid Build Coastguard Worker || bcj_x86_test_msbyte(b)) {
249*cf5a6c84SAndroid Build Coastguard Worker prev_pos = i;
250*cf5a6c84SAndroid Build Coastguard Worker prev_mask = (prev_mask << 1) | 1;
251*cf5a6c84SAndroid Build Coastguard Worker continue;
252*cf5a6c84SAndroid Build Coastguard Worker }
253*cf5a6c84SAndroid Build Coastguard Worker }
254*cf5a6c84SAndroid Build Coastguard Worker }
255*cf5a6c84SAndroid Build Coastguard Worker
256*cf5a6c84SAndroid Build Coastguard Worker prev_pos = i;
257*cf5a6c84SAndroid Build Coastguard Worker
258*cf5a6c84SAndroid Build Coastguard Worker if (bcj_x86_test_msbyte(buf[i + 4])) {
259*cf5a6c84SAndroid Build Coastguard Worker src = get_unaligned_le32(buf + i + 1);
260*cf5a6c84SAndroid Build Coastguard Worker for (;;) {
261*cf5a6c84SAndroid Build Coastguard Worker dest = src - (s->pos + (unsigned)i + 5);
262*cf5a6c84SAndroid Build Coastguard Worker if (!prev_mask)
263*cf5a6c84SAndroid Build Coastguard Worker break;
264*cf5a6c84SAndroid Build Coastguard Worker
265*cf5a6c84SAndroid Build Coastguard Worker j = mask_to_bit_num[prev_mask] * 8;
266*cf5a6c84SAndroid Build Coastguard Worker b = (char)(dest >> (24 - j));
267*cf5a6c84SAndroid Build Coastguard Worker if (!bcj_x86_test_msbyte(b))
268*cf5a6c84SAndroid Build Coastguard Worker break;
269*cf5a6c84SAndroid Build Coastguard Worker
270*cf5a6c84SAndroid Build Coastguard Worker src = dest ^ (((unsigned)1 << (32 - j)) - 1);
271*cf5a6c84SAndroid Build Coastguard Worker }
272*cf5a6c84SAndroid Build Coastguard Worker
273*cf5a6c84SAndroid Build Coastguard Worker dest &= 0x01FFFFFF;
274*cf5a6c84SAndroid Build Coastguard Worker dest |= (unsigned)0 - (dest & 0x01000000);
275*cf5a6c84SAndroid Build Coastguard Worker put_unaligned_le32(dest, buf + i + 1);
276*cf5a6c84SAndroid Build Coastguard Worker i += 4;
277*cf5a6c84SAndroid Build Coastguard Worker } else {
278*cf5a6c84SAndroid Build Coastguard Worker prev_mask = (prev_mask << 1) | 1;
279*cf5a6c84SAndroid Build Coastguard Worker }
280*cf5a6c84SAndroid Build Coastguard Worker }
281*cf5a6c84SAndroid Build Coastguard Worker
282*cf5a6c84SAndroid Build Coastguard Worker prev_pos = i - prev_pos;
283*cf5a6c84SAndroid Build Coastguard Worker s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
284*cf5a6c84SAndroid Build Coastguard Worker return i;
285*cf5a6c84SAndroid Build Coastguard Worker }
286*cf5a6c84SAndroid Build Coastguard Worker
bcj_powerpc(struct xz_dec_bcj * s,char * buf,size_t size)287*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_powerpc(struct xz_dec_bcj *s, char *buf, size_t size)
288*cf5a6c84SAndroid Build Coastguard Worker {
289*cf5a6c84SAndroid Build Coastguard Worker size_t i;
290*cf5a6c84SAndroid Build Coastguard Worker unsigned instr;
291*cf5a6c84SAndroid Build Coastguard Worker
292*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i + 4 <= size; i += 4) {
293*cf5a6c84SAndroid Build Coastguard Worker instr = get_unaligned_be32(buf + i);
294*cf5a6c84SAndroid Build Coastguard Worker if ((instr & 0xFC000003) == 0x48000001) {
295*cf5a6c84SAndroid Build Coastguard Worker instr &= 0x03FFFFFC;
296*cf5a6c84SAndroid Build Coastguard Worker instr -= s->pos + (unsigned)i;
297*cf5a6c84SAndroid Build Coastguard Worker instr &= 0x03FFFFFC;
298*cf5a6c84SAndroid Build Coastguard Worker instr |= 0x48000001;
299*cf5a6c84SAndroid Build Coastguard Worker put_unaligned_be32(instr, buf + i);
300*cf5a6c84SAndroid Build Coastguard Worker }
301*cf5a6c84SAndroid Build Coastguard Worker }
302*cf5a6c84SAndroid Build Coastguard Worker
303*cf5a6c84SAndroid Build Coastguard Worker return i;
304*cf5a6c84SAndroid Build Coastguard Worker }
305*cf5a6c84SAndroid Build Coastguard Worker
bcj_ia64(struct xz_dec_bcj * s,char * buf,size_t size)306*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_ia64(struct xz_dec_bcj *s, char *buf, size_t size)
307*cf5a6c84SAndroid Build Coastguard Worker {
308*cf5a6c84SAndroid Build Coastguard Worker static const char branch_table[32] = {
309*cf5a6c84SAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0,
310*cf5a6c84SAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0,
311*cf5a6c84SAndroid Build Coastguard Worker 4, 4, 6, 6, 0, 0, 7, 7,
312*cf5a6c84SAndroid Build Coastguard Worker 4, 4, 0, 0, 4, 4, 0, 0
313*cf5a6c84SAndroid Build Coastguard Worker };
314*cf5a6c84SAndroid Build Coastguard Worker
315*cf5a6c84SAndroid Build Coastguard Worker /*
316*cf5a6c84SAndroid Build Coastguard Worker * The local variables take a little bit stack space, but it's less
317*cf5a6c84SAndroid Build Coastguard Worker * than what LZMA2 decoder takes, so it doesn't make sense to reduce
318*cf5a6c84SAndroid Build Coastguard Worker * stack usage here without doing that for the LZMA2 decoder too.
319*cf5a6c84SAndroid Build Coastguard Worker */
320*cf5a6c84SAndroid Build Coastguard Worker
321*cf5a6c84SAndroid Build Coastguard Worker /* Loop counters */
322*cf5a6c84SAndroid Build Coastguard Worker size_t i;
323*cf5a6c84SAndroid Build Coastguard Worker size_t j;
324*cf5a6c84SAndroid Build Coastguard Worker
325*cf5a6c84SAndroid Build Coastguard Worker /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
326*cf5a6c84SAndroid Build Coastguard Worker unsigned slot;
327*cf5a6c84SAndroid Build Coastguard Worker
328*cf5a6c84SAndroid Build Coastguard Worker /* Bitwise offset of the instruction indicated by slot */
329*cf5a6c84SAndroid Build Coastguard Worker unsigned bit_pos;
330*cf5a6c84SAndroid Build Coastguard Worker
331*cf5a6c84SAndroid Build Coastguard Worker /* bit_pos split into byte and bit parts */
332*cf5a6c84SAndroid Build Coastguard Worker unsigned byte_pos;
333*cf5a6c84SAndroid Build Coastguard Worker unsigned bit_res;
334*cf5a6c84SAndroid Build Coastguard Worker
335*cf5a6c84SAndroid Build Coastguard Worker /* Address part of an instruction */
336*cf5a6c84SAndroid Build Coastguard Worker unsigned addr;
337*cf5a6c84SAndroid Build Coastguard Worker
338*cf5a6c84SAndroid Build Coastguard Worker /* Mask used to detect which instructions to convert */
339*cf5a6c84SAndroid Build Coastguard Worker unsigned mask;
340*cf5a6c84SAndroid Build Coastguard Worker
341*cf5a6c84SAndroid Build Coastguard Worker /* 41-bit instruction stored somewhere in the lowest 48 bits */
342*cf5a6c84SAndroid Build Coastguard Worker uint64_t instr;
343*cf5a6c84SAndroid Build Coastguard Worker
344*cf5a6c84SAndroid Build Coastguard Worker /* Instruction normalized with bit_res for easier manipulation */
345*cf5a6c84SAndroid Build Coastguard Worker uint64_t norm;
346*cf5a6c84SAndroid Build Coastguard Worker
347*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i + 16 <= size; i += 16) {
348*cf5a6c84SAndroid Build Coastguard Worker mask = branch_table[buf[i] & 0x1F];
349*cf5a6c84SAndroid Build Coastguard Worker for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
350*cf5a6c84SAndroid Build Coastguard Worker if (!((mask >> slot) & 1))
351*cf5a6c84SAndroid Build Coastguard Worker continue;
352*cf5a6c84SAndroid Build Coastguard Worker
353*cf5a6c84SAndroid Build Coastguard Worker byte_pos = bit_pos >> 3;
354*cf5a6c84SAndroid Build Coastguard Worker bit_res = bit_pos & 7;
355*cf5a6c84SAndroid Build Coastguard Worker instr = 0;
356*cf5a6c84SAndroid Build Coastguard Worker for (j = 0; j < 6; ++j)
357*cf5a6c84SAndroid Build Coastguard Worker instr |= (uint64_t)(buf[i + j + byte_pos])
358*cf5a6c84SAndroid Build Coastguard Worker << (8 * j);
359*cf5a6c84SAndroid Build Coastguard Worker
360*cf5a6c84SAndroid Build Coastguard Worker norm = instr >> bit_res;
361*cf5a6c84SAndroid Build Coastguard Worker
362*cf5a6c84SAndroid Build Coastguard Worker if (((norm >> 37) & 0x0F) == 5
363*cf5a6c84SAndroid Build Coastguard Worker && !((norm >> 9) & 7)) {
364*cf5a6c84SAndroid Build Coastguard Worker addr = (norm >> 13) & 0x0FFFFF;
365*cf5a6c84SAndroid Build Coastguard Worker addr |= ((unsigned)(norm >> 36) & 1) << 20;
366*cf5a6c84SAndroid Build Coastguard Worker addr <<= 4;
367*cf5a6c84SAndroid Build Coastguard Worker addr -= s->pos + (unsigned)i;
368*cf5a6c84SAndroid Build Coastguard Worker addr >>= 4;
369*cf5a6c84SAndroid Build Coastguard Worker
370*cf5a6c84SAndroid Build Coastguard Worker norm &= ~((uint64_t)0x8FFFFF << 13);
371*cf5a6c84SAndroid Build Coastguard Worker norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
372*cf5a6c84SAndroid Build Coastguard Worker norm |= (uint64_t)(addr & 0x100000)
373*cf5a6c84SAndroid Build Coastguard Worker << (36 - 20);
374*cf5a6c84SAndroid Build Coastguard Worker
375*cf5a6c84SAndroid Build Coastguard Worker instr &= (1 << bit_res) - 1;
376*cf5a6c84SAndroid Build Coastguard Worker instr |= norm << bit_res;
377*cf5a6c84SAndroid Build Coastguard Worker
378*cf5a6c84SAndroid Build Coastguard Worker for (j = 0; j < 6; j++)
379*cf5a6c84SAndroid Build Coastguard Worker buf[i + j + byte_pos]
380*cf5a6c84SAndroid Build Coastguard Worker = (char)(instr >> (8 * j));
381*cf5a6c84SAndroid Build Coastguard Worker }
382*cf5a6c84SAndroid Build Coastguard Worker }
383*cf5a6c84SAndroid Build Coastguard Worker }
384*cf5a6c84SAndroid Build Coastguard Worker
385*cf5a6c84SAndroid Build Coastguard Worker return i;
386*cf5a6c84SAndroid Build Coastguard Worker }
387*cf5a6c84SAndroid Build Coastguard Worker
bcj_arm(struct xz_dec_bcj * s,char * buf,size_t size)388*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_arm(struct xz_dec_bcj *s, char *buf, size_t size)
389*cf5a6c84SAndroid Build Coastguard Worker {
390*cf5a6c84SAndroid Build Coastguard Worker size_t i;
391*cf5a6c84SAndroid Build Coastguard Worker unsigned addr;
392*cf5a6c84SAndroid Build Coastguard Worker
393*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i + 4 <= size; i += 4) {
394*cf5a6c84SAndroid Build Coastguard Worker if (buf[i + 3] == 0xEB) {
395*cf5a6c84SAndroid Build Coastguard Worker addr = (unsigned)buf[i] | ((unsigned)buf[i + 1] << 8)
396*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[i + 2] << 16);
397*cf5a6c84SAndroid Build Coastguard Worker addr <<= 2;
398*cf5a6c84SAndroid Build Coastguard Worker addr -= s->pos + (unsigned)i + 8;
399*cf5a6c84SAndroid Build Coastguard Worker addr >>= 2;
400*cf5a6c84SAndroid Build Coastguard Worker buf[i] = (char)addr;
401*cf5a6c84SAndroid Build Coastguard Worker buf[i + 1] = (char)(addr >> 8);
402*cf5a6c84SAndroid Build Coastguard Worker buf[i + 2] = (char)(addr >> 16);
403*cf5a6c84SAndroid Build Coastguard Worker }
404*cf5a6c84SAndroid Build Coastguard Worker }
405*cf5a6c84SAndroid Build Coastguard Worker
406*cf5a6c84SAndroid Build Coastguard Worker return i;
407*cf5a6c84SAndroid Build Coastguard Worker }
408*cf5a6c84SAndroid Build Coastguard Worker
bcj_armthumb(struct xz_dec_bcj * s,char * buf,size_t size)409*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_armthumb(struct xz_dec_bcj *s, char *buf, size_t size)
410*cf5a6c84SAndroid Build Coastguard Worker {
411*cf5a6c84SAndroid Build Coastguard Worker size_t i;
412*cf5a6c84SAndroid Build Coastguard Worker unsigned addr;
413*cf5a6c84SAndroid Build Coastguard Worker
414*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i + 4 <= size; i += 2) {
415*cf5a6c84SAndroid Build Coastguard Worker if ((buf[i + 1] & 0xF8) == 0xF0
416*cf5a6c84SAndroid Build Coastguard Worker && (buf[i + 3] & 0xF8) == 0xF8) {
417*cf5a6c84SAndroid Build Coastguard Worker addr = (((unsigned)buf[i + 1] & 7) << 19)
418*cf5a6c84SAndroid Build Coastguard Worker | ((unsigned)buf[i] << 11)
419*cf5a6c84SAndroid Build Coastguard Worker | (((unsigned)buf[i + 3] & 7) << 8)
420*cf5a6c84SAndroid Build Coastguard Worker | (unsigned)buf[i + 2];
421*cf5a6c84SAndroid Build Coastguard Worker addr <<= 1;
422*cf5a6c84SAndroid Build Coastguard Worker addr -= s->pos + (unsigned)i + 4;
423*cf5a6c84SAndroid Build Coastguard Worker addr >>= 1;
424*cf5a6c84SAndroid Build Coastguard Worker buf[i + 1] = (char)(0xF0 | ((addr >> 19) & 7));
425*cf5a6c84SAndroid Build Coastguard Worker buf[i] = (char)(addr >> 11);
426*cf5a6c84SAndroid Build Coastguard Worker buf[i + 3] = (char)(0xF8 | ((addr >> 8) & 7));
427*cf5a6c84SAndroid Build Coastguard Worker buf[i + 2] = (char)addr;
428*cf5a6c84SAndroid Build Coastguard Worker i += 2;
429*cf5a6c84SAndroid Build Coastguard Worker }
430*cf5a6c84SAndroid Build Coastguard Worker }
431*cf5a6c84SAndroid Build Coastguard Worker
432*cf5a6c84SAndroid Build Coastguard Worker return i;
433*cf5a6c84SAndroid Build Coastguard Worker }
434*cf5a6c84SAndroid Build Coastguard Worker
bcj_sparc(struct xz_dec_bcj * s,char * buf,size_t size)435*cf5a6c84SAndroid Build Coastguard Worker static size_t bcj_sparc(struct xz_dec_bcj *s, char *buf, size_t size)
436*cf5a6c84SAndroid Build Coastguard Worker {
437*cf5a6c84SAndroid Build Coastguard Worker size_t i;
438*cf5a6c84SAndroid Build Coastguard Worker unsigned instr;
439*cf5a6c84SAndroid Build Coastguard Worker
440*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i + 4 <= size; i += 4) {
441*cf5a6c84SAndroid Build Coastguard Worker instr = get_unaligned_be32(buf + i);
442*cf5a6c84SAndroid Build Coastguard Worker if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
443*cf5a6c84SAndroid Build Coastguard Worker instr <<= 2;
444*cf5a6c84SAndroid Build Coastguard Worker instr -= s->pos + (unsigned)i;
445*cf5a6c84SAndroid Build Coastguard Worker instr >>= 2;
446*cf5a6c84SAndroid Build Coastguard Worker instr = ((unsigned)0x40000000 - (instr & 0x400000))
447*cf5a6c84SAndroid Build Coastguard Worker | 0x40000000 | (instr & 0x3FFFFF);
448*cf5a6c84SAndroid Build Coastguard Worker put_unaligned_be32(instr, buf + i);
449*cf5a6c84SAndroid Build Coastguard Worker }
450*cf5a6c84SAndroid Build Coastguard Worker }
451*cf5a6c84SAndroid Build Coastguard Worker
452*cf5a6c84SAndroid Build Coastguard Worker return i;
453*cf5a6c84SAndroid Build Coastguard Worker }
454*cf5a6c84SAndroid Build Coastguard Worker
455*cf5a6c84SAndroid Build Coastguard Worker /*
456*cf5a6c84SAndroid Build Coastguard Worker * Apply the selected BCJ filter. Update *pos and s->pos to match the amount
457*cf5a6c84SAndroid Build Coastguard Worker * of data that got filtered.
458*cf5a6c84SAndroid Build Coastguard Worker *
459*cf5a6c84SAndroid Build Coastguard Worker * NOTE: This is implemented as a switch statement to avoid using function
460*cf5a6c84SAndroid Build Coastguard Worker * pointers, which could be problematic in the kernel boot code, which must
461*cf5a6c84SAndroid Build Coastguard Worker * avoid pointers to static data (at least on x86).
462*cf5a6c84SAndroid Build Coastguard Worker */
bcj_apply(struct xz_dec_bcj * s,char * buf,size_t * pos,size_t size)463*cf5a6c84SAndroid Build Coastguard Worker static void bcj_apply(struct xz_dec_bcj *s,
464*cf5a6c84SAndroid Build Coastguard Worker char *buf, size_t *pos, size_t size)
465*cf5a6c84SAndroid Build Coastguard Worker {
466*cf5a6c84SAndroid Build Coastguard Worker size_t filtered;
467*cf5a6c84SAndroid Build Coastguard Worker
468*cf5a6c84SAndroid Build Coastguard Worker buf += *pos;
469*cf5a6c84SAndroid Build Coastguard Worker size -= *pos;
470*cf5a6c84SAndroid Build Coastguard Worker
471*cf5a6c84SAndroid Build Coastguard Worker switch (s->type) {
472*cf5a6c84SAndroid Build Coastguard Worker case BCJ_X86:
473*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_x86(s, buf, size);
474*cf5a6c84SAndroid Build Coastguard Worker break;
475*cf5a6c84SAndroid Build Coastguard Worker case BCJ_POWERPC:
476*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_powerpc(s, buf, size);
477*cf5a6c84SAndroid Build Coastguard Worker break;
478*cf5a6c84SAndroid Build Coastguard Worker case BCJ_IA64:
479*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_ia64(s, buf, size);
480*cf5a6c84SAndroid Build Coastguard Worker break;
481*cf5a6c84SAndroid Build Coastguard Worker case BCJ_ARM:
482*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_arm(s, buf, size);
483*cf5a6c84SAndroid Build Coastguard Worker break;
484*cf5a6c84SAndroid Build Coastguard Worker case BCJ_ARMTHUMB:
485*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_armthumb(s, buf, size);
486*cf5a6c84SAndroid Build Coastguard Worker break;
487*cf5a6c84SAndroid Build Coastguard Worker case BCJ_SPARC:
488*cf5a6c84SAndroid Build Coastguard Worker filtered = bcj_sparc(s, buf, size);
489*cf5a6c84SAndroid Build Coastguard Worker break;
490*cf5a6c84SAndroid Build Coastguard Worker default:
491*cf5a6c84SAndroid Build Coastguard Worker /* Never reached but silence compiler warnings. */
492*cf5a6c84SAndroid Build Coastguard Worker filtered = 0;
493*cf5a6c84SAndroid Build Coastguard Worker break;
494*cf5a6c84SAndroid Build Coastguard Worker }
495*cf5a6c84SAndroid Build Coastguard Worker
496*cf5a6c84SAndroid Build Coastguard Worker *pos += filtered;
497*cf5a6c84SAndroid Build Coastguard Worker s->pos += filtered;
498*cf5a6c84SAndroid Build Coastguard Worker }
499*cf5a6c84SAndroid Build Coastguard Worker
500*cf5a6c84SAndroid Build Coastguard Worker /*
501*cf5a6c84SAndroid Build Coastguard Worker * Flush pending filtered data from temp to the output buffer.
502*cf5a6c84SAndroid Build Coastguard Worker * Move the remaining mixture of possibly filtered and unfiltered
503*cf5a6c84SAndroid Build Coastguard Worker * data to the beginning of temp.
504*cf5a6c84SAndroid Build Coastguard Worker */
bcj_flush(struct xz_dec_bcj * s,struct xz_buf * b)505*cf5a6c84SAndroid Build Coastguard Worker static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
506*cf5a6c84SAndroid Build Coastguard Worker {
507*cf5a6c84SAndroid Build Coastguard Worker size_t copy_size;
508*cf5a6c84SAndroid Build Coastguard Worker
509*cf5a6c84SAndroid Build Coastguard Worker copy_size = minof(s->temp.filtered, b->out_size - b->out_pos);
510*cf5a6c84SAndroid Build Coastguard Worker memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
511*cf5a6c84SAndroid Build Coastguard Worker b->out_pos += copy_size;
512*cf5a6c84SAndroid Build Coastguard Worker
513*cf5a6c84SAndroid Build Coastguard Worker s->temp.filtered -= copy_size;
514*cf5a6c84SAndroid Build Coastguard Worker s->temp.size -= copy_size;
515*cf5a6c84SAndroid Build Coastguard Worker memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
516*cf5a6c84SAndroid Build Coastguard Worker }
517*cf5a6c84SAndroid Build Coastguard Worker
518*cf5a6c84SAndroid Build Coastguard Worker // Decode raw BCJ + LZMA2 stream. This must be used only if there actually is
519*cf5a6c84SAndroid Build Coastguard Worker // a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
520*cf5a6c84SAndroid Build Coastguard Worker // must be called directly.
521*cf5a6c84SAndroid Build Coastguard Worker // The BCJ filter functions are primitive in sense that they process the
522*cf5a6c84SAndroid Build Coastguard Worker // data in chunks of 1-16 bytes. To hide this issue, this function does
523*cf5a6c84SAndroid Build Coastguard Worker // some buffering.
xz_dec_bcj_run(struct xz_dec_bcj * s,struct xz_dec_lzma2 * lzma2,struct xz_buf * b)524*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2,
525*cf5a6c84SAndroid Build Coastguard Worker struct xz_buf *b)
526*cf5a6c84SAndroid Build Coastguard Worker {
527*cf5a6c84SAndroid Build Coastguard Worker size_t out_start;
528*cf5a6c84SAndroid Build Coastguard Worker
529*cf5a6c84SAndroid Build Coastguard Worker /*
530*cf5a6c84SAndroid Build Coastguard Worker * Flush pending already filtered data to the output buffer. Return
531*cf5a6c84SAndroid Build Coastguard Worker * immediatelly if we couldn't flush everything, or if the next
532*cf5a6c84SAndroid Build Coastguard Worker * filter in the chain had already returned XZ_STREAM_END.
533*cf5a6c84SAndroid Build Coastguard Worker */
534*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.filtered > 0) {
535*cf5a6c84SAndroid Build Coastguard Worker bcj_flush(s, b);
536*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.filtered > 0)
537*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
538*cf5a6c84SAndroid Build Coastguard Worker
539*cf5a6c84SAndroid Build Coastguard Worker if (s->ret == XZ_STREAM_END)
540*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
541*cf5a6c84SAndroid Build Coastguard Worker }
542*cf5a6c84SAndroid Build Coastguard Worker
543*cf5a6c84SAndroid Build Coastguard Worker /*
544*cf5a6c84SAndroid Build Coastguard Worker * If we have more output space than what is currently pending in
545*cf5a6c84SAndroid Build Coastguard Worker * temp, copy the unfiltered data from temp to the output buffer
546*cf5a6c84SAndroid Build Coastguard Worker * and try to fill the output buffer by decoding more data from the
547*cf5a6c84SAndroid Build Coastguard Worker * next filter in the chain. Apply the BCJ filter on the new data
548*cf5a6c84SAndroid Build Coastguard Worker * in the output buffer. If everything cannot be filtered, copy it
549*cf5a6c84SAndroid Build Coastguard Worker * to temp and rewind the output buffer position accordingly.
550*cf5a6c84SAndroid Build Coastguard Worker *
551*cf5a6c84SAndroid Build Coastguard Worker * This needs to be always run when temp.size == 0 to handle a special
552*cf5a6c84SAndroid Build Coastguard Worker * case where the output buffer is full and the next filter has no
553*cf5a6c84SAndroid Build Coastguard Worker * more output coming but hasn't returned XZ_STREAM_END yet.
554*cf5a6c84SAndroid Build Coastguard Worker */
555*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size < b->out_size - b->out_pos || !s->temp.size) {
556*cf5a6c84SAndroid Build Coastguard Worker out_start = b->out_pos;
557*cf5a6c84SAndroid Build Coastguard Worker memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
558*cf5a6c84SAndroid Build Coastguard Worker b->out_pos += s->temp.size;
559*cf5a6c84SAndroid Build Coastguard Worker
560*cf5a6c84SAndroid Build Coastguard Worker s->ret = xz_dec_lzma2_run(lzma2, b);
561*cf5a6c84SAndroid Build Coastguard Worker if (s->ret != XZ_STREAM_END
562*cf5a6c84SAndroid Build Coastguard Worker && (s->ret != XZ_OK ))
563*cf5a6c84SAndroid Build Coastguard Worker return s->ret;
564*cf5a6c84SAndroid Build Coastguard Worker
565*cf5a6c84SAndroid Build Coastguard Worker bcj_apply(s, b->out, &out_start, b->out_pos);
566*cf5a6c84SAndroid Build Coastguard Worker
567*cf5a6c84SAndroid Build Coastguard Worker /*
568*cf5a6c84SAndroid Build Coastguard Worker * As an exception, if the next filter returned XZ_STREAM_END,
569*cf5a6c84SAndroid Build Coastguard Worker * we can do that too, since the last few bytes that remain
570*cf5a6c84SAndroid Build Coastguard Worker * unfiltered are meant to remain unfiltered.
571*cf5a6c84SAndroid Build Coastguard Worker */
572*cf5a6c84SAndroid Build Coastguard Worker if (s->ret == XZ_STREAM_END)
573*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
574*cf5a6c84SAndroid Build Coastguard Worker
575*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = b->out_pos - out_start;
576*cf5a6c84SAndroid Build Coastguard Worker b->out_pos -= s->temp.size;
577*cf5a6c84SAndroid Build Coastguard Worker memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
578*cf5a6c84SAndroid Build Coastguard Worker
579*cf5a6c84SAndroid Build Coastguard Worker /*
580*cf5a6c84SAndroid Build Coastguard Worker * If there wasn't enough input to the next filter to fill
581*cf5a6c84SAndroid Build Coastguard Worker * the output buffer with unfiltered data, there's no point
582*cf5a6c84SAndroid Build Coastguard Worker * to try decoding more data to temp.
583*cf5a6c84SAndroid Build Coastguard Worker */
584*cf5a6c84SAndroid Build Coastguard Worker if (b->out_pos + s->temp.size < b->out_size)
585*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
586*cf5a6c84SAndroid Build Coastguard Worker }
587*cf5a6c84SAndroid Build Coastguard Worker
588*cf5a6c84SAndroid Build Coastguard Worker /*
589*cf5a6c84SAndroid Build Coastguard Worker * We have unfiltered data in temp. If the output buffer isn't full
590*cf5a6c84SAndroid Build Coastguard Worker * yet, try to fill the temp buffer by decoding more data from the
591*cf5a6c84SAndroid Build Coastguard Worker * next filter. Apply the BCJ filter on temp. Then we hopefully can
592*cf5a6c84SAndroid Build Coastguard Worker * fill the actual output buffer by copying filtered data from temp.
593*cf5a6c84SAndroid Build Coastguard Worker * A mix of filtered and unfiltered data may be left in temp; it will
594*cf5a6c84SAndroid Build Coastguard Worker * be taken care on the next call to this function.
595*cf5a6c84SAndroid Build Coastguard Worker */
596*cf5a6c84SAndroid Build Coastguard Worker if (b->out_pos < b->out_size) {
597*cf5a6c84SAndroid Build Coastguard Worker /* Make b->out{,_pos,_size} temporarily point to s->temp. */
598*cf5a6c84SAndroid Build Coastguard Worker s->out = b->out;
599*cf5a6c84SAndroid Build Coastguard Worker s->out_pos = b->out_pos;
600*cf5a6c84SAndroid Build Coastguard Worker s->out_size = b->out_size;
601*cf5a6c84SAndroid Build Coastguard Worker b->out = s->temp.buf;
602*cf5a6c84SAndroid Build Coastguard Worker b->out_pos = s->temp.size;
603*cf5a6c84SAndroid Build Coastguard Worker b->out_size = sizeof(s->temp.buf);
604*cf5a6c84SAndroid Build Coastguard Worker
605*cf5a6c84SAndroid Build Coastguard Worker s->ret = xz_dec_lzma2_run(lzma2, b);
606*cf5a6c84SAndroid Build Coastguard Worker
607*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = b->out_pos;
608*cf5a6c84SAndroid Build Coastguard Worker b->out = s->out;
609*cf5a6c84SAndroid Build Coastguard Worker b->out_pos = s->out_pos;
610*cf5a6c84SAndroid Build Coastguard Worker b->out_size = s->out_size;
611*cf5a6c84SAndroid Build Coastguard Worker
612*cf5a6c84SAndroid Build Coastguard Worker if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
613*cf5a6c84SAndroid Build Coastguard Worker return s->ret;
614*cf5a6c84SAndroid Build Coastguard Worker
615*cf5a6c84SAndroid Build Coastguard Worker bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
616*cf5a6c84SAndroid Build Coastguard Worker
617*cf5a6c84SAndroid Build Coastguard Worker /*
618*cf5a6c84SAndroid Build Coastguard Worker * If the next filter returned XZ_STREAM_END, we mark that
619*cf5a6c84SAndroid Build Coastguard Worker * everything is filtered, since the last unfiltered bytes
620*cf5a6c84SAndroid Build Coastguard Worker * of the stream are meant to be left as is.
621*cf5a6c84SAndroid Build Coastguard Worker */
622*cf5a6c84SAndroid Build Coastguard Worker if (s->ret == XZ_STREAM_END)
623*cf5a6c84SAndroid Build Coastguard Worker s->temp.filtered = s->temp.size;
624*cf5a6c84SAndroid Build Coastguard Worker
625*cf5a6c84SAndroid Build Coastguard Worker bcj_flush(s, b);
626*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.filtered > 0)
627*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
628*cf5a6c84SAndroid Build Coastguard Worker }
629*cf5a6c84SAndroid Build Coastguard Worker
630*cf5a6c84SAndroid Build Coastguard Worker return s->ret;
631*cf5a6c84SAndroid Build Coastguard Worker }
632*cf5a6c84SAndroid Build Coastguard Worker
633*cf5a6c84SAndroid Build Coastguard Worker /*
634*cf5a6c84SAndroid Build Coastguard Worker * Decode the Filter ID of a BCJ filter. This implementation doesn't
635*cf5a6c84SAndroid Build Coastguard Worker * support custom start offsets, so no decoding of Filter Properties
636*cf5a6c84SAndroid Build Coastguard Worker * is needed. Returns XZ_OK if the given Filter ID is supported.
637*cf5a6c84SAndroid Build Coastguard Worker * Otherwise XZ_OPTIONS_ERROR is returned.
638*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_bcj_reset(struct xz_dec_bcj * s,char id)639*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, char id)
640*cf5a6c84SAndroid Build Coastguard Worker {
641*cf5a6c84SAndroid Build Coastguard Worker s->type = id;
642*cf5a6c84SAndroid Build Coastguard Worker s->ret = XZ_OK;
643*cf5a6c84SAndroid Build Coastguard Worker s->pos = 0;
644*cf5a6c84SAndroid Build Coastguard Worker s->x86_prev_mask = 0;
645*cf5a6c84SAndroid Build Coastguard Worker s->temp.filtered = 0;
646*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = 0;
647*cf5a6c84SAndroid Build Coastguard Worker
648*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
649*cf5a6c84SAndroid Build Coastguard Worker }
650*cf5a6c84SAndroid Build Coastguard Worker
651*cf5a6c84SAndroid Build Coastguard Worker /*
652*cf5a6c84SAndroid Build Coastguard Worker * LZMA2 decoder
653*cf5a6c84SAndroid Build Coastguard Worker */
654*cf5a6c84SAndroid Build Coastguard Worker
655*cf5a6c84SAndroid Build Coastguard Worker
656*cf5a6c84SAndroid Build Coastguard Worker // BEGIN xz_lzma2.h
657*cf5a6c84SAndroid Build Coastguard Worker /*
658*cf5a6c84SAndroid Build Coastguard Worker * LZMA2 definitions
659*cf5a6c84SAndroid Build Coastguard Worker *
660*cf5a6c84SAndroid Build Coastguard Worker */
661*cf5a6c84SAndroid Build Coastguard Worker
662*cf5a6c84SAndroid Build Coastguard Worker
663*cf5a6c84SAndroid Build Coastguard Worker /* Range coder constants */
664*cf5a6c84SAndroid Build Coastguard Worker #define RC_SHIFT_BITS 8
665*cf5a6c84SAndroid Build Coastguard Worker #define RC_TOP_BITS 24
666*cf5a6c84SAndroid Build Coastguard Worker #define RC_TOP_VALUE (1 << RC_TOP_BITS)
667*cf5a6c84SAndroid Build Coastguard Worker #define RC_BIT_MODEL_TOTAL_BITS 11
668*cf5a6c84SAndroid Build Coastguard Worker #define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS)
669*cf5a6c84SAndroid Build Coastguard Worker #define RC_MOVE_BITS 5
670*cf5a6c84SAndroid Build Coastguard Worker
671*cf5a6c84SAndroid Build Coastguard Worker /*
672*cf5a6c84SAndroid Build Coastguard Worker * Maximum number of position states. A position state is the lowest pb
673*cf5a6c84SAndroid Build Coastguard Worker * number of bits of the current uncompressed offset. In some places there
674*cf5a6c84SAndroid Build Coastguard Worker * are different sets of probabilities for different position states.
675*cf5a6c84SAndroid Build Coastguard Worker */
676*cf5a6c84SAndroid Build Coastguard Worker #define POS_STATES_MAX (1 << 4)
677*cf5a6c84SAndroid Build Coastguard Worker
678*cf5a6c84SAndroid Build Coastguard Worker /*
679*cf5a6c84SAndroid Build Coastguard Worker * This enum is used to track which LZMA symbols have occurred most recently
680*cf5a6c84SAndroid Build Coastguard Worker * and in which order. This information is used to predict the next symbol.
681*cf5a6c84SAndroid Build Coastguard Worker *
682*cf5a6c84SAndroid Build Coastguard Worker * Symbols:
683*cf5a6c84SAndroid Build Coastguard Worker * - Literal: One 8-bit byte
684*cf5a6c84SAndroid Build Coastguard Worker * - Match: Repeat a chunk of data at some distance
685*cf5a6c84SAndroid Build Coastguard Worker * - Long repeat: Multi-byte match at a recently seen distance
686*cf5a6c84SAndroid Build Coastguard Worker * - Short repeat: One-byte repeat at a recently seen distance
687*cf5a6c84SAndroid Build Coastguard Worker *
688*cf5a6c84SAndroid Build Coastguard Worker * The symbol names are in from STATE_oldest_older_previous. REP means
689*cf5a6c84SAndroid Build Coastguard Worker * either short or long repeated match, and NONLIT means any non-literal.
690*cf5a6c84SAndroid Build Coastguard Worker */
691*cf5a6c84SAndroid Build Coastguard Worker enum lzma_state {
692*cf5a6c84SAndroid Build Coastguard Worker STATE_LIT_LIT,
693*cf5a6c84SAndroid Build Coastguard Worker STATE_MATCH_LIT_LIT,
694*cf5a6c84SAndroid Build Coastguard Worker STATE_REP_LIT_LIT,
695*cf5a6c84SAndroid Build Coastguard Worker STATE_SHORTREP_LIT_LIT,
696*cf5a6c84SAndroid Build Coastguard Worker STATE_MATCH_LIT,
697*cf5a6c84SAndroid Build Coastguard Worker STATE_REP_LIT,
698*cf5a6c84SAndroid Build Coastguard Worker STATE_SHORTREP_LIT,
699*cf5a6c84SAndroid Build Coastguard Worker STATE_LIT_MATCH,
700*cf5a6c84SAndroid Build Coastguard Worker STATE_LIT_LONGREP,
701*cf5a6c84SAndroid Build Coastguard Worker STATE_LIT_SHORTREP,
702*cf5a6c84SAndroid Build Coastguard Worker STATE_NONLIT_MATCH,
703*cf5a6c84SAndroid Build Coastguard Worker STATE_NONLIT_REP
704*cf5a6c84SAndroid Build Coastguard Worker };
705*cf5a6c84SAndroid Build Coastguard Worker
706*cf5a6c84SAndroid Build Coastguard Worker /* Total number of states */
707*cf5a6c84SAndroid Build Coastguard Worker #define STATES 12
708*cf5a6c84SAndroid Build Coastguard Worker
709*cf5a6c84SAndroid Build Coastguard Worker /* The lowest 7 states indicate that the previous state was a literal. */
710*cf5a6c84SAndroid Build Coastguard Worker #define LIT_STATES 7
711*cf5a6c84SAndroid Build Coastguard Worker
712*cf5a6c84SAndroid Build Coastguard Worker /* Indicate that the latest symbol was a literal. */
lzma_state_literal(enum lzma_state * state)713*cf5a6c84SAndroid Build Coastguard Worker static void lzma_state_literal(enum lzma_state *state)
714*cf5a6c84SAndroid Build Coastguard Worker {
715*cf5a6c84SAndroid Build Coastguard Worker if (*state <= STATE_SHORTREP_LIT_LIT)
716*cf5a6c84SAndroid Build Coastguard Worker *state = STATE_LIT_LIT;
717*cf5a6c84SAndroid Build Coastguard Worker else if (*state <= STATE_LIT_SHORTREP)
718*cf5a6c84SAndroid Build Coastguard Worker *state -= 3;
719*cf5a6c84SAndroid Build Coastguard Worker else
720*cf5a6c84SAndroid Build Coastguard Worker *state -= 6;
721*cf5a6c84SAndroid Build Coastguard Worker }
722*cf5a6c84SAndroid Build Coastguard Worker
723*cf5a6c84SAndroid Build Coastguard Worker /* Indicate that the latest symbol was a match. */
lzma_state_match(enum lzma_state * state)724*cf5a6c84SAndroid Build Coastguard Worker static void lzma_state_match(enum lzma_state *state)
725*cf5a6c84SAndroid Build Coastguard Worker {
726*cf5a6c84SAndroid Build Coastguard Worker *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
727*cf5a6c84SAndroid Build Coastguard Worker }
728*cf5a6c84SAndroid Build Coastguard Worker
729*cf5a6c84SAndroid Build Coastguard Worker /* Indicate that the latest state was a long repeated match. */
lzma_state_long_rep(enum lzma_state * state)730*cf5a6c84SAndroid Build Coastguard Worker static void lzma_state_long_rep(enum lzma_state *state)
731*cf5a6c84SAndroid Build Coastguard Worker {
732*cf5a6c84SAndroid Build Coastguard Worker *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
733*cf5a6c84SAndroid Build Coastguard Worker }
734*cf5a6c84SAndroid Build Coastguard Worker
735*cf5a6c84SAndroid Build Coastguard Worker /* Indicate that the latest symbol was a short match. */
lzma_state_short_rep(enum lzma_state * state)736*cf5a6c84SAndroid Build Coastguard Worker static void lzma_state_short_rep(enum lzma_state *state)
737*cf5a6c84SAndroid Build Coastguard Worker {
738*cf5a6c84SAndroid Build Coastguard Worker *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
739*cf5a6c84SAndroid Build Coastguard Worker }
740*cf5a6c84SAndroid Build Coastguard Worker
741*cf5a6c84SAndroid Build Coastguard Worker /* Each literal coder is divided in three sections:
742*cf5a6c84SAndroid Build Coastguard Worker * - 0x001-0x0FF: Without match byte
743*cf5a6c84SAndroid Build Coastguard Worker * - 0x101-0x1FF: With match byte; match bit is 0
744*cf5a6c84SAndroid Build Coastguard Worker * - 0x201-0x2FF: With match byte; match bit is 1
745*cf5a6c84SAndroid Build Coastguard Worker *
746*cf5a6c84SAndroid Build Coastguard Worker * Match byte is used when the previous LZMA symbol was something else than
747*cf5a6c84SAndroid Build Coastguard Worker * a literal (that is, it was some kind of match).
748*cf5a6c84SAndroid Build Coastguard Worker */
749*cf5a6c84SAndroid Build Coastguard Worker #define LITERAL_CODER_SIZE 0x300
750*cf5a6c84SAndroid Build Coastguard Worker
751*cf5a6c84SAndroid Build Coastguard Worker /* Maximum number of literal coders */
752*cf5a6c84SAndroid Build Coastguard Worker #define LITERAL_CODERS_MAX (1 << 4)
753*cf5a6c84SAndroid Build Coastguard Worker
754*cf5a6c84SAndroid Build Coastguard Worker /* Minimum length of a match is two bytes. */
755*cf5a6c84SAndroid Build Coastguard Worker #define MATCH_LEN_MIN 2
756*cf5a6c84SAndroid Build Coastguard Worker
757*cf5a6c84SAndroid Build Coastguard Worker /* Match length is encoded with 4, 5, or 10 bits.
758*cf5a6c84SAndroid Build Coastguard Worker *
759*cf5a6c84SAndroid Build Coastguard Worker * Length Bits
760*cf5a6c84SAndroid Build Coastguard Worker * 2-9 4 = Choice=0 + 3 bits
761*cf5a6c84SAndroid Build Coastguard Worker * 10-17 5 = Choice=1 + Choice2=0 + 3 bits
762*cf5a6c84SAndroid Build Coastguard Worker * 18-273 10 = Choice=1 + Choice2=1 + 8 bits
763*cf5a6c84SAndroid Build Coastguard Worker */
764*cf5a6c84SAndroid Build Coastguard Worker #define LEN_LOW_BITS 3
765*cf5a6c84SAndroid Build Coastguard Worker #define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
766*cf5a6c84SAndroid Build Coastguard Worker #define LEN_MID_BITS 3
767*cf5a6c84SAndroid Build Coastguard Worker #define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
768*cf5a6c84SAndroid Build Coastguard Worker #define LEN_HIGH_BITS 8
769*cf5a6c84SAndroid Build Coastguard Worker #define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
770*cf5a6c84SAndroid Build Coastguard Worker #define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
771*cf5a6c84SAndroid Build Coastguard Worker
772*cf5a6c84SAndroid Build Coastguard Worker /*
773*cf5a6c84SAndroid Build Coastguard Worker * Maximum length of a match is 273 which is a result of the encoding
774*cf5a6c84SAndroid Build Coastguard Worker * described above.
775*cf5a6c84SAndroid Build Coastguard Worker */
776*cf5a6c84SAndroid Build Coastguard Worker #define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
777*cf5a6c84SAndroid Build Coastguard Worker
778*cf5a6c84SAndroid Build Coastguard Worker /*
779*cf5a6c84SAndroid Build Coastguard Worker * Different sets of probabilities are used for match distances that have
780*cf5a6c84SAndroid Build Coastguard Worker * very short match length: Lengths of 2, 3, and 4 bytes have a separate
781*cf5a6c84SAndroid Build Coastguard Worker * set of probabilities for each length. The matches with longer length
782*cf5a6c84SAndroid Build Coastguard Worker * use a shared set of probabilities.
783*cf5a6c84SAndroid Build Coastguard Worker */
784*cf5a6c84SAndroid Build Coastguard Worker #define DIST_STATES 4
785*cf5a6c84SAndroid Build Coastguard Worker
786*cf5a6c84SAndroid Build Coastguard Worker /*
787*cf5a6c84SAndroid Build Coastguard Worker * Get the index of the appropriate probability array for decoding
788*cf5a6c84SAndroid Build Coastguard Worker * the distance slot.
789*cf5a6c84SAndroid Build Coastguard Worker */
lzma_get_dist_state(unsigned len)790*cf5a6c84SAndroid Build Coastguard Worker static unsigned lzma_get_dist_state(unsigned len)
791*cf5a6c84SAndroid Build Coastguard Worker {
792*cf5a6c84SAndroid Build Coastguard Worker return len < DIST_STATES + MATCH_LEN_MIN
793*cf5a6c84SAndroid Build Coastguard Worker ? len - MATCH_LEN_MIN : DIST_STATES - 1;
794*cf5a6c84SAndroid Build Coastguard Worker }
795*cf5a6c84SAndroid Build Coastguard Worker
796*cf5a6c84SAndroid Build Coastguard Worker /*
797*cf5a6c84SAndroid Build Coastguard Worker * The highest two bits of a 32-bit match distance are encoded using six bits.
798*cf5a6c84SAndroid Build Coastguard Worker * This six-bit value is called a distance slot. This way encoding a 32-bit
799*cf5a6c84SAndroid Build Coastguard Worker * value takes 6-36 bits, larger values taking more bits.
800*cf5a6c84SAndroid Build Coastguard Worker */
801*cf5a6c84SAndroid Build Coastguard Worker #define DIST_SLOT_BITS 6
802*cf5a6c84SAndroid Build Coastguard Worker #define DIST_SLOTS (1 << DIST_SLOT_BITS)
803*cf5a6c84SAndroid Build Coastguard Worker
804*cf5a6c84SAndroid Build Coastguard Worker /* Match distances up to 127 are fully encoded using probabilities. Since
805*cf5a6c84SAndroid Build Coastguard Worker * the highest two bits (distance slot) are always encoded using six bits,
806*cf5a6c84SAndroid Build Coastguard Worker * the distances 0-3 don't need any additional bits to encode, since the
807*cf5a6c84SAndroid Build Coastguard Worker * distance slot itself is the same as the actual distance. DIST_MODEL_START
808*cf5a6c84SAndroid Build Coastguard Worker * indicates the first distance slot where at least one additional bit is
809*cf5a6c84SAndroid Build Coastguard Worker * needed.
810*cf5a6c84SAndroid Build Coastguard Worker */
811*cf5a6c84SAndroid Build Coastguard Worker #define DIST_MODEL_START 4
812*cf5a6c84SAndroid Build Coastguard Worker
813*cf5a6c84SAndroid Build Coastguard Worker /*
814*cf5a6c84SAndroid Build Coastguard Worker * Match distances greater than 127 are encoded in three pieces:
815*cf5a6c84SAndroid Build Coastguard Worker * - distance slot: the highest two bits
816*cf5a6c84SAndroid Build Coastguard Worker * - direct bits: 2-26 bits below the highest two bits
817*cf5a6c84SAndroid Build Coastguard Worker * - alignment bits: four lowest bits
818*cf5a6c84SAndroid Build Coastguard Worker *
819*cf5a6c84SAndroid Build Coastguard Worker * Direct bits don't use any probabilities.
820*cf5a6c84SAndroid Build Coastguard Worker *
821*cf5a6c84SAndroid Build Coastguard Worker * The distance slot value of 14 is for distances 128-191.
822*cf5a6c84SAndroid Build Coastguard Worker */
823*cf5a6c84SAndroid Build Coastguard Worker #define DIST_MODEL_END 14
824*cf5a6c84SAndroid Build Coastguard Worker
825*cf5a6c84SAndroid Build Coastguard Worker /* Distance slots that indicate a distance <= 127. */
826*cf5a6c84SAndroid Build Coastguard Worker #define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)
827*cf5a6c84SAndroid Build Coastguard Worker #define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
828*cf5a6c84SAndroid Build Coastguard Worker
829*cf5a6c84SAndroid Build Coastguard Worker /*
830*cf5a6c84SAndroid Build Coastguard Worker * For match distances greater than 127, only the highest two bits and the
831*cf5a6c84SAndroid Build Coastguard Worker * lowest four bits (alignment) is encoded using probabilities.
832*cf5a6c84SAndroid Build Coastguard Worker */
833*cf5a6c84SAndroid Build Coastguard Worker #define ALIGN_BITS 4
834*cf5a6c84SAndroid Build Coastguard Worker #define ALIGN_SIZE (1 << ALIGN_BITS)
835*cf5a6c84SAndroid Build Coastguard Worker #define ALIGN_MASK (ALIGN_SIZE - 1)
836*cf5a6c84SAndroid Build Coastguard Worker
837*cf5a6c84SAndroid Build Coastguard Worker /* Total number of all probability variables */
838*cf5a6c84SAndroid Build Coastguard Worker #define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE)
839*cf5a6c84SAndroid Build Coastguard Worker
840*cf5a6c84SAndroid Build Coastguard Worker /*
841*cf5a6c84SAndroid Build Coastguard Worker * LZMA remembers the four most recent match distances. Reusing these
842*cf5a6c84SAndroid Build Coastguard Worker * distances tends to take less space than re-encoding the actual
843*cf5a6c84SAndroid Build Coastguard Worker * distance value.
844*cf5a6c84SAndroid Build Coastguard Worker */
845*cf5a6c84SAndroid Build Coastguard Worker #define REPS 4
846*cf5a6c84SAndroid Build Coastguard Worker
847*cf5a6c84SAndroid Build Coastguard Worker
848*cf5a6c84SAndroid Build Coastguard Worker // END xz_lzma2.h
849*cf5a6c84SAndroid Build Coastguard Worker
850*cf5a6c84SAndroid Build Coastguard Worker /*
851*cf5a6c84SAndroid Build Coastguard Worker * Range decoder initialization eats the first five bytes of each LZMA chunk.
852*cf5a6c84SAndroid Build Coastguard Worker */
853*cf5a6c84SAndroid Build Coastguard Worker #define RC_INIT_BYTES 5
854*cf5a6c84SAndroid Build Coastguard Worker
855*cf5a6c84SAndroid Build Coastguard Worker /*
856*cf5a6c84SAndroid Build Coastguard Worker * Minimum number of usable input buffer to safely decode one LZMA symbol.
857*cf5a6c84SAndroid Build Coastguard Worker * The worst case is that we decode 22 bits using probabilities and 26
858*cf5a6c84SAndroid Build Coastguard Worker * direct bits. This may decode at maximum of 20 bytes of input. However,
859*cf5a6c84SAndroid Build Coastguard Worker * lzma_main() does an extra normalization before returning, thus we
860*cf5a6c84SAndroid Build Coastguard Worker * need to put 21 here.
861*cf5a6c84SAndroid Build Coastguard Worker */
862*cf5a6c84SAndroid Build Coastguard Worker #define LZMA_IN_REQUIRED 21
863*cf5a6c84SAndroid Build Coastguard Worker
864*cf5a6c84SAndroid Build Coastguard Worker /*
865*cf5a6c84SAndroid Build Coastguard Worker * Dictionary (history buffer)
866*cf5a6c84SAndroid Build Coastguard Worker *
867*cf5a6c84SAndroid Build Coastguard Worker * These are always true:
868*cf5a6c84SAndroid Build Coastguard Worker * start <= pos <= full <= end
869*cf5a6c84SAndroid Build Coastguard Worker * pos <= limit <= end
870*cf5a6c84SAndroid Build Coastguard Worker * end == size
871*cf5a6c84SAndroid Build Coastguard Worker * size <= size_max
872*cf5a6c84SAndroid Build Coastguard Worker * allocated <= size
873*cf5a6c84SAndroid Build Coastguard Worker *
874*cf5a6c84SAndroid Build Coastguard Worker * Most of these variables are size_t as a relic of single-call mode,
875*cf5a6c84SAndroid Build Coastguard Worker * in which the dictionary variables address the actual output
876*cf5a6c84SAndroid Build Coastguard Worker * buffer directly.
877*cf5a6c84SAndroid Build Coastguard Worker */
878*cf5a6c84SAndroid Build Coastguard Worker struct dictionary {
879*cf5a6c84SAndroid Build Coastguard Worker // Beginning of the history buffer
880*cf5a6c84SAndroid Build Coastguard Worker char *buf;
881*cf5a6c84SAndroid Build Coastguard Worker // Old position in buf (before decoding more data)
882*cf5a6c84SAndroid Build Coastguard Worker size_t start;
883*cf5a6c84SAndroid Build Coastguard Worker // Position in buf
884*cf5a6c84SAndroid Build Coastguard Worker size_t pos;
885*cf5a6c84SAndroid Build Coastguard Worker // How full dictionary is. This is used to detect corrupt input that
886*cf5a6c84SAndroid Build Coastguard Worker // would read beyond the beginning of the uncompressed stream.
887*cf5a6c84SAndroid Build Coastguard Worker size_t full;
888*cf5a6c84SAndroid Build Coastguard Worker /* Write limit; we don't write to buf[limit] or later bytes. */
889*cf5a6c84SAndroid Build Coastguard Worker size_t limit;
890*cf5a6c84SAndroid Build Coastguard Worker // End of the dictionary buffer. This is the same as the dictionary size.
891*cf5a6c84SAndroid Build Coastguard Worker size_t end;
892*cf5a6c84SAndroid Build Coastguard Worker // Size of the dictionary as specified in Block Header. This is used
893*cf5a6c84SAndroid Build Coastguard Worker // together with "full" to detect corrupt input that would make us
894*cf5a6c84SAndroid Build Coastguard Worker // read beyond the beginning of the uncompressed stream.
895*cf5a6c84SAndroid Build Coastguard Worker unsigned size;
896*cf5a6c84SAndroid Build Coastguard Worker // Maximum allowed dictionary size.
897*cf5a6c84SAndroid Build Coastguard Worker unsigned size_max;
898*cf5a6c84SAndroid Build Coastguard Worker // Amount of memory currently allocated for the dictionary.
899*cf5a6c84SAndroid Build Coastguard Worker unsigned allocated;
900*cf5a6c84SAndroid Build Coastguard Worker };
901*cf5a6c84SAndroid Build Coastguard Worker
902*cf5a6c84SAndroid Build Coastguard Worker /* Range decoder */
903*cf5a6c84SAndroid Build Coastguard Worker struct rc_dec {
904*cf5a6c84SAndroid Build Coastguard Worker unsigned range;
905*cf5a6c84SAndroid Build Coastguard Worker unsigned code;
906*cf5a6c84SAndroid Build Coastguard Worker
907*cf5a6c84SAndroid Build Coastguard Worker /*
908*cf5a6c84SAndroid Build Coastguard Worker * Number of initializing bytes remaining to be read
909*cf5a6c84SAndroid Build Coastguard Worker * by rc_read_init().
910*cf5a6c84SAndroid Build Coastguard Worker */
911*cf5a6c84SAndroid Build Coastguard Worker unsigned init_bytes_left;
912*cf5a6c84SAndroid Build Coastguard Worker
913*cf5a6c84SAndroid Build Coastguard Worker /*
914*cf5a6c84SAndroid Build Coastguard Worker * Buffer from which we read our input. It can be either
915*cf5a6c84SAndroid Build Coastguard Worker * temp.buf or the caller-provided input buffer.
916*cf5a6c84SAndroid Build Coastguard Worker */
917*cf5a6c84SAndroid Build Coastguard Worker const char *in;
918*cf5a6c84SAndroid Build Coastguard Worker size_t in_pos;
919*cf5a6c84SAndroid Build Coastguard Worker size_t in_limit;
920*cf5a6c84SAndroid Build Coastguard Worker };
921*cf5a6c84SAndroid Build Coastguard Worker
922*cf5a6c84SAndroid Build Coastguard Worker /* Probabilities for a length decoder. */
923*cf5a6c84SAndroid Build Coastguard Worker struct lzma_len_dec {
924*cf5a6c84SAndroid Build Coastguard Worker /* Probability of match length being at least 10 */
925*cf5a6c84SAndroid Build Coastguard Worker uint16_t choice;
926*cf5a6c84SAndroid Build Coastguard Worker
927*cf5a6c84SAndroid Build Coastguard Worker /* Probability of match length being at least 18 */
928*cf5a6c84SAndroid Build Coastguard Worker uint16_t choice2;
929*cf5a6c84SAndroid Build Coastguard Worker
930*cf5a6c84SAndroid Build Coastguard Worker /* Probabilities for match lengths 2-9 */
931*cf5a6c84SAndroid Build Coastguard Worker uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
932*cf5a6c84SAndroid Build Coastguard Worker
933*cf5a6c84SAndroid Build Coastguard Worker /* Probabilities for match lengths 10-17 */
934*cf5a6c84SAndroid Build Coastguard Worker uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
935*cf5a6c84SAndroid Build Coastguard Worker
936*cf5a6c84SAndroid Build Coastguard Worker /* Probabilities for match lengths 18-273 */
937*cf5a6c84SAndroid Build Coastguard Worker uint16_t high[LEN_HIGH_SYMBOLS];
938*cf5a6c84SAndroid Build Coastguard Worker };
939*cf5a6c84SAndroid Build Coastguard Worker
940*cf5a6c84SAndroid Build Coastguard Worker struct lzma_dec {
941*cf5a6c84SAndroid Build Coastguard Worker /* Distances of latest four matches */
942*cf5a6c84SAndroid Build Coastguard Worker unsigned rep0;
943*cf5a6c84SAndroid Build Coastguard Worker unsigned rep1;
944*cf5a6c84SAndroid Build Coastguard Worker unsigned rep2;
945*cf5a6c84SAndroid Build Coastguard Worker unsigned rep3;
946*cf5a6c84SAndroid Build Coastguard Worker
947*cf5a6c84SAndroid Build Coastguard Worker /* Types of the most recently seen LZMA symbols */
948*cf5a6c84SAndroid Build Coastguard Worker enum lzma_state state;
949*cf5a6c84SAndroid Build Coastguard Worker
950*cf5a6c84SAndroid Build Coastguard Worker /*
951*cf5a6c84SAndroid Build Coastguard Worker * Length of a match. This is updated so that dict_repeat can
952*cf5a6c84SAndroid Build Coastguard Worker * be called again to finish repeating the whole match.
953*cf5a6c84SAndroid Build Coastguard Worker */
954*cf5a6c84SAndroid Build Coastguard Worker unsigned len;
955*cf5a6c84SAndroid Build Coastguard Worker
956*cf5a6c84SAndroid Build Coastguard Worker /*
957*cf5a6c84SAndroid Build Coastguard Worker * LZMA properties or related bit masks (number of literal
958*cf5a6c84SAndroid Build Coastguard Worker * context bits, a mask dervied from the number of literal
959*cf5a6c84SAndroid Build Coastguard Worker * position bits, and a mask dervied from the number
960*cf5a6c84SAndroid Build Coastguard Worker * position bits)
961*cf5a6c84SAndroid Build Coastguard Worker */
962*cf5a6c84SAndroid Build Coastguard Worker unsigned lc;
963*cf5a6c84SAndroid Build Coastguard Worker unsigned literal_pos_mask; /* (1 << lp) - 1 */
964*cf5a6c84SAndroid Build Coastguard Worker unsigned pos_mask; /* (1 << pb) - 1 */
965*cf5a6c84SAndroid Build Coastguard Worker
966*cf5a6c84SAndroid Build Coastguard Worker /* If 1, it's a match. Otherwise it's a single 8-bit literal. */
967*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_match[STATES][POS_STATES_MAX];
968*cf5a6c84SAndroid Build Coastguard Worker
969*cf5a6c84SAndroid Build Coastguard Worker /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
970*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_rep[STATES];
971*cf5a6c84SAndroid Build Coastguard Worker
972*cf5a6c84SAndroid Build Coastguard Worker /*
973*cf5a6c84SAndroid Build Coastguard Worker * If 0, distance of a repeated match is rep0.
974*cf5a6c84SAndroid Build Coastguard Worker * Otherwise check is_rep1.
975*cf5a6c84SAndroid Build Coastguard Worker */
976*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_rep0[STATES];
977*cf5a6c84SAndroid Build Coastguard Worker
978*cf5a6c84SAndroid Build Coastguard Worker /*
979*cf5a6c84SAndroid Build Coastguard Worker * If 0, distance of a repeated match is rep1.
980*cf5a6c84SAndroid Build Coastguard Worker * Otherwise check is_rep2.
981*cf5a6c84SAndroid Build Coastguard Worker */
982*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_rep1[STATES];
983*cf5a6c84SAndroid Build Coastguard Worker
984*cf5a6c84SAndroid Build Coastguard Worker /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
985*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_rep2[STATES];
986*cf5a6c84SAndroid Build Coastguard Worker
987*cf5a6c84SAndroid Build Coastguard Worker /*
988*cf5a6c84SAndroid Build Coastguard Worker * If 1, the repeated match has length of one byte. Otherwise
989*cf5a6c84SAndroid Build Coastguard Worker * the length is decoded from rep_len_decoder.
990*cf5a6c84SAndroid Build Coastguard Worker */
991*cf5a6c84SAndroid Build Coastguard Worker uint16_t is_rep0_long[STATES][POS_STATES_MAX];
992*cf5a6c84SAndroid Build Coastguard Worker
993*cf5a6c84SAndroid Build Coastguard Worker /*
994*cf5a6c84SAndroid Build Coastguard Worker * Probability tree for the highest two bits of the match
995*cf5a6c84SAndroid Build Coastguard Worker * distance. There is a separate probability tree for match
996*cf5a6c84SAndroid Build Coastguard Worker * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
997*cf5a6c84SAndroid Build Coastguard Worker */
998*cf5a6c84SAndroid Build Coastguard Worker uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
999*cf5a6c84SAndroid Build Coastguard Worker
1000*cf5a6c84SAndroid Build Coastguard Worker /*
1001*cf5a6c84SAndroid Build Coastguard Worker * Probility trees for additional bits for match distance
1002*cf5a6c84SAndroid Build Coastguard Worker * when the distance is in the range [4, 127].
1003*cf5a6c84SAndroid Build Coastguard Worker */
1004*cf5a6c84SAndroid Build Coastguard Worker uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
1005*cf5a6c84SAndroid Build Coastguard Worker
1006*cf5a6c84SAndroid Build Coastguard Worker /*
1007*cf5a6c84SAndroid Build Coastguard Worker * Probability tree for the lowest four bits of a match
1008*cf5a6c84SAndroid Build Coastguard Worker * distance that is equal to or greater than 128.
1009*cf5a6c84SAndroid Build Coastguard Worker */
1010*cf5a6c84SAndroid Build Coastguard Worker uint16_t dist_align[ALIGN_SIZE];
1011*cf5a6c84SAndroid Build Coastguard Worker
1012*cf5a6c84SAndroid Build Coastguard Worker /* Length of a normal match */
1013*cf5a6c84SAndroid Build Coastguard Worker struct lzma_len_dec match_len_dec;
1014*cf5a6c84SAndroid Build Coastguard Worker
1015*cf5a6c84SAndroid Build Coastguard Worker /* Length of a repeated match */
1016*cf5a6c84SAndroid Build Coastguard Worker struct lzma_len_dec rep_len_dec;
1017*cf5a6c84SAndroid Build Coastguard Worker
1018*cf5a6c84SAndroid Build Coastguard Worker /* Probabilities of literals */
1019*cf5a6c84SAndroid Build Coastguard Worker uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
1020*cf5a6c84SAndroid Build Coastguard Worker };
1021*cf5a6c84SAndroid Build Coastguard Worker
1022*cf5a6c84SAndroid Build Coastguard Worker struct lzma2_dec {
1023*cf5a6c84SAndroid Build Coastguard Worker /* Position in xz_dec_lzma2_run(). */
1024*cf5a6c84SAndroid Build Coastguard Worker enum lzma2_seq {
1025*cf5a6c84SAndroid Build Coastguard Worker SEQ_CONTROL,
1026*cf5a6c84SAndroid Build Coastguard Worker SEQ_UNCOMPRESSED_1,
1027*cf5a6c84SAndroid Build Coastguard Worker SEQ_UNCOMPRESSED_2,
1028*cf5a6c84SAndroid Build Coastguard Worker SEQ_COMPRESSED_0,
1029*cf5a6c84SAndroid Build Coastguard Worker SEQ_COMPRESSED_1,
1030*cf5a6c84SAndroid Build Coastguard Worker SEQ_PROPERTIES,
1031*cf5a6c84SAndroid Build Coastguard Worker SEQ_LZMA_PREPARE,
1032*cf5a6c84SAndroid Build Coastguard Worker SEQ_LZMA_RUN,
1033*cf5a6c84SAndroid Build Coastguard Worker SEQ_COPY
1034*cf5a6c84SAndroid Build Coastguard Worker } sequence;
1035*cf5a6c84SAndroid Build Coastguard Worker
1036*cf5a6c84SAndroid Build Coastguard Worker /* Next position after decoding the compressed size of the chunk. */
1037*cf5a6c84SAndroid Build Coastguard Worker enum lzma2_seq next_sequence;
1038*cf5a6c84SAndroid Build Coastguard Worker
1039*cf5a6c84SAndroid Build Coastguard Worker /* Uncompressed size of LZMA chunk (2 MiB at maximum) */
1040*cf5a6c84SAndroid Build Coastguard Worker unsigned uncompressed;
1041*cf5a6c84SAndroid Build Coastguard Worker
1042*cf5a6c84SAndroid Build Coastguard Worker /*
1043*cf5a6c84SAndroid Build Coastguard Worker * Compressed size of LZMA chunk or compressed/uncompressed
1044*cf5a6c84SAndroid Build Coastguard Worker * size of uncompressed chunk (64 KiB at maximum)
1045*cf5a6c84SAndroid Build Coastguard Worker */
1046*cf5a6c84SAndroid Build Coastguard Worker unsigned compressed;
1047*cf5a6c84SAndroid Build Coastguard Worker
1048*cf5a6c84SAndroid Build Coastguard Worker /*
1049*cf5a6c84SAndroid Build Coastguard Worker * True if dictionary reset is needed. This is false before
1050*cf5a6c84SAndroid Build Coastguard Worker * the first chunk (LZMA or uncompressed).
1051*cf5a6c84SAndroid Build Coastguard Worker */
1052*cf5a6c84SAndroid Build Coastguard Worker int need_dict_reset;
1053*cf5a6c84SAndroid Build Coastguard Worker
1054*cf5a6c84SAndroid Build Coastguard Worker /*
1055*cf5a6c84SAndroid Build Coastguard Worker * True if new LZMA properties are needed. This is false
1056*cf5a6c84SAndroid Build Coastguard Worker * before the first LZMA chunk.
1057*cf5a6c84SAndroid Build Coastguard Worker */
1058*cf5a6c84SAndroid Build Coastguard Worker int need_props;
1059*cf5a6c84SAndroid Build Coastguard Worker };
1060*cf5a6c84SAndroid Build Coastguard Worker
1061*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_lzma2 {
1062*cf5a6c84SAndroid Build Coastguard Worker /*
1063*cf5a6c84SAndroid Build Coastguard Worker * The order below is important on x86 to reduce code size and
1064*cf5a6c84SAndroid Build Coastguard Worker * it shouldn't hurt on other platforms. Everything up to and
1065*cf5a6c84SAndroid Build Coastguard Worker * including lzma.pos_mask are in the first 128 bytes on x86-32,
1066*cf5a6c84SAndroid Build Coastguard Worker * which allows using smaller instructions to access those
1067*cf5a6c84SAndroid Build Coastguard Worker * variables. On x86-64, fewer variables fit into the first 128
1068*cf5a6c84SAndroid Build Coastguard Worker * bytes, but this is still the best order without sacrificing
1069*cf5a6c84SAndroid Build Coastguard Worker * the readability by splitting the structures.
1070*cf5a6c84SAndroid Build Coastguard Worker */
1071*cf5a6c84SAndroid Build Coastguard Worker struct rc_dec rc;
1072*cf5a6c84SAndroid Build Coastguard Worker struct dictionary dict;
1073*cf5a6c84SAndroid Build Coastguard Worker struct lzma2_dec lzma2;
1074*cf5a6c84SAndroid Build Coastguard Worker struct lzma_dec lzma;
1075*cf5a6c84SAndroid Build Coastguard Worker
1076*cf5a6c84SAndroid Build Coastguard Worker /*
1077*cf5a6c84SAndroid Build Coastguard Worker * Temporary buffer which holds small number of input bytes between
1078*cf5a6c84SAndroid Build Coastguard Worker * decoder calls. See lzma2_lzma() for details.
1079*cf5a6c84SAndroid Build Coastguard Worker */
1080*cf5a6c84SAndroid Build Coastguard Worker struct {
1081*cf5a6c84SAndroid Build Coastguard Worker unsigned size;
1082*cf5a6c84SAndroid Build Coastguard Worker char buf[3 * LZMA_IN_REQUIRED];
1083*cf5a6c84SAndroid Build Coastguard Worker } temp;
1084*cf5a6c84SAndroid Build Coastguard Worker };
1085*cf5a6c84SAndroid Build Coastguard Worker
1086*cf5a6c84SAndroid Build Coastguard Worker /**************
1087*cf5a6c84SAndroid Build Coastguard Worker * Dictionary *
1088*cf5a6c84SAndroid Build Coastguard Worker **************/
1089*cf5a6c84SAndroid Build Coastguard Worker
1090*cf5a6c84SAndroid Build Coastguard Worker /* Reset the dictionary state. */
dict_reset(struct dictionary * dict)1091*cf5a6c84SAndroid Build Coastguard Worker static void dict_reset(struct dictionary *dict)
1092*cf5a6c84SAndroid Build Coastguard Worker {
1093*cf5a6c84SAndroid Build Coastguard Worker dict->start = 0;
1094*cf5a6c84SAndroid Build Coastguard Worker dict->pos = 0;
1095*cf5a6c84SAndroid Build Coastguard Worker dict->limit = 0;
1096*cf5a6c84SAndroid Build Coastguard Worker dict->full = 0;
1097*cf5a6c84SAndroid Build Coastguard Worker }
1098*cf5a6c84SAndroid Build Coastguard Worker
1099*cf5a6c84SAndroid Build Coastguard Worker /* Set dictionary write limit */
dict_limit(struct dictionary * dict,size_t out_max)1100*cf5a6c84SAndroid Build Coastguard Worker static void dict_limit(struct dictionary *dict, size_t out_max)
1101*cf5a6c84SAndroid Build Coastguard Worker {
1102*cf5a6c84SAndroid Build Coastguard Worker if (dict->end - dict->pos <= out_max)
1103*cf5a6c84SAndroid Build Coastguard Worker dict->limit = dict->end;
1104*cf5a6c84SAndroid Build Coastguard Worker else
1105*cf5a6c84SAndroid Build Coastguard Worker dict->limit = dict->pos + out_max;
1106*cf5a6c84SAndroid Build Coastguard Worker }
1107*cf5a6c84SAndroid Build Coastguard Worker
1108*cf5a6c84SAndroid Build Coastguard Worker /* Return true if at least one byte can be written into the dictionary. */
dict_has_space(const struct dictionary * dict)1109*cf5a6c84SAndroid Build Coastguard Worker static int dict_has_space(const struct dictionary *dict)
1110*cf5a6c84SAndroid Build Coastguard Worker {
1111*cf5a6c84SAndroid Build Coastguard Worker return dict->pos < dict->limit;
1112*cf5a6c84SAndroid Build Coastguard Worker }
1113*cf5a6c84SAndroid Build Coastguard Worker
1114*cf5a6c84SAndroid Build Coastguard Worker /*
1115*cf5a6c84SAndroid Build Coastguard Worker * Get a byte from the dictionary at the given distance. The distance is
1116*cf5a6c84SAndroid Build Coastguard Worker * assumed to valid, or as a special case, zero when the dictionary is
1117*cf5a6c84SAndroid Build Coastguard Worker * still empty. This special case is needed for single-call decoding to
1118*cf5a6c84SAndroid Build Coastguard Worker * avoid writing a '\0' to the end of the destination buffer.
1119*cf5a6c84SAndroid Build Coastguard Worker */
dict_get(const struct dictionary * dict,unsigned dist)1120*cf5a6c84SAndroid Build Coastguard Worker static unsigned dict_get(const struct dictionary *dict, unsigned dist)
1121*cf5a6c84SAndroid Build Coastguard Worker {
1122*cf5a6c84SAndroid Build Coastguard Worker size_t offset = dict->pos - dist - 1;
1123*cf5a6c84SAndroid Build Coastguard Worker
1124*cf5a6c84SAndroid Build Coastguard Worker if (dist >= dict->pos)
1125*cf5a6c84SAndroid Build Coastguard Worker offset += dict->end;
1126*cf5a6c84SAndroid Build Coastguard Worker
1127*cf5a6c84SAndroid Build Coastguard Worker return dict->full > 0 ? dict->buf[offset] : 0;
1128*cf5a6c84SAndroid Build Coastguard Worker }
1129*cf5a6c84SAndroid Build Coastguard Worker
1130*cf5a6c84SAndroid Build Coastguard Worker /*
1131*cf5a6c84SAndroid Build Coastguard Worker * Put one byte into the dictionary. It is assumed that there is space for it.
1132*cf5a6c84SAndroid Build Coastguard Worker */
dict_put(struct dictionary * dict,char byte)1133*cf5a6c84SAndroid Build Coastguard Worker static void dict_put(struct dictionary *dict, char byte)
1134*cf5a6c84SAndroid Build Coastguard Worker {
1135*cf5a6c84SAndroid Build Coastguard Worker dict->buf[dict->pos++] = byte;
1136*cf5a6c84SAndroid Build Coastguard Worker
1137*cf5a6c84SAndroid Build Coastguard Worker if (dict->full < dict->pos)
1138*cf5a6c84SAndroid Build Coastguard Worker dict->full = dict->pos;
1139*cf5a6c84SAndroid Build Coastguard Worker }
1140*cf5a6c84SAndroid Build Coastguard Worker
1141*cf5a6c84SAndroid Build Coastguard Worker /*
1142*cf5a6c84SAndroid Build Coastguard Worker * Repeat given number of bytes from the given distance. If the distance is
1143*cf5a6c84SAndroid Build Coastguard Worker * invalid, false is returned. On success, true is returned and *len is
1144*cf5a6c84SAndroid Build Coastguard Worker * updated to indicate how many bytes were left to be repeated.
1145*cf5a6c84SAndroid Build Coastguard Worker */
dict_repeat(struct dictionary * dict,unsigned * len,unsigned dist)1146*cf5a6c84SAndroid Build Coastguard Worker static int dict_repeat(struct dictionary *dict, unsigned *len, unsigned dist)
1147*cf5a6c84SAndroid Build Coastguard Worker {
1148*cf5a6c84SAndroid Build Coastguard Worker size_t back;
1149*cf5a6c84SAndroid Build Coastguard Worker unsigned left;
1150*cf5a6c84SAndroid Build Coastguard Worker
1151*cf5a6c84SAndroid Build Coastguard Worker if (dist >= dict->full || dist >= dict->size) return 0;
1152*cf5a6c84SAndroid Build Coastguard Worker
1153*cf5a6c84SAndroid Build Coastguard Worker left = minof(dict->limit - dict->pos, *len);
1154*cf5a6c84SAndroid Build Coastguard Worker *len -= left;
1155*cf5a6c84SAndroid Build Coastguard Worker
1156*cf5a6c84SAndroid Build Coastguard Worker back = dict->pos - dist - 1;
1157*cf5a6c84SAndroid Build Coastguard Worker if (dist >= dict->pos)
1158*cf5a6c84SAndroid Build Coastguard Worker back += dict->end;
1159*cf5a6c84SAndroid Build Coastguard Worker
1160*cf5a6c84SAndroid Build Coastguard Worker do {
1161*cf5a6c84SAndroid Build Coastguard Worker dict->buf[dict->pos++] = dict->buf[back++];
1162*cf5a6c84SAndroid Build Coastguard Worker if (back == dict->end)
1163*cf5a6c84SAndroid Build Coastguard Worker back = 0;
1164*cf5a6c84SAndroid Build Coastguard Worker } while (--left > 0);
1165*cf5a6c84SAndroid Build Coastguard Worker
1166*cf5a6c84SAndroid Build Coastguard Worker if (dict->full < dict->pos)
1167*cf5a6c84SAndroid Build Coastguard Worker dict->full = dict->pos;
1168*cf5a6c84SAndroid Build Coastguard Worker
1169*cf5a6c84SAndroid Build Coastguard Worker return 1;
1170*cf5a6c84SAndroid Build Coastguard Worker }
1171*cf5a6c84SAndroid Build Coastguard Worker
1172*cf5a6c84SAndroid Build Coastguard Worker /* Copy uncompressed data as is from input to dictionary and output buffers. */
dict_uncompressed(struct dictionary * dict,struct xz_buf * b,unsigned * left)1173*cf5a6c84SAndroid Build Coastguard Worker static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
1174*cf5a6c84SAndroid Build Coastguard Worker unsigned *left)
1175*cf5a6c84SAndroid Build Coastguard Worker {
1176*cf5a6c84SAndroid Build Coastguard Worker size_t copy_size;
1177*cf5a6c84SAndroid Build Coastguard Worker
1178*cf5a6c84SAndroid Build Coastguard Worker while (*left > 0 && b->in_pos < b->in_size
1179*cf5a6c84SAndroid Build Coastguard Worker && b->out_pos < b->out_size) {
1180*cf5a6c84SAndroid Build Coastguard Worker copy_size = minof(b->in_size - b->in_pos,
1181*cf5a6c84SAndroid Build Coastguard Worker b->out_size - b->out_pos);
1182*cf5a6c84SAndroid Build Coastguard Worker if (copy_size > dict->end - dict->pos)
1183*cf5a6c84SAndroid Build Coastguard Worker copy_size = dict->end - dict->pos;
1184*cf5a6c84SAndroid Build Coastguard Worker if (copy_size > *left)
1185*cf5a6c84SAndroid Build Coastguard Worker copy_size = *left;
1186*cf5a6c84SAndroid Build Coastguard Worker
1187*cf5a6c84SAndroid Build Coastguard Worker *left -= copy_size;
1188*cf5a6c84SAndroid Build Coastguard Worker
1189*cf5a6c84SAndroid Build Coastguard Worker memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
1190*cf5a6c84SAndroid Build Coastguard Worker dict->pos += copy_size;
1191*cf5a6c84SAndroid Build Coastguard Worker
1192*cf5a6c84SAndroid Build Coastguard Worker if (dict->full < dict->pos)
1193*cf5a6c84SAndroid Build Coastguard Worker dict->full = dict->pos;
1194*cf5a6c84SAndroid Build Coastguard Worker
1195*cf5a6c84SAndroid Build Coastguard Worker if (dict->pos == dict->end)
1196*cf5a6c84SAndroid Build Coastguard Worker dict->pos = 0;
1197*cf5a6c84SAndroid Build Coastguard Worker
1198*cf5a6c84SAndroid Build Coastguard Worker memcpy(b->out + b->out_pos, b->in + b->in_pos,
1199*cf5a6c84SAndroid Build Coastguard Worker copy_size);
1200*cf5a6c84SAndroid Build Coastguard Worker
1201*cf5a6c84SAndroid Build Coastguard Worker dict->start = dict->pos;
1202*cf5a6c84SAndroid Build Coastguard Worker
1203*cf5a6c84SAndroid Build Coastguard Worker b->out_pos += copy_size;
1204*cf5a6c84SAndroid Build Coastguard Worker b->in_pos += copy_size;
1205*cf5a6c84SAndroid Build Coastguard Worker }
1206*cf5a6c84SAndroid Build Coastguard Worker }
1207*cf5a6c84SAndroid Build Coastguard Worker
1208*cf5a6c84SAndroid Build Coastguard Worker /*
1209*cf5a6c84SAndroid Build Coastguard Worker * Flush pending data from dictionary to b->out. It is assumed that there is
1210*cf5a6c84SAndroid Build Coastguard Worker * enough space in b->out. This is guaranteed because caller uses dict_limit()
1211*cf5a6c84SAndroid Build Coastguard Worker * before decoding data into the dictionary.
1212*cf5a6c84SAndroid Build Coastguard Worker */
dict_flush(struct dictionary * dict,struct xz_buf * b)1213*cf5a6c84SAndroid Build Coastguard Worker static unsigned dict_flush(struct dictionary *dict, struct xz_buf *b)
1214*cf5a6c84SAndroid Build Coastguard Worker {
1215*cf5a6c84SAndroid Build Coastguard Worker size_t copy_size = dict->pos - dict->start;
1216*cf5a6c84SAndroid Build Coastguard Worker
1217*cf5a6c84SAndroid Build Coastguard Worker if (dict->pos == dict->end)
1218*cf5a6c84SAndroid Build Coastguard Worker dict->pos = 0;
1219*cf5a6c84SAndroid Build Coastguard Worker
1220*cf5a6c84SAndroid Build Coastguard Worker memcpy(b->out + b->out_pos, dict->buf + dict->start,
1221*cf5a6c84SAndroid Build Coastguard Worker copy_size);
1222*cf5a6c84SAndroid Build Coastguard Worker
1223*cf5a6c84SAndroid Build Coastguard Worker dict->start = dict->pos;
1224*cf5a6c84SAndroid Build Coastguard Worker b->out_pos += copy_size;
1225*cf5a6c84SAndroid Build Coastguard Worker return copy_size;
1226*cf5a6c84SAndroid Build Coastguard Worker }
1227*cf5a6c84SAndroid Build Coastguard Worker
1228*cf5a6c84SAndroid Build Coastguard Worker /*****************
1229*cf5a6c84SAndroid Build Coastguard Worker * Range decoder *
1230*cf5a6c84SAndroid Build Coastguard Worker *****************/
1231*cf5a6c84SAndroid Build Coastguard Worker
1232*cf5a6c84SAndroid Build Coastguard Worker /* Reset the range decoder. */
rc_reset(struct rc_dec * rc)1233*cf5a6c84SAndroid Build Coastguard Worker static void rc_reset(struct rc_dec *rc)
1234*cf5a6c84SAndroid Build Coastguard Worker {
1235*cf5a6c84SAndroid Build Coastguard Worker rc->range = (unsigned)-1;
1236*cf5a6c84SAndroid Build Coastguard Worker rc->code = 0;
1237*cf5a6c84SAndroid Build Coastguard Worker rc->init_bytes_left = RC_INIT_BYTES;
1238*cf5a6c84SAndroid Build Coastguard Worker }
1239*cf5a6c84SAndroid Build Coastguard Worker
1240*cf5a6c84SAndroid Build Coastguard Worker /*
1241*cf5a6c84SAndroid Build Coastguard Worker * Read the first five initial bytes into rc->code if they haven't been
1242*cf5a6c84SAndroid Build Coastguard Worker * read already. (Yes, the first byte gets completely ignored.)
1243*cf5a6c84SAndroid Build Coastguard Worker */
rc_read_init(struct rc_dec * rc,struct xz_buf * b)1244*cf5a6c84SAndroid Build Coastguard Worker static int rc_read_init(struct rc_dec *rc, struct xz_buf *b)
1245*cf5a6c84SAndroid Build Coastguard Worker {
1246*cf5a6c84SAndroid Build Coastguard Worker while (rc->init_bytes_left > 0) {
1247*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size) return 0;
1248*cf5a6c84SAndroid Build Coastguard Worker
1249*cf5a6c84SAndroid Build Coastguard Worker rc->code = (rc->code << 8) + b->in[b->in_pos++];
1250*cf5a6c84SAndroid Build Coastguard Worker --rc->init_bytes_left;
1251*cf5a6c84SAndroid Build Coastguard Worker }
1252*cf5a6c84SAndroid Build Coastguard Worker
1253*cf5a6c84SAndroid Build Coastguard Worker return 1;
1254*cf5a6c84SAndroid Build Coastguard Worker }
1255*cf5a6c84SAndroid Build Coastguard Worker
1256*cf5a6c84SAndroid Build Coastguard Worker /* Return true if there may not be enough input for the next decoding loop. */
rc_limit_exceeded(const struct rc_dec * rc)1257*cf5a6c84SAndroid Build Coastguard Worker static int rc_limit_exceeded(const struct rc_dec *rc)
1258*cf5a6c84SAndroid Build Coastguard Worker {
1259*cf5a6c84SAndroid Build Coastguard Worker return rc->in_pos > rc->in_limit;
1260*cf5a6c84SAndroid Build Coastguard Worker }
1261*cf5a6c84SAndroid Build Coastguard Worker
1262*cf5a6c84SAndroid Build Coastguard Worker /* Read the next input byte if needed. */
rc_normalize(struct rc_dec * rc)1263*cf5a6c84SAndroid Build Coastguard Worker static void rc_normalize(struct rc_dec *rc)
1264*cf5a6c84SAndroid Build Coastguard Worker {
1265*cf5a6c84SAndroid Build Coastguard Worker if (rc->range < RC_TOP_VALUE) {
1266*cf5a6c84SAndroid Build Coastguard Worker rc->range <<= RC_SHIFT_BITS;
1267*cf5a6c84SAndroid Build Coastguard Worker rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
1268*cf5a6c84SAndroid Build Coastguard Worker }
1269*cf5a6c84SAndroid Build Coastguard Worker }
1270*cf5a6c84SAndroid Build Coastguard Worker
1271*cf5a6c84SAndroid Build Coastguard Worker /*
1272*cf5a6c84SAndroid Build Coastguard Worker * Decode one bit. In some versions, this function has been splitted in three
1273*cf5a6c84SAndroid Build Coastguard Worker * functions so that the compiler is supposed to be able to more easily avoid
1274*cf5a6c84SAndroid Build Coastguard Worker * an extra branch. In this particular version of the LZMA decoder, this
1275*cf5a6c84SAndroid Build Coastguard Worker * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3
1276*cf5a6c84SAndroid Build Coastguard Worker * on x86). Using a non-splitted version results in nicer looking code too.
1277*cf5a6c84SAndroid Build Coastguard Worker *
1278*cf5a6c84SAndroid Build Coastguard Worker * NOTE: This must return an int. Do not make it return a bool or the speed
1279*cf5a6c84SAndroid Build Coastguard Worker * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care,
1280*cf5a6c84SAndroid Build Coastguard Worker * and it generates 10-20 % faster code than GCC 3.x from this file anyway.)
1281*cf5a6c84SAndroid Build Coastguard Worker */
rc_bit(struct rc_dec * rc,uint16_t * prob)1282*cf5a6c84SAndroid Build Coastguard Worker static int rc_bit(struct rc_dec *rc, uint16_t *prob)
1283*cf5a6c84SAndroid Build Coastguard Worker {
1284*cf5a6c84SAndroid Build Coastguard Worker unsigned bound;
1285*cf5a6c84SAndroid Build Coastguard Worker int bit;
1286*cf5a6c84SAndroid Build Coastguard Worker
1287*cf5a6c84SAndroid Build Coastguard Worker rc_normalize(rc);
1288*cf5a6c84SAndroid Build Coastguard Worker bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
1289*cf5a6c84SAndroid Build Coastguard Worker if (rc->code < bound) {
1290*cf5a6c84SAndroid Build Coastguard Worker rc->range = bound;
1291*cf5a6c84SAndroid Build Coastguard Worker *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
1292*cf5a6c84SAndroid Build Coastguard Worker bit = 0;
1293*cf5a6c84SAndroid Build Coastguard Worker } else {
1294*cf5a6c84SAndroid Build Coastguard Worker rc->range -= bound;
1295*cf5a6c84SAndroid Build Coastguard Worker rc->code -= bound;
1296*cf5a6c84SAndroid Build Coastguard Worker *prob -= *prob >> RC_MOVE_BITS;
1297*cf5a6c84SAndroid Build Coastguard Worker bit = 1;
1298*cf5a6c84SAndroid Build Coastguard Worker }
1299*cf5a6c84SAndroid Build Coastguard Worker
1300*cf5a6c84SAndroid Build Coastguard Worker return bit;
1301*cf5a6c84SAndroid Build Coastguard Worker }
1302*cf5a6c84SAndroid Build Coastguard Worker
1303*cf5a6c84SAndroid Build Coastguard Worker /* Decode a bittree starting from the most significant bit. */
rc_bittree(struct rc_dec * rc,uint16_t * probs,unsigned limit)1304*cf5a6c84SAndroid Build Coastguard Worker static unsigned rc_bittree(struct rc_dec *rc,
1305*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs, unsigned limit)
1306*cf5a6c84SAndroid Build Coastguard Worker {
1307*cf5a6c84SAndroid Build Coastguard Worker unsigned symbol = 1;
1308*cf5a6c84SAndroid Build Coastguard Worker
1309*cf5a6c84SAndroid Build Coastguard Worker do {
1310*cf5a6c84SAndroid Build Coastguard Worker if (rc_bit(rc, &probs[symbol]))
1311*cf5a6c84SAndroid Build Coastguard Worker symbol = (symbol << 1) + 1;
1312*cf5a6c84SAndroid Build Coastguard Worker else
1313*cf5a6c84SAndroid Build Coastguard Worker symbol <<= 1;
1314*cf5a6c84SAndroid Build Coastguard Worker } while (symbol < limit);
1315*cf5a6c84SAndroid Build Coastguard Worker
1316*cf5a6c84SAndroid Build Coastguard Worker return symbol;
1317*cf5a6c84SAndroid Build Coastguard Worker }
1318*cf5a6c84SAndroid Build Coastguard Worker
1319*cf5a6c84SAndroid Build Coastguard Worker /* Decode a bittree starting from the least significant bit. */
rc_bittree_reverse(struct rc_dec * rc,uint16_t * probs,unsigned * dest,unsigned limit)1320*cf5a6c84SAndroid Build Coastguard Worker static void rc_bittree_reverse(struct rc_dec *rc,
1321*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs,
1322*cf5a6c84SAndroid Build Coastguard Worker unsigned *dest, unsigned limit)
1323*cf5a6c84SAndroid Build Coastguard Worker {
1324*cf5a6c84SAndroid Build Coastguard Worker unsigned symbol = 1;
1325*cf5a6c84SAndroid Build Coastguard Worker unsigned i = 0;
1326*cf5a6c84SAndroid Build Coastguard Worker
1327*cf5a6c84SAndroid Build Coastguard Worker do {
1328*cf5a6c84SAndroid Build Coastguard Worker if (rc_bit(rc, &probs[symbol])) {
1329*cf5a6c84SAndroid Build Coastguard Worker symbol = (symbol << 1) + 1;
1330*cf5a6c84SAndroid Build Coastguard Worker *dest += 1 << i;
1331*cf5a6c84SAndroid Build Coastguard Worker } else {
1332*cf5a6c84SAndroid Build Coastguard Worker symbol <<= 1;
1333*cf5a6c84SAndroid Build Coastguard Worker }
1334*cf5a6c84SAndroid Build Coastguard Worker } while (++i < limit);
1335*cf5a6c84SAndroid Build Coastguard Worker }
1336*cf5a6c84SAndroid Build Coastguard Worker
1337*cf5a6c84SAndroid Build Coastguard Worker /* Decode direct bits (fixed fifty-fifty probability) */
rc_direct(struct rc_dec * rc,unsigned * dest,unsigned limit)1338*cf5a6c84SAndroid Build Coastguard Worker static void rc_direct(struct rc_dec *rc, unsigned *dest, unsigned limit)
1339*cf5a6c84SAndroid Build Coastguard Worker {
1340*cf5a6c84SAndroid Build Coastguard Worker unsigned mask;
1341*cf5a6c84SAndroid Build Coastguard Worker
1342*cf5a6c84SAndroid Build Coastguard Worker do {
1343*cf5a6c84SAndroid Build Coastguard Worker rc_normalize(rc);
1344*cf5a6c84SAndroid Build Coastguard Worker rc->range >>= 1;
1345*cf5a6c84SAndroid Build Coastguard Worker rc->code -= rc->range;
1346*cf5a6c84SAndroid Build Coastguard Worker mask = (unsigned)0 - (rc->code >> 31);
1347*cf5a6c84SAndroid Build Coastguard Worker rc->code += rc->range & mask;
1348*cf5a6c84SAndroid Build Coastguard Worker *dest = (*dest << 1) + (mask + 1);
1349*cf5a6c84SAndroid Build Coastguard Worker } while (--limit > 0);
1350*cf5a6c84SAndroid Build Coastguard Worker }
1351*cf5a6c84SAndroid Build Coastguard Worker
1352*cf5a6c84SAndroid Build Coastguard Worker /********
1353*cf5a6c84SAndroid Build Coastguard Worker * LZMA *
1354*cf5a6c84SAndroid Build Coastguard Worker ********/
1355*cf5a6c84SAndroid Build Coastguard Worker
1356*cf5a6c84SAndroid Build Coastguard Worker /* Get pointer to literal coder probability array. */
lzma_literal_probs(struct xz_dec_lzma2 * s)1357*cf5a6c84SAndroid Build Coastguard Worker static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
1358*cf5a6c84SAndroid Build Coastguard Worker {
1359*cf5a6c84SAndroid Build Coastguard Worker unsigned prev_byte = dict_get(&s->dict, 0);
1360*cf5a6c84SAndroid Build Coastguard Worker unsigned low = prev_byte >> (8 - s->lzma.lc);
1361*cf5a6c84SAndroid Build Coastguard Worker unsigned high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
1362*cf5a6c84SAndroid Build Coastguard Worker return s->lzma.literal[low + high];
1363*cf5a6c84SAndroid Build Coastguard Worker }
1364*cf5a6c84SAndroid Build Coastguard Worker
1365*cf5a6c84SAndroid Build Coastguard Worker /* Decode a literal (one 8-bit byte) */
lzma_literal(struct xz_dec_lzma2 * s)1366*cf5a6c84SAndroid Build Coastguard Worker static void lzma_literal(struct xz_dec_lzma2 *s)
1367*cf5a6c84SAndroid Build Coastguard Worker {
1368*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs;
1369*cf5a6c84SAndroid Build Coastguard Worker unsigned symbol;
1370*cf5a6c84SAndroid Build Coastguard Worker unsigned match_byte;
1371*cf5a6c84SAndroid Build Coastguard Worker unsigned match_bit;
1372*cf5a6c84SAndroid Build Coastguard Worker unsigned offset;
1373*cf5a6c84SAndroid Build Coastguard Worker unsigned i;
1374*cf5a6c84SAndroid Build Coastguard Worker
1375*cf5a6c84SAndroid Build Coastguard Worker probs = lzma_literal_probs(s);
1376*cf5a6c84SAndroid Build Coastguard Worker
1377*cf5a6c84SAndroid Build Coastguard Worker if (s->lzma.state < LIT_STATES) {
1378*cf5a6c84SAndroid Build Coastguard Worker symbol = rc_bittree(&s->rc, probs, 0x100);
1379*cf5a6c84SAndroid Build Coastguard Worker } else {
1380*cf5a6c84SAndroid Build Coastguard Worker symbol = 1;
1381*cf5a6c84SAndroid Build Coastguard Worker match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
1382*cf5a6c84SAndroid Build Coastguard Worker offset = 0x100;
1383*cf5a6c84SAndroid Build Coastguard Worker
1384*cf5a6c84SAndroid Build Coastguard Worker do {
1385*cf5a6c84SAndroid Build Coastguard Worker match_bit = match_byte & offset;
1386*cf5a6c84SAndroid Build Coastguard Worker match_byte <<= 1;
1387*cf5a6c84SAndroid Build Coastguard Worker i = offset + match_bit + symbol;
1388*cf5a6c84SAndroid Build Coastguard Worker
1389*cf5a6c84SAndroid Build Coastguard Worker if (rc_bit(&s->rc, &probs[i])) {
1390*cf5a6c84SAndroid Build Coastguard Worker symbol = (symbol << 1) + 1;
1391*cf5a6c84SAndroid Build Coastguard Worker offset &= match_bit;
1392*cf5a6c84SAndroid Build Coastguard Worker } else {
1393*cf5a6c84SAndroid Build Coastguard Worker symbol <<= 1;
1394*cf5a6c84SAndroid Build Coastguard Worker offset &= ~match_bit;
1395*cf5a6c84SAndroid Build Coastguard Worker }
1396*cf5a6c84SAndroid Build Coastguard Worker } while (symbol < 0x100);
1397*cf5a6c84SAndroid Build Coastguard Worker }
1398*cf5a6c84SAndroid Build Coastguard Worker
1399*cf5a6c84SAndroid Build Coastguard Worker dict_put(&s->dict, (char)symbol);
1400*cf5a6c84SAndroid Build Coastguard Worker lzma_state_literal(&s->lzma.state);
1401*cf5a6c84SAndroid Build Coastguard Worker }
1402*cf5a6c84SAndroid Build Coastguard Worker
1403*cf5a6c84SAndroid Build Coastguard Worker /* Decode the length of the match into s->lzma.len. */
lzma_len(struct xz_dec_lzma2 * s,struct lzma_len_dec * l,unsigned pos_state)1404*cf5a6c84SAndroid Build Coastguard Worker static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
1405*cf5a6c84SAndroid Build Coastguard Worker unsigned pos_state)
1406*cf5a6c84SAndroid Build Coastguard Worker {
1407*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs;
1408*cf5a6c84SAndroid Build Coastguard Worker unsigned limit;
1409*cf5a6c84SAndroid Build Coastguard Worker
1410*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &l->choice)) {
1411*cf5a6c84SAndroid Build Coastguard Worker probs = l->low[pos_state];
1412*cf5a6c84SAndroid Build Coastguard Worker limit = LEN_LOW_SYMBOLS;
1413*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len = MATCH_LEN_MIN;
1414*cf5a6c84SAndroid Build Coastguard Worker } else {
1415*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &l->choice2)) {
1416*cf5a6c84SAndroid Build Coastguard Worker probs = l->mid[pos_state];
1417*cf5a6c84SAndroid Build Coastguard Worker limit = LEN_MID_SYMBOLS;
1418*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
1419*cf5a6c84SAndroid Build Coastguard Worker } else {
1420*cf5a6c84SAndroid Build Coastguard Worker probs = l->high;
1421*cf5a6c84SAndroid Build Coastguard Worker limit = LEN_HIGH_SYMBOLS;
1422*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
1423*cf5a6c84SAndroid Build Coastguard Worker + LEN_MID_SYMBOLS;
1424*cf5a6c84SAndroid Build Coastguard Worker }
1425*cf5a6c84SAndroid Build Coastguard Worker }
1426*cf5a6c84SAndroid Build Coastguard Worker
1427*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
1428*cf5a6c84SAndroid Build Coastguard Worker }
1429*cf5a6c84SAndroid Build Coastguard Worker
1430*cf5a6c84SAndroid Build Coastguard Worker /* Decode a match. The distance will be stored in s->lzma.rep0. */
lzma_match(struct xz_dec_lzma2 * s,unsigned pos_state)1431*cf5a6c84SAndroid Build Coastguard Worker static void lzma_match(struct xz_dec_lzma2 *s, unsigned pos_state)
1432*cf5a6c84SAndroid Build Coastguard Worker {
1433*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs;
1434*cf5a6c84SAndroid Build Coastguard Worker unsigned dist_slot;
1435*cf5a6c84SAndroid Build Coastguard Worker unsigned limit;
1436*cf5a6c84SAndroid Build Coastguard Worker
1437*cf5a6c84SAndroid Build Coastguard Worker lzma_state_match(&s->lzma.state);
1438*cf5a6c84SAndroid Build Coastguard Worker
1439*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep3 = s->lzma.rep2;
1440*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep2 = s->lzma.rep1;
1441*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep1 = s->lzma.rep0;
1442*cf5a6c84SAndroid Build Coastguard Worker
1443*cf5a6c84SAndroid Build Coastguard Worker lzma_len(s, &s->lzma.match_len_dec, pos_state);
1444*cf5a6c84SAndroid Build Coastguard Worker
1445*cf5a6c84SAndroid Build Coastguard Worker probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
1446*cf5a6c84SAndroid Build Coastguard Worker dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
1447*cf5a6c84SAndroid Build Coastguard Worker
1448*cf5a6c84SAndroid Build Coastguard Worker if (dist_slot < DIST_MODEL_START) {
1449*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 = dist_slot;
1450*cf5a6c84SAndroid Build Coastguard Worker } else {
1451*cf5a6c84SAndroid Build Coastguard Worker limit = (dist_slot >> 1) - 1;
1452*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 = 2 + (dist_slot & 1);
1453*cf5a6c84SAndroid Build Coastguard Worker
1454*cf5a6c84SAndroid Build Coastguard Worker if (dist_slot < DIST_MODEL_END) {
1455*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 <<= limit;
1456*cf5a6c84SAndroid Build Coastguard Worker probs = s->lzma.dist_special + s->lzma.rep0
1457*cf5a6c84SAndroid Build Coastguard Worker - dist_slot - 1;
1458*cf5a6c84SAndroid Build Coastguard Worker rc_bittree_reverse(&s->rc, probs,
1459*cf5a6c84SAndroid Build Coastguard Worker &s->lzma.rep0, limit);
1460*cf5a6c84SAndroid Build Coastguard Worker } else {
1461*cf5a6c84SAndroid Build Coastguard Worker rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
1462*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 <<= ALIGN_BITS;
1463*cf5a6c84SAndroid Build Coastguard Worker rc_bittree_reverse(&s->rc, s->lzma.dist_align,
1464*cf5a6c84SAndroid Build Coastguard Worker &s->lzma.rep0, ALIGN_BITS);
1465*cf5a6c84SAndroid Build Coastguard Worker }
1466*cf5a6c84SAndroid Build Coastguard Worker }
1467*cf5a6c84SAndroid Build Coastguard Worker }
1468*cf5a6c84SAndroid Build Coastguard Worker
1469*cf5a6c84SAndroid Build Coastguard Worker /*
1470*cf5a6c84SAndroid Build Coastguard Worker * Decode a repeated match. The distance is one of the four most recently
1471*cf5a6c84SAndroid Build Coastguard Worker * seen matches. The distance will be stored in s->lzma.rep0.
1472*cf5a6c84SAndroid Build Coastguard Worker */
lzma_rep_match(struct xz_dec_lzma2 * s,unsigned pos_state)1473*cf5a6c84SAndroid Build Coastguard Worker static void lzma_rep_match(struct xz_dec_lzma2 *s, unsigned pos_state)
1474*cf5a6c84SAndroid Build Coastguard Worker {
1475*cf5a6c84SAndroid Build Coastguard Worker unsigned tmp;
1476*cf5a6c84SAndroid Build Coastguard Worker
1477*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
1478*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
1479*cf5a6c84SAndroid Build Coastguard Worker s->lzma.state][pos_state])) {
1480*cf5a6c84SAndroid Build Coastguard Worker lzma_state_short_rep(&s->lzma.state);
1481*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len = 1;
1482*cf5a6c84SAndroid Build Coastguard Worker return;
1483*cf5a6c84SAndroid Build Coastguard Worker }
1484*cf5a6c84SAndroid Build Coastguard Worker } else {
1485*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
1486*cf5a6c84SAndroid Build Coastguard Worker tmp = s->lzma.rep1;
1487*cf5a6c84SAndroid Build Coastguard Worker } else {
1488*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
1489*cf5a6c84SAndroid Build Coastguard Worker tmp = s->lzma.rep2;
1490*cf5a6c84SAndroid Build Coastguard Worker } else {
1491*cf5a6c84SAndroid Build Coastguard Worker tmp = s->lzma.rep3;
1492*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep3 = s->lzma.rep2;
1493*cf5a6c84SAndroid Build Coastguard Worker }
1494*cf5a6c84SAndroid Build Coastguard Worker
1495*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep2 = s->lzma.rep1;
1496*cf5a6c84SAndroid Build Coastguard Worker }
1497*cf5a6c84SAndroid Build Coastguard Worker
1498*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep1 = s->lzma.rep0;
1499*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 = tmp;
1500*cf5a6c84SAndroid Build Coastguard Worker }
1501*cf5a6c84SAndroid Build Coastguard Worker
1502*cf5a6c84SAndroid Build Coastguard Worker lzma_state_long_rep(&s->lzma.state);
1503*cf5a6c84SAndroid Build Coastguard Worker lzma_len(s, &s->lzma.rep_len_dec, pos_state);
1504*cf5a6c84SAndroid Build Coastguard Worker }
1505*cf5a6c84SAndroid Build Coastguard Worker
1506*cf5a6c84SAndroid Build Coastguard Worker /* LZMA decoder core */
lzma_main(struct xz_dec_lzma2 * s)1507*cf5a6c84SAndroid Build Coastguard Worker static int lzma_main(struct xz_dec_lzma2 *s)
1508*cf5a6c84SAndroid Build Coastguard Worker {
1509*cf5a6c84SAndroid Build Coastguard Worker unsigned pos_state;
1510*cf5a6c84SAndroid Build Coastguard Worker
1511*cf5a6c84SAndroid Build Coastguard Worker /*
1512*cf5a6c84SAndroid Build Coastguard Worker * If the dictionary was reached during the previous call, try to
1513*cf5a6c84SAndroid Build Coastguard Worker * finish the possibly pending repeat in the dictionary.
1514*cf5a6c84SAndroid Build Coastguard Worker */
1515*cf5a6c84SAndroid Build Coastguard Worker if (dict_has_space(&s->dict) && s->lzma.len > 0)
1516*cf5a6c84SAndroid Build Coastguard Worker dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
1517*cf5a6c84SAndroid Build Coastguard Worker
1518*cf5a6c84SAndroid Build Coastguard Worker /*
1519*cf5a6c84SAndroid Build Coastguard Worker * Decode more LZMA symbols. One iteration may consume up to
1520*cf5a6c84SAndroid Build Coastguard Worker * LZMA_IN_REQUIRED - 1 bytes.
1521*cf5a6c84SAndroid Build Coastguard Worker */
1522*cf5a6c84SAndroid Build Coastguard Worker while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
1523*cf5a6c84SAndroid Build Coastguard Worker pos_state = s->dict.pos & s->lzma.pos_mask;
1524*cf5a6c84SAndroid Build Coastguard Worker
1525*cf5a6c84SAndroid Build Coastguard Worker if (!rc_bit(&s->rc, &s->lzma.is_match[
1526*cf5a6c84SAndroid Build Coastguard Worker s->lzma.state][pos_state])) {
1527*cf5a6c84SAndroid Build Coastguard Worker lzma_literal(s);
1528*cf5a6c84SAndroid Build Coastguard Worker } else {
1529*cf5a6c84SAndroid Build Coastguard Worker if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
1530*cf5a6c84SAndroid Build Coastguard Worker lzma_rep_match(s, pos_state);
1531*cf5a6c84SAndroid Build Coastguard Worker else
1532*cf5a6c84SAndroid Build Coastguard Worker lzma_match(s, pos_state);
1533*cf5a6c84SAndroid Build Coastguard Worker
1534*cf5a6c84SAndroid Build Coastguard Worker if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
1535*cf5a6c84SAndroid Build Coastguard Worker return 0;
1536*cf5a6c84SAndroid Build Coastguard Worker }
1537*cf5a6c84SAndroid Build Coastguard Worker }
1538*cf5a6c84SAndroid Build Coastguard Worker
1539*cf5a6c84SAndroid Build Coastguard Worker /*
1540*cf5a6c84SAndroid Build Coastguard Worker * Having the range decoder always normalized when we are outside
1541*cf5a6c84SAndroid Build Coastguard Worker * this function makes it easier to correctly handle end of the chunk.
1542*cf5a6c84SAndroid Build Coastguard Worker */
1543*cf5a6c84SAndroid Build Coastguard Worker rc_normalize(&s->rc);
1544*cf5a6c84SAndroid Build Coastguard Worker
1545*cf5a6c84SAndroid Build Coastguard Worker return 1;
1546*cf5a6c84SAndroid Build Coastguard Worker }
1547*cf5a6c84SAndroid Build Coastguard Worker
1548*cf5a6c84SAndroid Build Coastguard Worker /*
1549*cf5a6c84SAndroid Build Coastguard Worker * Reset the LZMA decoder and range decoder state. Dictionary is nore reset
1550*cf5a6c84SAndroid Build Coastguard Worker * here, because LZMA state may be reset without resetting the dictionary.
1551*cf5a6c84SAndroid Build Coastguard Worker */
lzma_reset(struct xz_dec_lzma2 * s)1552*cf5a6c84SAndroid Build Coastguard Worker static void lzma_reset(struct xz_dec_lzma2 *s)
1553*cf5a6c84SAndroid Build Coastguard Worker {
1554*cf5a6c84SAndroid Build Coastguard Worker uint16_t *probs;
1555*cf5a6c84SAndroid Build Coastguard Worker size_t i;
1556*cf5a6c84SAndroid Build Coastguard Worker
1557*cf5a6c84SAndroid Build Coastguard Worker s->lzma.state = STATE_LIT_LIT;
1558*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep0 = 0;
1559*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep1 = 0;
1560*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep2 = 0;
1561*cf5a6c84SAndroid Build Coastguard Worker s->lzma.rep3 = 0;
1562*cf5a6c84SAndroid Build Coastguard Worker
1563*cf5a6c84SAndroid Build Coastguard Worker /*
1564*cf5a6c84SAndroid Build Coastguard Worker * All probabilities are initialized to the same value. This hack
1565*cf5a6c84SAndroid Build Coastguard Worker * makes the code smaller by avoiding a separate loop for each
1566*cf5a6c84SAndroid Build Coastguard Worker * probability array.
1567*cf5a6c84SAndroid Build Coastguard Worker *
1568*cf5a6c84SAndroid Build Coastguard Worker * This could be optimized so that only that part of literal
1569*cf5a6c84SAndroid Build Coastguard Worker * probabilities that are actually required. In the common case
1570*cf5a6c84SAndroid Build Coastguard Worker * we would write 12 KiB less.
1571*cf5a6c84SAndroid Build Coastguard Worker */
1572*cf5a6c84SAndroid Build Coastguard Worker probs = s->lzma.is_match[0];
1573*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i < PROBS_TOTAL; ++i)
1574*cf5a6c84SAndroid Build Coastguard Worker probs[i] = RC_BIT_MODEL_TOTAL / 2;
1575*cf5a6c84SAndroid Build Coastguard Worker
1576*cf5a6c84SAndroid Build Coastguard Worker rc_reset(&s->rc);
1577*cf5a6c84SAndroid Build Coastguard Worker }
1578*cf5a6c84SAndroid Build Coastguard Worker
1579*cf5a6c84SAndroid Build Coastguard Worker /*
1580*cf5a6c84SAndroid Build Coastguard Worker * Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks
1581*cf5a6c84SAndroid Build Coastguard Worker * from the decoded lp and pb values. On success, the LZMA decoder state is
1582*cf5a6c84SAndroid Build Coastguard Worker * reset and true is returned.
1583*cf5a6c84SAndroid Build Coastguard Worker */
lzma_props(struct xz_dec_lzma2 * s,char props)1584*cf5a6c84SAndroid Build Coastguard Worker static int lzma_props(struct xz_dec_lzma2 *s, char props)
1585*cf5a6c84SAndroid Build Coastguard Worker {
1586*cf5a6c84SAndroid Build Coastguard Worker if (props > (4 * 5 + 4) * 9 + 8)
1587*cf5a6c84SAndroid Build Coastguard Worker return 0;
1588*cf5a6c84SAndroid Build Coastguard Worker
1589*cf5a6c84SAndroid Build Coastguard Worker s->lzma.pos_mask = 0;
1590*cf5a6c84SAndroid Build Coastguard Worker while (props >= 9 * 5) {
1591*cf5a6c84SAndroid Build Coastguard Worker props -= 9 * 5;
1592*cf5a6c84SAndroid Build Coastguard Worker ++s->lzma.pos_mask;
1593*cf5a6c84SAndroid Build Coastguard Worker }
1594*cf5a6c84SAndroid Build Coastguard Worker
1595*cf5a6c84SAndroid Build Coastguard Worker s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
1596*cf5a6c84SAndroid Build Coastguard Worker
1597*cf5a6c84SAndroid Build Coastguard Worker s->lzma.literal_pos_mask = 0;
1598*cf5a6c84SAndroid Build Coastguard Worker while (props >= 9) {
1599*cf5a6c84SAndroid Build Coastguard Worker props -= 9;
1600*cf5a6c84SAndroid Build Coastguard Worker ++s->lzma.literal_pos_mask;
1601*cf5a6c84SAndroid Build Coastguard Worker }
1602*cf5a6c84SAndroid Build Coastguard Worker
1603*cf5a6c84SAndroid Build Coastguard Worker s->lzma.lc = props;
1604*cf5a6c84SAndroid Build Coastguard Worker
1605*cf5a6c84SAndroid Build Coastguard Worker if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
1606*cf5a6c84SAndroid Build Coastguard Worker return 0;
1607*cf5a6c84SAndroid Build Coastguard Worker
1608*cf5a6c84SAndroid Build Coastguard Worker s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
1609*cf5a6c84SAndroid Build Coastguard Worker
1610*cf5a6c84SAndroid Build Coastguard Worker lzma_reset(s);
1611*cf5a6c84SAndroid Build Coastguard Worker
1612*cf5a6c84SAndroid Build Coastguard Worker return 1;
1613*cf5a6c84SAndroid Build Coastguard Worker }
1614*cf5a6c84SAndroid Build Coastguard Worker
1615*cf5a6c84SAndroid Build Coastguard Worker /*********
1616*cf5a6c84SAndroid Build Coastguard Worker * LZMA2 *
1617*cf5a6c84SAndroid Build Coastguard Worker *********/
1618*cf5a6c84SAndroid Build Coastguard Worker
1619*cf5a6c84SAndroid Build Coastguard Worker /*
1620*cf5a6c84SAndroid Build Coastguard Worker * The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't
1621*cf5a6c84SAndroid Build Coastguard Worker * been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This
1622*cf5a6c84SAndroid Build Coastguard Worker * wrapper function takes care of making the LZMA decoder's assumption safe.
1623*cf5a6c84SAndroid Build Coastguard Worker *
1624*cf5a6c84SAndroid Build Coastguard Worker * As long as there is plenty of input left to be decoded in the current LZMA
1625*cf5a6c84SAndroid Build Coastguard Worker * chunk, we decode directly from the caller-supplied input buffer until
1626*cf5a6c84SAndroid Build Coastguard Worker * there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into
1627*cf5a6c84SAndroid Build Coastguard Worker * s->temp.buf, which (hopefully) gets filled on the next call to this
1628*cf5a6c84SAndroid Build Coastguard Worker * function. We decode a few bytes from the temporary buffer so that we can
1629*cf5a6c84SAndroid Build Coastguard Worker * continue decoding from the caller-supplied input buffer again.
1630*cf5a6c84SAndroid Build Coastguard Worker */
lzma2_lzma(struct xz_dec_lzma2 * s,struct xz_buf * b)1631*cf5a6c84SAndroid Build Coastguard Worker static int lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
1632*cf5a6c84SAndroid Build Coastguard Worker {
1633*cf5a6c84SAndroid Build Coastguard Worker size_t in_avail;
1634*cf5a6c84SAndroid Build Coastguard Worker unsigned tmp;
1635*cf5a6c84SAndroid Build Coastguard Worker
1636*cf5a6c84SAndroid Build Coastguard Worker in_avail = b->in_size - b->in_pos;
1637*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size > 0 || !s->lzma2.compressed) {
1638*cf5a6c84SAndroid Build Coastguard Worker tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
1639*cf5a6c84SAndroid Build Coastguard Worker if (tmp > s->lzma2.compressed - s->temp.size)
1640*cf5a6c84SAndroid Build Coastguard Worker tmp = s->lzma2.compressed - s->temp.size;
1641*cf5a6c84SAndroid Build Coastguard Worker if (tmp > in_avail)
1642*cf5a6c84SAndroid Build Coastguard Worker tmp = in_avail;
1643*cf5a6c84SAndroid Build Coastguard Worker
1644*cf5a6c84SAndroid Build Coastguard Worker memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
1645*cf5a6c84SAndroid Build Coastguard Worker
1646*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size + tmp == s->lzma2.compressed) {
1647*cf5a6c84SAndroid Build Coastguard Worker memset(s->temp.buf + s->temp.size + tmp, 0,
1648*cf5a6c84SAndroid Build Coastguard Worker sizeof(s->temp.buf)
1649*cf5a6c84SAndroid Build Coastguard Worker - s->temp.size - tmp);
1650*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_limit = s->temp.size + tmp;
1651*cf5a6c84SAndroid Build Coastguard Worker } else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
1652*cf5a6c84SAndroid Build Coastguard Worker s->temp.size += tmp;
1653*cf5a6c84SAndroid Build Coastguard Worker b->in_pos += tmp;
1654*cf5a6c84SAndroid Build Coastguard Worker return 1;
1655*cf5a6c84SAndroid Build Coastguard Worker } else {
1656*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
1657*cf5a6c84SAndroid Build Coastguard Worker }
1658*cf5a6c84SAndroid Build Coastguard Worker
1659*cf5a6c84SAndroid Build Coastguard Worker s->rc.in = s->temp.buf;
1660*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_pos = 0;
1661*cf5a6c84SAndroid Build Coastguard Worker
1662*cf5a6c84SAndroid Build Coastguard Worker if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
1663*cf5a6c84SAndroid Build Coastguard Worker return 0;
1664*cf5a6c84SAndroid Build Coastguard Worker
1665*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.compressed -= s->rc.in_pos;
1666*cf5a6c84SAndroid Build Coastguard Worker
1667*cf5a6c84SAndroid Build Coastguard Worker if (s->rc.in_pos < s->temp.size) {
1668*cf5a6c84SAndroid Build Coastguard Worker s->temp.size -= s->rc.in_pos;
1669*cf5a6c84SAndroid Build Coastguard Worker memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
1670*cf5a6c84SAndroid Build Coastguard Worker s->temp.size);
1671*cf5a6c84SAndroid Build Coastguard Worker return 1;
1672*cf5a6c84SAndroid Build Coastguard Worker }
1673*cf5a6c84SAndroid Build Coastguard Worker
1674*cf5a6c84SAndroid Build Coastguard Worker b->in_pos += s->rc.in_pos - s->temp.size;
1675*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = 0;
1676*cf5a6c84SAndroid Build Coastguard Worker }
1677*cf5a6c84SAndroid Build Coastguard Worker
1678*cf5a6c84SAndroid Build Coastguard Worker in_avail = b->in_size - b->in_pos;
1679*cf5a6c84SAndroid Build Coastguard Worker if (in_avail >= LZMA_IN_REQUIRED) {
1680*cf5a6c84SAndroid Build Coastguard Worker s->rc.in = b->in;
1681*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_pos = b->in_pos;
1682*cf5a6c84SAndroid Build Coastguard Worker
1683*cf5a6c84SAndroid Build Coastguard Worker if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
1684*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_limit = b->in_pos + s->lzma2.compressed;
1685*cf5a6c84SAndroid Build Coastguard Worker else
1686*cf5a6c84SAndroid Build Coastguard Worker s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
1687*cf5a6c84SAndroid Build Coastguard Worker
1688*cf5a6c84SAndroid Build Coastguard Worker if (!lzma_main(s))
1689*cf5a6c84SAndroid Build Coastguard Worker return 0;
1690*cf5a6c84SAndroid Build Coastguard Worker
1691*cf5a6c84SAndroid Build Coastguard Worker in_avail = s->rc.in_pos - b->in_pos;
1692*cf5a6c84SAndroid Build Coastguard Worker if (in_avail > s->lzma2.compressed) return 0;
1693*cf5a6c84SAndroid Build Coastguard Worker
1694*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.compressed -= in_avail;
1695*cf5a6c84SAndroid Build Coastguard Worker b->in_pos = s->rc.in_pos;
1696*cf5a6c84SAndroid Build Coastguard Worker }
1697*cf5a6c84SAndroid Build Coastguard Worker
1698*cf5a6c84SAndroid Build Coastguard Worker in_avail = b->in_size - b->in_pos;
1699*cf5a6c84SAndroid Build Coastguard Worker if (in_avail < LZMA_IN_REQUIRED) {
1700*cf5a6c84SAndroid Build Coastguard Worker if (in_avail > s->lzma2.compressed)
1701*cf5a6c84SAndroid Build Coastguard Worker in_avail = s->lzma2.compressed;
1702*cf5a6c84SAndroid Build Coastguard Worker
1703*cf5a6c84SAndroid Build Coastguard Worker memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
1704*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = in_avail;
1705*cf5a6c84SAndroid Build Coastguard Worker b->in_pos += in_avail;
1706*cf5a6c84SAndroid Build Coastguard Worker }
1707*cf5a6c84SAndroid Build Coastguard Worker
1708*cf5a6c84SAndroid Build Coastguard Worker return 1;
1709*cf5a6c84SAndroid Build Coastguard Worker }
1710*cf5a6c84SAndroid Build Coastguard Worker
1711*cf5a6c84SAndroid Build Coastguard Worker /*
1712*cf5a6c84SAndroid Build Coastguard Worker * Take care of the LZMA2 control layer, and forward the job of actual LZMA
1713*cf5a6c84SAndroid Build Coastguard Worker * decoding or copying of uncompressed chunks to other functions.
1714*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_lzma2_run(struct xz_dec_lzma2 * s,struct xz_buf * b)1715*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b)
1716*cf5a6c84SAndroid Build Coastguard Worker {
1717*cf5a6c84SAndroid Build Coastguard Worker unsigned tmp;
1718*cf5a6c84SAndroid Build Coastguard Worker
1719*cf5a6c84SAndroid Build Coastguard Worker while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
1720*cf5a6c84SAndroid Build Coastguard Worker switch (s->lzma2.sequence) {
1721*cf5a6c84SAndroid Build Coastguard Worker case SEQ_CONTROL:
1722*cf5a6c84SAndroid Build Coastguard Worker /*
1723*cf5a6c84SAndroid Build Coastguard Worker * LZMA2 control byte
1724*cf5a6c84SAndroid Build Coastguard Worker *
1725*cf5a6c84SAndroid Build Coastguard Worker * Exact values:
1726*cf5a6c84SAndroid Build Coastguard Worker * 0x00 End marker
1727*cf5a6c84SAndroid Build Coastguard Worker * 0x01 Dictionary reset followed by
1728*cf5a6c84SAndroid Build Coastguard Worker * an uncompressed chunk
1729*cf5a6c84SAndroid Build Coastguard Worker * 0x02 Uncompressed chunk (no dictionary reset)
1730*cf5a6c84SAndroid Build Coastguard Worker *
1731*cf5a6c84SAndroid Build Coastguard Worker * Highest three bits (s->control & 0xE0):
1732*cf5a6c84SAndroid Build Coastguard Worker * 0xE0 Dictionary reset, new properties and state
1733*cf5a6c84SAndroid Build Coastguard Worker * reset, followed by LZMA compressed chunk
1734*cf5a6c84SAndroid Build Coastguard Worker * 0xC0 New properties and state reset, followed
1735*cf5a6c84SAndroid Build Coastguard Worker * by LZMA compressed chunk (no dictionary
1736*cf5a6c84SAndroid Build Coastguard Worker * reset)
1737*cf5a6c84SAndroid Build Coastguard Worker * 0xA0 State reset using old properties,
1738*cf5a6c84SAndroid Build Coastguard Worker * followed by LZMA compressed chunk (no
1739*cf5a6c84SAndroid Build Coastguard Worker * dictionary reset)
1740*cf5a6c84SAndroid Build Coastguard Worker * 0x80 LZMA chunk (no dictionary or state reset)
1741*cf5a6c84SAndroid Build Coastguard Worker *
1742*cf5a6c84SAndroid Build Coastguard Worker * For LZMA compressed chunks, the lowest five bits
1743*cf5a6c84SAndroid Build Coastguard Worker * (s->control & 1F) are the highest bits of the
1744*cf5a6c84SAndroid Build Coastguard Worker * uncompressed size (bits 16-20).
1745*cf5a6c84SAndroid Build Coastguard Worker *
1746*cf5a6c84SAndroid Build Coastguard Worker * A new LZMA2 stream must begin with a dictionary
1747*cf5a6c84SAndroid Build Coastguard Worker * reset. The first LZMA chunk must set new
1748*cf5a6c84SAndroid Build Coastguard Worker * properties and reset the LZMA state.
1749*cf5a6c84SAndroid Build Coastguard Worker *
1750*cf5a6c84SAndroid Build Coastguard Worker * Values that don't match anything described above
1751*cf5a6c84SAndroid Build Coastguard Worker * are invalid and we return XZ_DATA_ERROR.
1752*cf5a6c84SAndroid Build Coastguard Worker */
1753*cf5a6c84SAndroid Build Coastguard Worker
1754*cf5a6c84SAndroid Build Coastguard Worker
1755*cf5a6c84SAndroid Build Coastguard Worker if (!(tmp = b->in[b->in_pos++]))
1756*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
1757*cf5a6c84SAndroid Build Coastguard Worker
1758*cf5a6c84SAndroid Build Coastguard Worker if (tmp >= 0xE0 || tmp == 1) {
1759*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.need_props = 1;
1760*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.need_dict_reset = 0;
1761*cf5a6c84SAndroid Build Coastguard Worker dict_reset(&s->dict);
1762*cf5a6c84SAndroid Build Coastguard Worker } else if (s->lzma2.need_dict_reset) {
1763*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1764*cf5a6c84SAndroid Build Coastguard Worker }
1765*cf5a6c84SAndroid Build Coastguard Worker
1766*cf5a6c84SAndroid Build Coastguard Worker if (tmp >= 0x80) {
1767*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.uncompressed = (tmp & 0x1F) << 16;
1768*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
1769*cf5a6c84SAndroid Build Coastguard Worker
1770*cf5a6c84SAndroid Build Coastguard Worker if (tmp >= 0xC0) {
1771*cf5a6c84SAndroid Build Coastguard Worker /*
1772*cf5a6c84SAndroid Build Coastguard Worker * When there are new properties,
1773*cf5a6c84SAndroid Build Coastguard Worker * state reset is done at
1774*cf5a6c84SAndroid Build Coastguard Worker * SEQ_PROPERTIES.
1775*cf5a6c84SAndroid Build Coastguard Worker */
1776*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.need_props = 0;
1777*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.next_sequence
1778*cf5a6c84SAndroid Build Coastguard Worker = SEQ_PROPERTIES;
1779*cf5a6c84SAndroid Build Coastguard Worker
1780*cf5a6c84SAndroid Build Coastguard Worker } else if (s->lzma2.need_props) {
1781*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1782*cf5a6c84SAndroid Build Coastguard Worker
1783*cf5a6c84SAndroid Build Coastguard Worker } else {
1784*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.next_sequence
1785*cf5a6c84SAndroid Build Coastguard Worker = SEQ_LZMA_PREPARE;
1786*cf5a6c84SAndroid Build Coastguard Worker if (tmp >= 0xA0)
1787*cf5a6c84SAndroid Build Coastguard Worker lzma_reset(s);
1788*cf5a6c84SAndroid Build Coastguard Worker }
1789*cf5a6c84SAndroid Build Coastguard Worker } else {
1790*cf5a6c84SAndroid Build Coastguard Worker if (tmp > 2)
1791*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1792*cf5a6c84SAndroid Build Coastguard Worker
1793*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_COMPRESSED_0;
1794*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.next_sequence = SEQ_COPY;
1795*cf5a6c84SAndroid Build Coastguard Worker }
1796*cf5a6c84SAndroid Build Coastguard Worker
1797*cf5a6c84SAndroid Build Coastguard Worker break;
1798*cf5a6c84SAndroid Build Coastguard Worker
1799*cf5a6c84SAndroid Build Coastguard Worker case SEQ_UNCOMPRESSED_1:
1800*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.uncompressed
1801*cf5a6c84SAndroid Build Coastguard Worker += (unsigned)b->in[b->in_pos++] << 8;
1802*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
1803*cf5a6c84SAndroid Build Coastguard Worker break;
1804*cf5a6c84SAndroid Build Coastguard Worker
1805*cf5a6c84SAndroid Build Coastguard Worker case SEQ_UNCOMPRESSED_2:
1806*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.uncompressed
1807*cf5a6c84SAndroid Build Coastguard Worker += (unsigned)b->in[b->in_pos++] + 1;
1808*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_COMPRESSED_0;
1809*cf5a6c84SAndroid Build Coastguard Worker break;
1810*cf5a6c84SAndroid Build Coastguard Worker
1811*cf5a6c84SAndroid Build Coastguard Worker case SEQ_COMPRESSED_0:
1812*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.compressed
1813*cf5a6c84SAndroid Build Coastguard Worker = (unsigned)b->in[b->in_pos++] << 8;
1814*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_COMPRESSED_1;
1815*cf5a6c84SAndroid Build Coastguard Worker break;
1816*cf5a6c84SAndroid Build Coastguard Worker
1817*cf5a6c84SAndroid Build Coastguard Worker case SEQ_COMPRESSED_1:
1818*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.compressed
1819*cf5a6c84SAndroid Build Coastguard Worker += (unsigned)b->in[b->in_pos++] + 1;
1820*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = s->lzma2.next_sequence;
1821*cf5a6c84SAndroid Build Coastguard Worker break;
1822*cf5a6c84SAndroid Build Coastguard Worker
1823*cf5a6c84SAndroid Build Coastguard Worker case SEQ_PROPERTIES:
1824*cf5a6c84SAndroid Build Coastguard Worker if (!lzma_props(s, b->in[b->in_pos++]))
1825*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1826*cf5a6c84SAndroid Build Coastguard Worker
1827*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_LZMA_PREPARE;
1828*cf5a6c84SAndroid Build Coastguard Worker
1829*cf5a6c84SAndroid Build Coastguard Worker case SEQ_LZMA_PREPARE:
1830*cf5a6c84SAndroid Build Coastguard Worker if (s->lzma2.compressed < RC_INIT_BYTES)
1831*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1832*cf5a6c84SAndroid Build Coastguard Worker
1833*cf5a6c84SAndroid Build Coastguard Worker if (!rc_read_init(&s->rc, b))
1834*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
1835*cf5a6c84SAndroid Build Coastguard Worker
1836*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.compressed -= RC_INIT_BYTES;
1837*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_LZMA_RUN;
1838*cf5a6c84SAndroid Build Coastguard Worker
1839*cf5a6c84SAndroid Build Coastguard Worker case SEQ_LZMA_RUN:
1840*cf5a6c84SAndroid Build Coastguard Worker /*
1841*cf5a6c84SAndroid Build Coastguard Worker * Set dictionary limit to indicate how much we want
1842*cf5a6c84SAndroid Build Coastguard Worker * to be encoded at maximum. Decode new data into the
1843*cf5a6c84SAndroid Build Coastguard Worker * dictionary. Flush the new data from dictionary to
1844*cf5a6c84SAndroid Build Coastguard Worker * b->out. Check if we finished decoding this chunk.
1845*cf5a6c84SAndroid Build Coastguard Worker * In case the dictionary got full but we didn't fill
1846*cf5a6c84SAndroid Build Coastguard Worker * the output buffer yet, we may run this loop
1847*cf5a6c84SAndroid Build Coastguard Worker * multiple times without changing s->lzma2.sequence.
1848*cf5a6c84SAndroid Build Coastguard Worker */
1849*cf5a6c84SAndroid Build Coastguard Worker dict_limit(&s->dict, minof(b->out_size - b->out_pos,
1850*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.uncompressed));
1851*cf5a6c84SAndroid Build Coastguard Worker if (!lzma2_lzma(s, b))
1852*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1853*cf5a6c84SAndroid Build Coastguard Worker
1854*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.uncompressed -= dict_flush(&s->dict, b);
1855*cf5a6c84SAndroid Build Coastguard Worker
1856*cf5a6c84SAndroid Build Coastguard Worker if (!s->lzma2.uncompressed) {
1857*cf5a6c84SAndroid Build Coastguard Worker if (s->lzma2.compressed > 0 || s->lzma.len > 0
1858*cf5a6c84SAndroid Build Coastguard Worker || s->rc.code)
1859*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
1860*cf5a6c84SAndroid Build Coastguard Worker
1861*cf5a6c84SAndroid Build Coastguard Worker rc_reset(&s->rc);
1862*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_CONTROL;
1863*cf5a6c84SAndroid Build Coastguard Worker
1864*cf5a6c84SAndroid Build Coastguard Worker } else if (b->out_pos == b->out_size
1865*cf5a6c84SAndroid Build Coastguard Worker || (b->in_pos == b->in_size
1866*cf5a6c84SAndroid Build Coastguard Worker && s->temp.size
1867*cf5a6c84SAndroid Build Coastguard Worker < s->lzma2.compressed)) {
1868*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
1869*cf5a6c84SAndroid Build Coastguard Worker }
1870*cf5a6c84SAndroid Build Coastguard Worker
1871*cf5a6c84SAndroid Build Coastguard Worker break;
1872*cf5a6c84SAndroid Build Coastguard Worker
1873*cf5a6c84SAndroid Build Coastguard Worker case SEQ_COPY:
1874*cf5a6c84SAndroid Build Coastguard Worker dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
1875*cf5a6c84SAndroid Build Coastguard Worker if (s->lzma2.compressed > 0)
1876*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
1877*cf5a6c84SAndroid Build Coastguard Worker
1878*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_CONTROL;
1879*cf5a6c84SAndroid Build Coastguard Worker break;
1880*cf5a6c84SAndroid Build Coastguard Worker }
1881*cf5a6c84SAndroid Build Coastguard Worker }
1882*cf5a6c84SAndroid Build Coastguard Worker
1883*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
1884*cf5a6c84SAndroid Build Coastguard Worker }
1885*cf5a6c84SAndroid Build Coastguard Worker
xz_dec_lzma2_create(unsigned dict_max)1886*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_lzma2 *xz_dec_lzma2_create(unsigned dict_max)
1887*cf5a6c84SAndroid Build Coastguard Worker {
1888*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_lzma2 *s = malloc(sizeof(*s));
1889*cf5a6c84SAndroid Build Coastguard Worker if (!s)
1890*cf5a6c84SAndroid Build Coastguard Worker return NULL;
1891*cf5a6c84SAndroid Build Coastguard Worker
1892*cf5a6c84SAndroid Build Coastguard Worker s->dict.size_max = dict_max;
1893*cf5a6c84SAndroid Build Coastguard Worker s->dict.buf = NULL;
1894*cf5a6c84SAndroid Build Coastguard Worker s->dict.allocated = 0;
1895*cf5a6c84SAndroid Build Coastguard Worker
1896*cf5a6c84SAndroid Build Coastguard Worker return s;
1897*cf5a6c84SAndroid Build Coastguard Worker }
1898*cf5a6c84SAndroid Build Coastguard Worker
xz_dec_lzma2_reset(struct xz_dec_lzma2 * s,char props)1899*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, char props)
1900*cf5a6c84SAndroid Build Coastguard Worker {
1901*cf5a6c84SAndroid Build Coastguard Worker /* This limits dictionary size to 3 GiB to keep parsing simpler. */
1902*cf5a6c84SAndroid Build Coastguard Worker if (props > 39)
1903*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
1904*cf5a6c84SAndroid Build Coastguard Worker
1905*cf5a6c84SAndroid Build Coastguard Worker s->dict.size = 2 + (props & 1);
1906*cf5a6c84SAndroid Build Coastguard Worker s->dict.size <<= (props >> 1) + 11;
1907*cf5a6c84SAndroid Build Coastguard Worker
1908*cf5a6c84SAndroid Build Coastguard Worker if (s->dict.size > s->dict.size_max)
1909*cf5a6c84SAndroid Build Coastguard Worker return XZ_MEMLIMIT_ERROR;
1910*cf5a6c84SAndroid Build Coastguard Worker
1911*cf5a6c84SAndroid Build Coastguard Worker s->dict.end = s->dict.size;
1912*cf5a6c84SAndroid Build Coastguard Worker
1913*cf5a6c84SAndroid Build Coastguard Worker if (s->dict.allocated < s->dict.size) {
1914*cf5a6c84SAndroid Build Coastguard Worker free(s->dict.buf);
1915*cf5a6c84SAndroid Build Coastguard Worker s->dict.buf = malloc(s->dict.size);
1916*cf5a6c84SAndroid Build Coastguard Worker if (s->dict.buf == NULL) {
1917*cf5a6c84SAndroid Build Coastguard Worker s->dict.allocated = 0;
1918*cf5a6c84SAndroid Build Coastguard Worker return XZ_MEM_ERROR;
1919*cf5a6c84SAndroid Build Coastguard Worker }
1920*cf5a6c84SAndroid Build Coastguard Worker }
1921*cf5a6c84SAndroid Build Coastguard Worker
1922*cf5a6c84SAndroid Build Coastguard Worker s->lzma.len = 0;
1923*cf5a6c84SAndroid Build Coastguard Worker
1924*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.sequence = SEQ_CONTROL;
1925*cf5a6c84SAndroid Build Coastguard Worker s->lzma2.need_dict_reset = 1;
1926*cf5a6c84SAndroid Build Coastguard Worker
1927*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = 0;
1928*cf5a6c84SAndroid Build Coastguard Worker
1929*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
1930*cf5a6c84SAndroid Build Coastguard Worker }
1931*cf5a6c84SAndroid Build Coastguard Worker
1932*cf5a6c84SAndroid Build Coastguard Worker /*
1933*cf5a6c84SAndroid Build Coastguard Worker * .xz Stream decoder
1934*cf5a6c84SAndroid Build Coastguard Worker */
1935*cf5a6c84SAndroid Build Coastguard Worker
1936*cf5a6c84SAndroid Build Coastguard Worker
1937*cf5a6c84SAndroid Build Coastguard Worker // BEGIN xz_stream.h
1938*cf5a6c84SAndroid Build Coastguard Worker /*
1939*cf5a6c84SAndroid Build Coastguard Worker * Definitions for handling the .xz file format
1940*cf5a6c84SAndroid Build Coastguard Worker */
1941*cf5a6c84SAndroid Build Coastguard Worker
1942*cf5a6c84SAndroid Build Coastguard Worker
1943*cf5a6c84SAndroid Build Coastguard Worker #define STREAM_HEADER_SIZE 12
1944*cf5a6c84SAndroid Build Coastguard Worker
1945*cf5a6c84SAndroid Build Coastguard Worker #define HEADER_MAGIC "\3757zXZ"
1946*cf5a6c84SAndroid Build Coastguard Worker #define HEADER_MAGIC_SIZE 6
1947*cf5a6c84SAndroid Build Coastguard Worker
1948*cf5a6c84SAndroid Build Coastguard Worker #define FOOTER_MAGIC "YZ"
1949*cf5a6c84SAndroid Build Coastguard Worker #define FOOTER_MAGIC_SIZE 2
1950*cf5a6c84SAndroid Build Coastguard Worker
1951*cf5a6c84SAndroid Build Coastguard Worker #define VLI_MAX ((uint64_t)-1 / 2)
1952*cf5a6c84SAndroid Build Coastguard Worker #define VLI_UNKNOWN (-1ULL)
1953*cf5a6c84SAndroid Build Coastguard Worker
1954*cf5a6c84SAndroid Build Coastguard Worker /* Maximum encoded size of a VLI */
1955*cf5a6c84SAndroid Build Coastguard Worker #define VLI_BYTES_MAX (sizeof(uint64_t) * 8 / 7)
1956*cf5a6c84SAndroid Build Coastguard Worker
1957*cf5a6c84SAndroid Build Coastguard Worker /* Integrity Check types */
1958*cf5a6c84SAndroid Build Coastguard Worker enum xz_check {
1959*cf5a6c84SAndroid Build Coastguard Worker XZ_CHECK_NONE = 0,
1960*cf5a6c84SAndroid Build Coastguard Worker XZ_CHECK_CRC32 = 1,
1961*cf5a6c84SAndroid Build Coastguard Worker XZ_CHECK_CRC64 = 4,
1962*cf5a6c84SAndroid Build Coastguard Worker XZ_CHECK_SHA256 = 10
1963*cf5a6c84SAndroid Build Coastguard Worker };
1964*cf5a6c84SAndroid Build Coastguard Worker
1965*cf5a6c84SAndroid Build Coastguard Worker /* Maximum possible Check ID */
1966*cf5a6c84SAndroid Build Coastguard Worker #define XZ_CHECK_MAX 15
1967*cf5a6c84SAndroid Build Coastguard Worker // END xz_stream.h
1968*cf5a6c84SAndroid Build Coastguard Worker
1969*cf5a6c84SAndroid Build Coastguard Worker /* Hash used to validate the Index field */
1970*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_hash {
1971*cf5a6c84SAndroid Build Coastguard Worker uint64_t unpadded;
1972*cf5a6c84SAndroid Build Coastguard Worker uint64_t uncompressed;
1973*cf5a6c84SAndroid Build Coastguard Worker unsigned crc32;
1974*cf5a6c84SAndroid Build Coastguard Worker };
1975*cf5a6c84SAndroid Build Coastguard Worker
1976*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec {
1977*cf5a6c84SAndroid Build Coastguard Worker /* Position in dec_main() */
1978*cf5a6c84SAndroid Build Coastguard Worker enum {
1979*cf5a6c84SAndroid Build Coastguard Worker SEQ_STREAM_HEADER,
1980*cf5a6c84SAndroid Build Coastguard Worker SEQ_BLOCK_START,
1981*cf5a6c84SAndroid Build Coastguard Worker SEQ_BLOCK_HEADER,
1982*cf5a6c84SAndroid Build Coastguard Worker SEQ_BLOCK_UNCOMPRESS,
1983*cf5a6c84SAndroid Build Coastguard Worker SEQ_BLOCK_PADDING,
1984*cf5a6c84SAndroid Build Coastguard Worker SEQ_BLOCK_CHECK,
1985*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX,
1986*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX_PADDING,
1987*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX_CRC32,
1988*cf5a6c84SAndroid Build Coastguard Worker SEQ_STREAM_FOOTER
1989*cf5a6c84SAndroid Build Coastguard Worker } sequence;
1990*cf5a6c84SAndroid Build Coastguard Worker
1991*cf5a6c84SAndroid Build Coastguard Worker /* Position in variable-length integers and Check fields */
1992*cf5a6c84SAndroid Build Coastguard Worker unsigned pos;
1993*cf5a6c84SAndroid Build Coastguard Worker
1994*cf5a6c84SAndroid Build Coastguard Worker /* Variable-length integer decoded by dec_vli() */
1995*cf5a6c84SAndroid Build Coastguard Worker uint64_t vli;
1996*cf5a6c84SAndroid Build Coastguard Worker
1997*cf5a6c84SAndroid Build Coastguard Worker /* Saved in_pos and out_pos */
1998*cf5a6c84SAndroid Build Coastguard Worker size_t in_start;
1999*cf5a6c84SAndroid Build Coastguard Worker size_t out_start;
2000*cf5a6c84SAndroid Build Coastguard Worker
2001*cf5a6c84SAndroid Build Coastguard Worker /* CRC32 or CRC64 value in Block or CRC32 value in Index */
2002*cf5a6c84SAndroid Build Coastguard Worker uint64_t crc;
2003*cf5a6c84SAndroid Build Coastguard Worker
2004*cf5a6c84SAndroid Build Coastguard Worker /* Type of the integrity check calculated from uncompressed data */
2005*cf5a6c84SAndroid Build Coastguard Worker enum xz_check check_type;
2006*cf5a6c84SAndroid Build Coastguard Worker
2007*cf5a6c84SAndroid Build Coastguard Worker /*
2008*cf5a6c84SAndroid Build Coastguard Worker * True if the next call to xz_dec_run() is allowed to return
2009*cf5a6c84SAndroid Build Coastguard Worker * XZ_BUF_ERROR.
2010*cf5a6c84SAndroid Build Coastguard Worker */
2011*cf5a6c84SAndroid Build Coastguard Worker int allow_buf_error;
2012*cf5a6c84SAndroid Build Coastguard Worker
2013*cf5a6c84SAndroid Build Coastguard Worker /* Information stored in Block Header */
2014*cf5a6c84SAndroid Build Coastguard Worker struct {
2015*cf5a6c84SAndroid Build Coastguard Worker /* Value stored in the Compressed Size field, or
2016*cf5a6c84SAndroid Build Coastguard Worker * VLI_UNKNOWN if Compressed Size is not present. */
2017*cf5a6c84SAndroid Build Coastguard Worker uint64_t compressed;
2018*cf5a6c84SAndroid Build Coastguard Worker
2019*cf5a6c84SAndroid Build Coastguard Worker /* Value stored in the Uncompressed Size field, or
2020*cf5a6c84SAndroid Build Coastguard Worker * VLI_UNKNOWN if Uncompressed Size is not present. */
2021*cf5a6c84SAndroid Build Coastguard Worker uint64_t uncompressed;
2022*cf5a6c84SAndroid Build Coastguard Worker
2023*cf5a6c84SAndroid Build Coastguard Worker /* Size of the Block Header field */
2024*cf5a6c84SAndroid Build Coastguard Worker unsigned size;
2025*cf5a6c84SAndroid Build Coastguard Worker } block_header;
2026*cf5a6c84SAndroid Build Coastguard Worker
2027*cf5a6c84SAndroid Build Coastguard Worker /* Information collected when decoding Blocks */
2028*cf5a6c84SAndroid Build Coastguard Worker struct {
2029*cf5a6c84SAndroid Build Coastguard Worker /* Observed compressed size of the current Block */
2030*cf5a6c84SAndroid Build Coastguard Worker uint64_t compressed;
2031*cf5a6c84SAndroid Build Coastguard Worker
2032*cf5a6c84SAndroid Build Coastguard Worker /* Observed uncompressed size of the current Block */
2033*cf5a6c84SAndroid Build Coastguard Worker uint64_t uncompressed;
2034*cf5a6c84SAndroid Build Coastguard Worker
2035*cf5a6c84SAndroid Build Coastguard Worker uint64_t count; /* Number of Blocks decoded so far */
2036*cf5a6c84SAndroid Build Coastguard Worker
2037*cf5a6c84SAndroid Build Coastguard Worker // Hash calculated from the Block sizes. This is used to
2038*cf5a6c84SAndroid Build Coastguard Worker // validate the Index field.
2039*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_hash hash;
2040*cf5a6c84SAndroid Build Coastguard Worker } block;
2041*cf5a6c84SAndroid Build Coastguard Worker
2042*cf5a6c84SAndroid Build Coastguard Worker /* Variables needed when verifying the Index field */
2043*cf5a6c84SAndroid Build Coastguard Worker struct {
2044*cf5a6c84SAndroid Build Coastguard Worker /* Position in dec_index() */
2045*cf5a6c84SAndroid Build Coastguard Worker enum {
2046*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX_COUNT,
2047*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX_UNPADDED,
2048*cf5a6c84SAndroid Build Coastguard Worker SEQ_INDEX_UNCOMPRESSED
2049*cf5a6c84SAndroid Build Coastguard Worker } sequence;
2050*cf5a6c84SAndroid Build Coastguard Worker
2051*cf5a6c84SAndroid Build Coastguard Worker // Size of the Index in bytes
2052*cf5a6c84SAndroid Build Coastguard Worker uint64_t size;
2053*cf5a6c84SAndroid Build Coastguard Worker
2054*cf5a6c84SAndroid Build Coastguard Worker // Number of Records (matches block.count in valid files)
2055*cf5a6c84SAndroid Build Coastguard Worker uint64_t count;
2056*cf5a6c84SAndroid Build Coastguard Worker
2057*cf5a6c84SAndroid Build Coastguard Worker // Hash calculated from the Records (matches block.hash in
2058*cf5a6c84SAndroid Build Coastguard Worker // valid files).
2059*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_hash hash;
2060*cf5a6c84SAndroid Build Coastguard Worker } index;
2061*cf5a6c84SAndroid Build Coastguard Worker
2062*cf5a6c84SAndroid Build Coastguard Worker /*
2063*cf5a6c84SAndroid Build Coastguard Worker * Temporary buffer needed to hold Stream Header, Block Header,
2064*cf5a6c84SAndroid Build Coastguard Worker * and Stream Footer. The Block Header is the biggest (1 KiB)
2065*cf5a6c84SAndroid Build Coastguard Worker * so we reserve space according to that. buf[] has to be aligned
2066*cf5a6c84SAndroid Build Coastguard Worker * to a multiple of four bytes; the size_t variables before it
2067*cf5a6c84SAndroid Build Coastguard Worker * should guarantee this.
2068*cf5a6c84SAndroid Build Coastguard Worker */
2069*cf5a6c84SAndroid Build Coastguard Worker struct {
2070*cf5a6c84SAndroid Build Coastguard Worker size_t pos;
2071*cf5a6c84SAndroid Build Coastguard Worker size_t size;
2072*cf5a6c84SAndroid Build Coastguard Worker char buf[1024];
2073*cf5a6c84SAndroid Build Coastguard Worker } temp;
2074*cf5a6c84SAndroid Build Coastguard Worker
2075*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_lzma2 *lzma2;
2076*cf5a6c84SAndroid Build Coastguard Worker
2077*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec_bcj *bcj;
2078*cf5a6c84SAndroid Build Coastguard Worker int bcj_active;
2079*cf5a6c84SAndroid Build Coastguard Worker };
2080*cf5a6c84SAndroid Build Coastguard Worker
2081*cf5a6c84SAndroid Build Coastguard Worker /* Sizes of the Check field with different Check IDs */
2082*cf5a6c84SAndroid Build Coastguard Worker static const char check_sizes[16] = {
2083*cf5a6c84SAndroid Build Coastguard Worker 0,
2084*cf5a6c84SAndroid Build Coastguard Worker 4, 4, 4,
2085*cf5a6c84SAndroid Build Coastguard Worker 8, 8, 8,
2086*cf5a6c84SAndroid Build Coastguard Worker 16, 16, 16,
2087*cf5a6c84SAndroid Build Coastguard Worker 32, 32, 32,
2088*cf5a6c84SAndroid Build Coastguard Worker 64, 64, 64
2089*cf5a6c84SAndroid Build Coastguard Worker };
2090*cf5a6c84SAndroid Build Coastguard Worker
2091*cf5a6c84SAndroid Build Coastguard Worker /*
2092*cf5a6c84SAndroid Build Coastguard Worker * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller
2093*cf5a6c84SAndroid Build Coastguard Worker * must have set s->temp.pos to indicate how much data we are supposed
2094*cf5a6c84SAndroid Build Coastguard Worker * to copy into s->temp.buf. Return true once s->temp.pos has reached
2095*cf5a6c84SAndroid Build Coastguard Worker * s->temp.size.
2096*cf5a6c84SAndroid Build Coastguard Worker */
fill_temp(struct xz_dec * s,struct xz_buf * b)2097*cf5a6c84SAndroid Build Coastguard Worker static int fill_temp(struct xz_dec *s, struct xz_buf *b)
2098*cf5a6c84SAndroid Build Coastguard Worker {
2099*cf5a6c84SAndroid Build Coastguard Worker size_t copy_size = minof(b->in_size - b->in_pos, s->temp.size - s->temp.pos);
2100*cf5a6c84SAndroid Build Coastguard Worker
2101*cf5a6c84SAndroid Build Coastguard Worker memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
2102*cf5a6c84SAndroid Build Coastguard Worker b->in_pos += copy_size;
2103*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos += copy_size;
2104*cf5a6c84SAndroid Build Coastguard Worker
2105*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.pos == s->temp.size) {
2106*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos = 0;
2107*cf5a6c84SAndroid Build Coastguard Worker return 1;
2108*cf5a6c84SAndroid Build Coastguard Worker }
2109*cf5a6c84SAndroid Build Coastguard Worker
2110*cf5a6c84SAndroid Build Coastguard Worker return 0;
2111*cf5a6c84SAndroid Build Coastguard Worker }
2112*cf5a6c84SAndroid Build Coastguard Worker
2113*cf5a6c84SAndroid Build Coastguard Worker /* Decode a variable-length integer (little-endian base-128 encoding) */
dec_vli(struct xz_dec * s,const char * in,size_t * in_pos,size_t in_size)2114*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_vli(struct xz_dec *s, const char *in,
2115*cf5a6c84SAndroid Build Coastguard Worker size_t *in_pos, size_t in_size)
2116*cf5a6c84SAndroid Build Coastguard Worker {
2117*cf5a6c84SAndroid Build Coastguard Worker char byte;
2118*cf5a6c84SAndroid Build Coastguard Worker
2119*cf5a6c84SAndroid Build Coastguard Worker if (!s->pos)
2120*cf5a6c84SAndroid Build Coastguard Worker s->vli = 0;
2121*cf5a6c84SAndroid Build Coastguard Worker
2122*cf5a6c84SAndroid Build Coastguard Worker while (*in_pos < in_size) {
2123*cf5a6c84SAndroid Build Coastguard Worker byte = in[*in_pos];
2124*cf5a6c84SAndroid Build Coastguard Worker ++*in_pos;
2125*cf5a6c84SAndroid Build Coastguard Worker
2126*cf5a6c84SAndroid Build Coastguard Worker s->vli |= (uint64_t)(byte & 0x7F) << s->pos;
2127*cf5a6c84SAndroid Build Coastguard Worker
2128*cf5a6c84SAndroid Build Coastguard Worker if (!(byte & 0x80)) {
2129*cf5a6c84SAndroid Build Coastguard Worker // Don't allow non-minimal encodings.
2130*cf5a6c84SAndroid Build Coastguard Worker if (!byte && s->pos)
2131*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2132*cf5a6c84SAndroid Build Coastguard Worker
2133*cf5a6c84SAndroid Build Coastguard Worker s->pos = 0;
2134*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
2135*cf5a6c84SAndroid Build Coastguard Worker }
2136*cf5a6c84SAndroid Build Coastguard Worker
2137*cf5a6c84SAndroid Build Coastguard Worker s->pos += 7;
2138*cf5a6c84SAndroid Build Coastguard Worker if (s->pos == 7 * VLI_BYTES_MAX)
2139*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2140*cf5a6c84SAndroid Build Coastguard Worker }
2141*cf5a6c84SAndroid Build Coastguard Worker
2142*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2143*cf5a6c84SAndroid Build Coastguard Worker }
2144*cf5a6c84SAndroid Build Coastguard Worker
2145*cf5a6c84SAndroid Build Coastguard Worker /*
2146*cf5a6c84SAndroid Build Coastguard Worker * Decode the Compressed Data field from a Block. Update and validate
2147*cf5a6c84SAndroid Build Coastguard Worker * the observed compressed and uncompressed sizes of the Block so that
2148*cf5a6c84SAndroid Build Coastguard Worker * they don't exceed the values possibly stored in the Block Header
2149*cf5a6c84SAndroid Build Coastguard Worker * (validation assumes that no integer overflow occurs, since uint64_t
2150*cf5a6c84SAndroid Build Coastguard Worker * is normally uint64_t). Update the CRC32 or CRC64 value if presence of
2151*cf5a6c84SAndroid Build Coastguard Worker * the CRC32 or CRC64 field was indicated in Stream Header.
2152*cf5a6c84SAndroid Build Coastguard Worker *
2153*cf5a6c84SAndroid Build Coastguard Worker * Once the decoding is finished, validate that the observed sizes match
2154*cf5a6c84SAndroid Build Coastguard Worker * the sizes possibly stored in the Block Header. Update the hash and
2155*cf5a6c84SAndroid Build Coastguard Worker * Block count, which are later used to validate the Index field.
2156*cf5a6c84SAndroid Build Coastguard Worker */
dec_block(struct xz_dec * s,struct xz_buf * b)2157*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
2158*cf5a6c84SAndroid Build Coastguard Worker {
2159*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2160*cf5a6c84SAndroid Build Coastguard Worker
2161*cf5a6c84SAndroid Build Coastguard Worker s->in_start = b->in_pos;
2162*cf5a6c84SAndroid Build Coastguard Worker s->out_start = b->out_pos;
2163*cf5a6c84SAndroid Build Coastguard Worker
2164*cf5a6c84SAndroid Build Coastguard Worker if (s->bcj_active)
2165*cf5a6c84SAndroid Build Coastguard Worker ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
2166*cf5a6c84SAndroid Build Coastguard Worker else
2167*cf5a6c84SAndroid Build Coastguard Worker ret = xz_dec_lzma2_run(s->lzma2, b);
2168*cf5a6c84SAndroid Build Coastguard Worker
2169*cf5a6c84SAndroid Build Coastguard Worker s->block.compressed += b->in_pos - s->in_start;
2170*cf5a6c84SAndroid Build Coastguard Worker s->block.uncompressed += b->out_pos - s->out_start;
2171*cf5a6c84SAndroid Build Coastguard Worker
2172*cf5a6c84SAndroid Build Coastguard Worker /*
2173*cf5a6c84SAndroid Build Coastguard Worker * There is no need to separately check for VLI_UNKNOWN, since
2174*cf5a6c84SAndroid Build Coastguard Worker * the observed sizes are always smaller than VLI_UNKNOWN.
2175*cf5a6c84SAndroid Build Coastguard Worker */
2176*cf5a6c84SAndroid Build Coastguard Worker if (s->block.compressed > s->block_header.compressed
2177*cf5a6c84SAndroid Build Coastguard Worker || s->block.uncompressed
2178*cf5a6c84SAndroid Build Coastguard Worker > s->block_header.uncompressed)
2179*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2180*cf5a6c84SAndroid Build Coastguard Worker
2181*cf5a6c84SAndroid Build Coastguard Worker if (s->check_type == XZ_CHECK_CRC32)
2182*cf5a6c84SAndroid Build Coastguard Worker s->crc = xz_crc32(b->out + s->out_start,
2183*cf5a6c84SAndroid Build Coastguard Worker b->out_pos - s->out_start, s->crc);
2184*cf5a6c84SAndroid Build Coastguard Worker else if (s->check_type == XZ_CHECK_CRC64) {
2185*cf5a6c84SAndroid Build Coastguard Worker s->crc = ~(s->crc);
2186*cf5a6c84SAndroid Build Coastguard Worker size_t size = b->out_pos - s->out_start;
2187*cf5a6c84SAndroid Build Coastguard Worker char *buf = b->out + s->out_start;
2188*cf5a6c84SAndroid Build Coastguard Worker while (size) {
2189*cf5a6c84SAndroid Build Coastguard Worker s->crc = xz_crc64_table[*buf++ ^ (s->crc & 0xFF)] ^ (s->crc >> 8);
2190*cf5a6c84SAndroid Build Coastguard Worker --size;
2191*cf5a6c84SAndroid Build Coastguard Worker }
2192*cf5a6c84SAndroid Build Coastguard Worker s->crc=~(s->crc);
2193*cf5a6c84SAndroid Build Coastguard Worker }
2194*cf5a6c84SAndroid Build Coastguard Worker
2195*cf5a6c84SAndroid Build Coastguard Worker if (ret == XZ_STREAM_END) {
2196*cf5a6c84SAndroid Build Coastguard Worker if (s->block_header.compressed != VLI_UNKNOWN
2197*cf5a6c84SAndroid Build Coastguard Worker && s->block_header.compressed
2198*cf5a6c84SAndroid Build Coastguard Worker != s->block.compressed)
2199*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2200*cf5a6c84SAndroid Build Coastguard Worker
2201*cf5a6c84SAndroid Build Coastguard Worker if (s->block_header.uncompressed != VLI_UNKNOWN
2202*cf5a6c84SAndroid Build Coastguard Worker && s->block_header.uncompressed
2203*cf5a6c84SAndroid Build Coastguard Worker != s->block.uncompressed)
2204*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2205*cf5a6c84SAndroid Build Coastguard Worker
2206*cf5a6c84SAndroid Build Coastguard Worker s->block.hash.unpadded += s->block_header.size
2207*cf5a6c84SAndroid Build Coastguard Worker + s->block.compressed;
2208*cf5a6c84SAndroid Build Coastguard Worker
2209*cf5a6c84SAndroid Build Coastguard Worker s->block.hash.unpadded += check_sizes[s->check_type];
2210*cf5a6c84SAndroid Build Coastguard Worker
2211*cf5a6c84SAndroid Build Coastguard Worker s->block.hash.uncompressed += s->block.uncompressed;
2212*cf5a6c84SAndroid Build Coastguard Worker s->block.hash.crc32 = xz_crc32(
2213*cf5a6c84SAndroid Build Coastguard Worker (const char *)&s->block.hash,
2214*cf5a6c84SAndroid Build Coastguard Worker sizeof(s->block.hash), s->block.hash.crc32);
2215*cf5a6c84SAndroid Build Coastguard Worker
2216*cf5a6c84SAndroid Build Coastguard Worker ++s->block.count;
2217*cf5a6c84SAndroid Build Coastguard Worker }
2218*cf5a6c84SAndroid Build Coastguard Worker
2219*cf5a6c84SAndroid Build Coastguard Worker return ret;
2220*cf5a6c84SAndroid Build Coastguard Worker }
2221*cf5a6c84SAndroid Build Coastguard Worker
2222*cf5a6c84SAndroid Build Coastguard Worker /* Update the Index size and the CRC32 value. */
index_update(struct xz_dec * s,const struct xz_buf * b)2223*cf5a6c84SAndroid Build Coastguard Worker static void index_update(struct xz_dec *s, const struct xz_buf *b)
2224*cf5a6c84SAndroid Build Coastguard Worker {
2225*cf5a6c84SAndroid Build Coastguard Worker size_t in_used = b->in_pos - s->in_start;
2226*cf5a6c84SAndroid Build Coastguard Worker s->index.size += in_used;
2227*cf5a6c84SAndroid Build Coastguard Worker s->crc = xz_crc32(b->in + s->in_start, in_used, s->crc);
2228*cf5a6c84SAndroid Build Coastguard Worker }
2229*cf5a6c84SAndroid Build Coastguard Worker
2230*cf5a6c84SAndroid Build Coastguard Worker /*
2231*cf5a6c84SAndroid Build Coastguard Worker * Decode the Number of Records, Unpadded Size, and Uncompressed Size
2232*cf5a6c84SAndroid Build Coastguard Worker * fields from the Index field. That is, Index Padding and CRC32 are not
2233*cf5a6c84SAndroid Build Coastguard Worker * decoded by this function.
2234*cf5a6c84SAndroid Build Coastguard Worker *
2235*cf5a6c84SAndroid Build Coastguard Worker * This can return XZ_OK (more input needed), XZ_STREAM_END (everything
2236*cf5a6c84SAndroid Build Coastguard Worker * successfully decoded), or XZ_DATA_ERROR (input is corrupt).
2237*cf5a6c84SAndroid Build Coastguard Worker */
dec_index(struct xz_dec * s,struct xz_buf * b)2238*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
2239*cf5a6c84SAndroid Build Coastguard Worker {
2240*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2241*cf5a6c84SAndroid Build Coastguard Worker
2242*cf5a6c84SAndroid Build Coastguard Worker do {
2243*cf5a6c84SAndroid Build Coastguard Worker ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
2244*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END) {
2245*cf5a6c84SAndroid Build Coastguard Worker index_update(s, b);
2246*cf5a6c84SAndroid Build Coastguard Worker return ret;
2247*cf5a6c84SAndroid Build Coastguard Worker }
2248*cf5a6c84SAndroid Build Coastguard Worker
2249*cf5a6c84SAndroid Build Coastguard Worker switch (s->index.sequence) {
2250*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX_COUNT:
2251*cf5a6c84SAndroid Build Coastguard Worker s->index.count = s->vli;
2252*cf5a6c84SAndroid Build Coastguard Worker
2253*cf5a6c84SAndroid Build Coastguard Worker /*
2254*cf5a6c84SAndroid Build Coastguard Worker * Validate that the Number of Records field
2255*cf5a6c84SAndroid Build Coastguard Worker * indicates the same number of Records as
2256*cf5a6c84SAndroid Build Coastguard Worker * there were Blocks in the Stream.
2257*cf5a6c84SAndroid Build Coastguard Worker */
2258*cf5a6c84SAndroid Build Coastguard Worker if (s->index.count != s->block.count)
2259*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2260*cf5a6c84SAndroid Build Coastguard Worker
2261*cf5a6c84SAndroid Build Coastguard Worker s->index.sequence = SEQ_INDEX_UNPADDED;
2262*cf5a6c84SAndroid Build Coastguard Worker break;
2263*cf5a6c84SAndroid Build Coastguard Worker
2264*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX_UNPADDED:
2265*cf5a6c84SAndroid Build Coastguard Worker s->index.hash.unpadded += s->vli;
2266*cf5a6c84SAndroid Build Coastguard Worker s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
2267*cf5a6c84SAndroid Build Coastguard Worker break;
2268*cf5a6c84SAndroid Build Coastguard Worker
2269*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX_UNCOMPRESSED:
2270*cf5a6c84SAndroid Build Coastguard Worker s->index.hash.uncompressed += s->vli;
2271*cf5a6c84SAndroid Build Coastguard Worker s->index.hash.crc32 = xz_crc32(
2272*cf5a6c84SAndroid Build Coastguard Worker (const char *)&s->index.hash,
2273*cf5a6c84SAndroid Build Coastguard Worker sizeof(s->index.hash),
2274*cf5a6c84SAndroid Build Coastguard Worker s->index.hash.crc32);
2275*cf5a6c84SAndroid Build Coastguard Worker --s->index.count;
2276*cf5a6c84SAndroid Build Coastguard Worker s->index.sequence = SEQ_INDEX_UNPADDED;
2277*cf5a6c84SAndroid Build Coastguard Worker break;
2278*cf5a6c84SAndroid Build Coastguard Worker }
2279*cf5a6c84SAndroid Build Coastguard Worker } while (s->index.count > 0);
2280*cf5a6c84SAndroid Build Coastguard Worker
2281*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
2282*cf5a6c84SAndroid Build Coastguard Worker }
2283*cf5a6c84SAndroid Build Coastguard Worker
2284*cf5a6c84SAndroid Build Coastguard Worker /*
2285*cf5a6c84SAndroid Build Coastguard Worker * Validate that the next four or eight input bytes match the value
2286*cf5a6c84SAndroid Build Coastguard Worker * of s->crc. s->pos must be zero when starting to validate the first byte.
2287*cf5a6c84SAndroid Build Coastguard Worker * The "bits" argument allows using the same code for both CRC32 and CRC64.
2288*cf5a6c84SAndroid Build Coastguard Worker */
crc_validate(struct xz_dec * s,struct xz_buf * b,unsigned bits)2289*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b,
2290*cf5a6c84SAndroid Build Coastguard Worker unsigned bits)
2291*cf5a6c84SAndroid Build Coastguard Worker {
2292*cf5a6c84SAndroid Build Coastguard Worker do {
2293*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size)
2294*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2295*cf5a6c84SAndroid Build Coastguard Worker
2296*cf5a6c84SAndroid Build Coastguard Worker if (((s->crc >> s->pos) & 0xFF) != b->in[b->in_pos++])
2297*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2298*cf5a6c84SAndroid Build Coastguard Worker
2299*cf5a6c84SAndroid Build Coastguard Worker s->pos += 8;
2300*cf5a6c84SAndroid Build Coastguard Worker
2301*cf5a6c84SAndroid Build Coastguard Worker } while (s->pos < bits);
2302*cf5a6c84SAndroid Build Coastguard Worker
2303*cf5a6c84SAndroid Build Coastguard Worker s->crc = 0;
2304*cf5a6c84SAndroid Build Coastguard Worker s->pos = 0;
2305*cf5a6c84SAndroid Build Coastguard Worker
2306*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
2307*cf5a6c84SAndroid Build Coastguard Worker }
2308*cf5a6c84SAndroid Build Coastguard Worker
2309*cf5a6c84SAndroid Build Coastguard Worker /*
2310*cf5a6c84SAndroid Build Coastguard Worker * Skip over the Check field when the Check ID is not supported.
2311*cf5a6c84SAndroid Build Coastguard Worker * Returns true once the whole Check field has been skipped over.
2312*cf5a6c84SAndroid Build Coastguard Worker */
check_skip(struct xz_dec * s,struct xz_buf * b)2313*cf5a6c84SAndroid Build Coastguard Worker static int check_skip(struct xz_dec *s, struct xz_buf *b)
2314*cf5a6c84SAndroid Build Coastguard Worker {
2315*cf5a6c84SAndroid Build Coastguard Worker while (s->pos < check_sizes[s->check_type]) {
2316*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size) return 0;
2317*cf5a6c84SAndroid Build Coastguard Worker
2318*cf5a6c84SAndroid Build Coastguard Worker ++b->in_pos;
2319*cf5a6c84SAndroid Build Coastguard Worker ++s->pos;
2320*cf5a6c84SAndroid Build Coastguard Worker }
2321*cf5a6c84SAndroid Build Coastguard Worker
2322*cf5a6c84SAndroid Build Coastguard Worker s->pos = 0;
2323*cf5a6c84SAndroid Build Coastguard Worker
2324*cf5a6c84SAndroid Build Coastguard Worker return 1;
2325*cf5a6c84SAndroid Build Coastguard Worker }
2326*cf5a6c84SAndroid Build Coastguard Worker
2327*cf5a6c84SAndroid Build Coastguard Worker /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
dec_stream_header(struct xz_dec * s)2328*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_stream_header(struct xz_dec *s)
2329*cf5a6c84SAndroid Build Coastguard Worker {
2330*cf5a6c84SAndroid Build Coastguard Worker if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
2331*cf5a6c84SAndroid Build Coastguard Worker return XZ_FORMAT_ERROR;
2332*cf5a6c84SAndroid Build Coastguard Worker
2333*cf5a6c84SAndroid Build Coastguard Worker if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
2334*cf5a6c84SAndroid Build Coastguard Worker != get_unaligned_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
2335*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2336*cf5a6c84SAndroid Build Coastguard Worker
2337*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[HEADER_MAGIC_SIZE])
2338*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2339*cf5a6c84SAndroid Build Coastguard Worker
2340*cf5a6c84SAndroid Build Coastguard Worker /*
2341*cf5a6c84SAndroid Build Coastguard Worker * Of integrity checks, we support none (Check ID = 0),
2342*cf5a6c84SAndroid Build Coastguard Worker * CRC32 (Check ID = 1), and optionally CRC64 (Check ID = 4).
2343*cf5a6c84SAndroid Build Coastguard Worker * However, if XZ_DEC_ANY_CHECK is defined, we will accept other
2344*cf5a6c84SAndroid Build Coastguard Worker * check types too, but then the check won't be verified and
2345*cf5a6c84SAndroid Build Coastguard Worker * a warning (XZ_UNSUPPORTED_CHECK) will be given.
2346*cf5a6c84SAndroid Build Coastguard Worker */
2347*cf5a6c84SAndroid Build Coastguard Worker s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
2348*cf5a6c84SAndroid Build Coastguard Worker
2349*cf5a6c84SAndroid Build Coastguard Worker if (s->check_type > XZ_CHECK_MAX)
2350*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2351*cf5a6c84SAndroid Build Coastguard Worker
2352*cf5a6c84SAndroid Build Coastguard Worker if (s->check_type > XZ_CHECK_CRC32 && s->check_type != XZ_CHECK_CRC64)
2353*cf5a6c84SAndroid Build Coastguard Worker return XZ_UNSUPPORTED_CHECK;
2354*cf5a6c84SAndroid Build Coastguard Worker
2355*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2356*cf5a6c84SAndroid Build Coastguard Worker }
2357*cf5a6c84SAndroid Build Coastguard Worker
2358*cf5a6c84SAndroid Build Coastguard Worker /* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
dec_stream_footer(struct xz_dec * s)2359*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_stream_footer(struct xz_dec *s)
2360*cf5a6c84SAndroid Build Coastguard Worker {
2361*cf5a6c84SAndroid Build Coastguard Worker if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
2362*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2363*cf5a6c84SAndroid Build Coastguard Worker
2364*cf5a6c84SAndroid Build Coastguard Worker if (xz_crc32(s->temp.buf + 4, 6, 0) != get_unaligned_le32(s->temp.buf))
2365*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2366*cf5a6c84SAndroid Build Coastguard Worker
2367*cf5a6c84SAndroid Build Coastguard Worker /*
2368*cf5a6c84SAndroid Build Coastguard Worker * Validate Backward Size. Note that we never added the size of the
2369*cf5a6c84SAndroid Build Coastguard Worker * Index CRC32 field to s->index.size, thus we use s->index.size / 4
2370*cf5a6c84SAndroid Build Coastguard Worker * instead of s->index.size / 4 - 1.
2371*cf5a6c84SAndroid Build Coastguard Worker */
2372*cf5a6c84SAndroid Build Coastguard Worker if ((s->index.size >> 2) != get_unaligned_le32(s->temp.buf + 4))
2373*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2374*cf5a6c84SAndroid Build Coastguard Worker
2375*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[8] || s->temp.buf[9] != s->check_type)
2376*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2377*cf5a6c84SAndroid Build Coastguard Worker
2378*cf5a6c84SAndroid Build Coastguard Worker /*
2379*cf5a6c84SAndroid Build Coastguard Worker * Use XZ_STREAM_END instead of XZ_OK to be more convenient
2380*cf5a6c84SAndroid Build Coastguard Worker * for the caller.
2381*cf5a6c84SAndroid Build Coastguard Worker */
2382*cf5a6c84SAndroid Build Coastguard Worker return XZ_STREAM_END;
2383*cf5a6c84SAndroid Build Coastguard Worker }
2384*cf5a6c84SAndroid Build Coastguard Worker
2385*cf5a6c84SAndroid Build Coastguard Worker /* Decode the Block Header and initialize the filter chain. */
dec_block_header(struct xz_dec * s)2386*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_block_header(struct xz_dec *s)
2387*cf5a6c84SAndroid Build Coastguard Worker {
2388*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2389*cf5a6c84SAndroid Build Coastguard Worker
2390*cf5a6c84SAndroid Build Coastguard Worker /*
2391*cf5a6c84SAndroid Build Coastguard Worker * Validate the CRC32. We know that the temp buffer is at least
2392*cf5a6c84SAndroid Build Coastguard Worker * eight bytes so this is safe.
2393*cf5a6c84SAndroid Build Coastguard Worker */
2394*cf5a6c84SAndroid Build Coastguard Worker s->temp.size -= 4;
2395*cf5a6c84SAndroid Build Coastguard Worker if (xz_crc32(s->temp.buf, s->temp.size, 0)
2396*cf5a6c84SAndroid Build Coastguard Worker != get_unaligned_le32(s->temp.buf + s->temp.size))
2397*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2398*cf5a6c84SAndroid Build Coastguard Worker
2399*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos = 2;
2400*cf5a6c84SAndroid Build Coastguard Worker
2401*cf5a6c84SAndroid Build Coastguard Worker /*
2402*cf5a6c84SAndroid Build Coastguard Worker * Catch unsupported Block Flags. We support only one or two filters
2403*cf5a6c84SAndroid Build Coastguard Worker * in the chain, so we catch that with the same test.
2404*cf5a6c84SAndroid Build Coastguard Worker */
2405*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[1] & 0x3E)
2406*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2407*cf5a6c84SAndroid Build Coastguard Worker
2408*cf5a6c84SAndroid Build Coastguard Worker /* Compressed Size */
2409*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[1] & 0x40) {
2410*cf5a6c84SAndroid Build Coastguard Worker if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
2411*cf5a6c84SAndroid Build Coastguard Worker != XZ_STREAM_END)
2412*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2413*cf5a6c84SAndroid Build Coastguard Worker
2414*cf5a6c84SAndroid Build Coastguard Worker s->block_header.compressed = s->vli;
2415*cf5a6c84SAndroid Build Coastguard Worker } else {
2416*cf5a6c84SAndroid Build Coastguard Worker s->block_header.compressed = VLI_UNKNOWN;
2417*cf5a6c84SAndroid Build Coastguard Worker }
2418*cf5a6c84SAndroid Build Coastguard Worker
2419*cf5a6c84SAndroid Build Coastguard Worker /* Uncompressed Size */
2420*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[1] & 0x80) {
2421*cf5a6c84SAndroid Build Coastguard Worker if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
2422*cf5a6c84SAndroid Build Coastguard Worker != XZ_STREAM_END)
2423*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2424*cf5a6c84SAndroid Build Coastguard Worker
2425*cf5a6c84SAndroid Build Coastguard Worker s->block_header.uncompressed = s->vli;
2426*cf5a6c84SAndroid Build Coastguard Worker } else {
2427*cf5a6c84SAndroid Build Coastguard Worker s->block_header.uncompressed = VLI_UNKNOWN;
2428*cf5a6c84SAndroid Build Coastguard Worker }
2429*cf5a6c84SAndroid Build Coastguard Worker
2430*cf5a6c84SAndroid Build Coastguard Worker /* If there are two filters, the first one must be a BCJ filter. */
2431*cf5a6c84SAndroid Build Coastguard Worker s->bcj_active = s->temp.buf[1] & 0x01;
2432*cf5a6c84SAndroid Build Coastguard Worker if (s->bcj_active) {
2433*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size - s->temp.pos < 2)
2434*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2435*cf5a6c84SAndroid Build Coastguard Worker
2436*cf5a6c84SAndroid Build Coastguard Worker ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
2437*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_OK)
2438*cf5a6c84SAndroid Build Coastguard Worker return ret;
2439*cf5a6c84SAndroid Build Coastguard Worker
2440*cf5a6c84SAndroid Build Coastguard Worker /*
2441*cf5a6c84SAndroid Build Coastguard Worker * We don't support custom start offset,
2442*cf5a6c84SAndroid Build Coastguard Worker * so Size of Properties must be zero.
2443*cf5a6c84SAndroid Build Coastguard Worker */
2444*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[s->temp.pos++])
2445*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2446*cf5a6c84SAndroid Build Coastguard Worker }
2447*cf5a6c84SAndroid Build Coastguard Worker
2448*cf5a6c84SAndroid Build Coastguard Worker /* Valid Filter Flags always take at least two bytes. */
2449*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size - s->temp.pos < 2)
2450*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2451*cf5a6c84SAndroid Build Coastguard Worker
2452*cf5a6c84SAndroid Build Coastguard Worker /* Filter ID = LZMA2 */
2453*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[s->temp.pos++] != 0x21)
2454*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2455*cf5a6c84SAndroid Build Coastguard Worker
2456*cf5a6c84SAndroid Build Coastguard Worker /* Size of Properties = 1-byte Filter Properties */
2457*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[s->temp.pos++] != 1)
2458*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2459*cf5a6c84SAndroid Build Coastguard Worker
2460*cf5a6c84SAndroid Build Coastguard Worker /* Filter Properties contains LZMA2 dictionary size. */
2461*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.size - s->temp.pos < 1)
2462*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2463*cf5a6c84SAndroid Build Coastguard Worker
2464*cf5a6c84SAndroid Build Coastguard Worker ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
2465*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_OK)
2466*cf5a6c84SAndroid Build Coastguard Worker return ret;
2467*cf5a6c84SAndroid Build Coastguard Worker
2468*cf5a6c84SAndroid Build Coastguard Worker /* The rest must be Header Padding. */
2469*cf5a6c84SAndroid Build Coastguard Worker while (s->temp.pos < s->temp.size)
2470*cf5a6c84SAndroid Build Coastguard Worker if (s->temp.buf[s->temp.pos++])
2471*cf5a6c84SAndroid Build Coastguard Worker return XZ_OPTIONS_ERROR;
2472*cf5a6c84SAndroid Build Coastguard Worker
2473*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos = 0;
2474*cf5a6c84SAndroid Build Coastguard Worker s->block.compressed = 0;
2475*cf5a6c84SAndroid Build Coastguard Worker s->block.uncompressed = 0;
2476*cf5a6c84SAndroid Build Coastguard Worker
2477*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2478*cf5a6c84SAndroid Build Coastguard Worker }
2479*cf5a6c84SAndroid Build Coastguard Worker
dec_main(struct xz_dec * s,struct xz_buf * b)2480*cf5a6c84SAndroid Build Coastguard Worker static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
2481*cf5a6c84SAndroid Build Coastguard Worker {
2482*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2483*cf5a6c84SAndroid Build Coastguard Worker
2484*cf5a6c84SAndroid Build Coastguard Worker /*
2485*cf5a6c84SAndroid Build Coastguard Worker * Store the start position for the case when we are in the middle
2486*cf5a6c84SAndroid Build Coastguard Worker * of the Index field.
2487*cf5a6c84SAndroid Build Coastguard Worker */
2488*cf5a6c84SAndroid Build Coastguard Worker s->in_start = b->in_pos;
2489*cf5a6c84SAndroid Build Coastguard Worker
2490*cf5a6c84SAndroid Build Coastguard Worker for (;;) {
2491*cf5a6c84SAndroid Build Coastguard Worker switch (s->sequence) {
2492*cf5a6c84SAndroid Build Coastguard Worker case SEQ_STREAM_HEADER:
2493*cf5a6c84SAndroid Build Coastguard Worker /*
2494*cf5a6c84SAndroid Build Coastguard Worker * Stream Header is copied to s->temp, and then
2495*cf5a6c84SAndroid Build Coastguard Worker * decoded from there. This way if the caller
2496*cf5a6c84SAndroid Build Coastguard Worker * gives us only little input at a time, we can
2497*cf5a6c84SAndroid Build Coastguard Worker * still keep the Stream Header decoding code
2498*cf5a6c84SAndroid Build Coastguard Worker * simple. Similar approach is used in many places
2499*cf5a6c84SAndroid Build Coastguard Worker * in this file.
2500*cf5a6c84SAndroid Build Coastguard Worker */
2501*cf5a6c84SAndroid Build Coastguard Worker if (!fill_temp(s, b))
2502*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2503*cf5a6c84SAndroid Build Coastguard Worker
2504*cf5a6c84SAndroid Build Coastguard Worker /*
2505*cf5a6c84SAndroid Build Coastguard Worker * If dec_stream_header() returns
2506*cf5a6c84SAndroid Build Coastguard Worker * XZ_UNSUPPORTED_CHECK, it is still possible
2507*cf5a6c84SAndroid Build Coastguard Worker * to continue decoding if working in multi-call
2508*cf5a6c84SAndroid Build Coastguard Worker * mode. Thus, update s->sequence before calling
2509*cf5a6c84SAndroid Build Coastguard Worker * dec_stream_header().
2510*cf5a6c84SAndroid Build Coastguard Worker */
2511*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_START;
2512*cf5a6c84SAndroid Build Coastguard Worker
2513*cf5a6c84SAndroid Build Coastguard Worker ret = dec_stream_header(s);
2514*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_OK)
2515*cf5a6c84SAndroid Build Coastguard Worker return ret;
2516*cf5a6c84SAndroid Build Coastguard Worker
2517*cf5a6c84SAndroid Build Coastguard Worker case SEQ_BLOCK_START:
2518*cf5a6c84SAndroid Build Coastguard Worker /* We need one byte of input to continue. */
2519*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size)
2520*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2521*cf5a6c84SAndroid Build Coastguard Worker
2522*cf5a6c84SAndroid Build Coastguard Worker /* See if this is the beginning of the Index field. */
2523*cf5a6c84SAndroid Build Coastguard Worker if (!b->in[b->in_pos]) {
2524*cf5a6c84SAndroid Build Coastguard Worker s->in_start = b->in_pos++;
2525*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_INDEX;
2526*cf5a6c84SAndroid Build Coastguard Worker break;
2527*cf5a6c84SAndroid Build Coastguard Worker }
2528*cf5a6c84SAndroid Build Coastguard Worker
2529*cf5a6c84SAndroid Build Coastguard Worker /*
2530*cf5a6c84SAndroid Build Coastguard Worker * Calculate the size of the Block Header and
2531*cf5a6c84SAndroid Build Coastguard Worker * prepare to decode it.
2532*cf5a6c84SAndroid Build Coastguard Worker */
2533*cf5a6c84SAndroid Build Coastguard Worker s->block_header.size
2534*cf5a6c84SAndroid Build Coastguard Worker = ((unsigned)b->in[b->in_pos] + 1) * 4;
2535*cf5a6c84SAndroid Build Coastguard Worker
2536*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = s->block_header.size;
2537*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos = 0;
2538*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_HEADER;
2539*cf5a6c84SAndroid Build Coastguard Worker
2540*cf5a6c84SAndroid Build Coastguard Worker case SEQ_BLOCK_HEADER:
2541*cf5a6c84SAndroid Build Coastguard Worker if (!fill_temp(s, b))
2542*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2543*cf5a6c84SAndroid Build Coastguard Worker
2544*cf5a6c84SAndroid Build Coastguard Worker ret = dec_block_header(s);
2545*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_OK)
2546*cf5a6c84SAndroid Build Coastguard Worker return ret;
2547*cf5a6c84SAndroid Build Coastguard Worker
2548*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_UNCOMPRESS;
2549*cf5a6c84SAndroid Build Coastguard Worker
2550*cf5a6c84SAndroid Build Coastguard Worker case SEQ_BLOCK_UNCOMPRESS:
2551*cf5a6c84SAndroid Build Coastguard Worker ret = dec_block(s, b);
2552*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END)
2553*cf5a6c84SAndroid Build Coastguard Worker return ret;
2554*cf5a6c84SAndroid Build Coastguard Worker
2555*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_PADDING;
2556*cf5a6c84SAndroid Build Coastguard Worker
2557*cf5a6c84SAndroid Build Coastguard Worker case SEQ_BLOCK_PADDING:
2558*cf5a6c84SAndroid Build Coastguard Worker /*
2559*cf5a6c84SAndroid Build Coastguard Worker * Size of Compressed Data + Block Padding
2560*cf5a6c84SAndroid Build Coastguard Worker * must be a multiple of four. We don't need
2561*cf5a6c84SAndroid Build Coastguard Worker * s->block.compressed for anything else
2562*cf5a6c84SAndroid Build Coastguard Worker * anymore, so we use it here to test the size
2563*cf5a6c84SAndroid Build Coastguard Worker * of the Block Padding field.
2564*cf5a6c84SAndroid Build Coastguard Worker */
2565*cf5a6c84SAndroid Build Coastguard Worker while (s->block.compressed & 3) {
2566*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size)
2567*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2568*cf5a6c84SAndroid Build Coastguard Worker
2569*cf5a6c84SAndroid Build Coastguard Worker if (b->in[b->in_pos++])
2570*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2571*cf5a6c84SAndroid Build Coastguard Worker
2572*cf5a6c84SAndroid Build Coastguard Worker ++s->block.compressed;
2573*cf5a6c84SAndroid Build Coastguard Worker }
2574*cf5a6c84SAndroid Build Coastguard Worker
2575*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_CHECK;
2576*cf5a6c84SAndroid Build Coastguard Worker
2577*cf5a6c84SAndroid Build Coastguard Worker case SEQ_BLOCK_CHECK:
2578*cf5a6c84SAndroid Build Coastguard Worker if (s->check_type == XZ_CHECK_CRC32) {
2579*cf5a6c84SAndroid Build Coastguard Worker ret = crc_validate(s, b, 32);
2580*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END)
2581*cf5a6c84SAndroid Build Coastguard Worker return ret;
2582*cf5a6c84SAndroid Build Coastguard Worker }
2583*cf5a6c84SAndroid Build Coastguard Worker else if (s->check_type == XZ_CHECK_CRC64) {
2584*cf5a6c84SAndroid Build Coastguard Worker ret = crc_validate(s, b, 64);
2585*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END)
2586*cf5a6c84SAndroid Build Coastguard Worker return ret;
2587*cf5a6c84SAndroid Build Coastguard Worker }
2588*cf5a6c84SAndroid Build Coastguard Worker else if (!check_skip(s, b)) {
2589*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2590*cf5a6c84SAndroid Build Coastguard Worker }
2591*cf5a6c84SAndroid Build Coastguard Worker
2592*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_BLOCK_START;
2593*cf5a6c84SAndroid Build Coastguard Worker break;
2594*cf5a6c84SAndroid Build Coastguard Worker
2595*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX:
2596*cf5a6c84SAndroid Build Coastguard Worker ret = dec_index(s, b);
2597*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END)
2598*cf5a6c84SAndroid Build Coastguard Worker return ret;
2599*cf5a6c84SAndroid Build Coastguard Worker
2600*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_INDEX_PADDING;
2601*cf5a6c84SAndroid Build Coastguard Worker
2602*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX_PADDING:
2603*cf5a6c84SAndroid Build Coastguard Worker while ((s->index.size + (b->in_pos - s->in_start))
2604*cf5a6c84SAndroid Build Coastguard Worker & 3) {
2605*cf5a6c84SAndroid Build Coastguard Worker if (b->in_pos == b->in_size) {
2606*cf5a6c84SAndroid Build Coastguard Worker index_update(s, b);
2607*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2608*cf5a6c84SAndroid Build Coastguard Worker }
2609*cf5a6c84SAndroid Build Coastguard Worker
2610*cf5a6c84SAndroid Build Coastguard Worker if (b->in[b->in_pos++])
2611*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2612*cf5a6c84SAndroid Build Coastguard Worker }
2613*cf5a6c84SAndroid Build Coastguard Worker
2614*cf5a6c84SAndroid Build Coastguard Worker /* Finish the CRC32 value and Index size. */
2615*cf5a6c84SAndroid Build Coastguard Worker index_update(s, b);
2616*cf5a6c84SAndroid Build Coastguard Worker
2617*cf5a6c84SAndroid Build Coastguard Worker /* Compare the hashes to validate the Index field. */
2618*cf5a6c84SAndroid Build Coastguard Worker if (!memeq(&s->block.hash, &s->index.hash,
2619*cf5a6c84SAndroid Build Coastguard Worker sizeof(s->block.hash)))
2620*cf5a6c84SAndroid Build Coastguard Worker return XZ_DATA_ERROR;
2621*cf5a6c84SAndroid Build Coastguard Worker
2622*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_INDEX_CRC32;
2623*cf5a6c84SAndroid Build Coastguard Worker
2624*cf5a6c84SAndroid Build Coastguard Worker case SEQ_INDEX_CRC32:
2625*cf5a6c84SAndroid Build Coastguard Worker ret = crc_validate(s, b, 32);
2626*cf5a6c84SAndroid Build Coastguard Worker if (ret != XZ_STREAM_END)
2627*cf5a6c84SAndroid Build Coastguard Worker return ret;
2628*cf5a6c84SAndroid Build Coastguard Worker
2629*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = STREAM_HEADER_SIZE;
2630*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_STREAM_FOOTER;
2631*cf5a6c84SAndroid Build Coastguard Worker
2632*cf5a6c84SAndroid Build Coastguard Worker case SEQ_STREAM_FOOTER:
2633*cf5a6c84SAndroid Build Coastguard Worker if (!fill_temp(s, b))
2634*cf5a6c84SAndroid Build Coastguard Worker return XZ_OK;
2635*cf5a6c84SAndroid Build Coastguard Worker
2636*cf5a6c84SAndroid Build Coastguard Worker return dec_stream_footer(s);
2637*cf5a6c84SAndroid Build Coastguard Worker }
2638*cf5a6c84SAndroid Build Coastguard Worker }
2639*cf5a6c84SAndroid Build Coastguard Worker
2640*cf5a6c84SAndroid Build Coastguard Worker /* Never reached */
2641*cf5a6c84SAndroid Build Coastguard Worker }
2642*cf5a6c84SAndroid Build Coastguard Worker
2643*cf5a6c84SAndroid Build Coastguard Worker /*
2644*cf5a6c84SAndroid Build Coastguard Worker * xz_dec_run() - Run the XZ decoder
2645*cf5a6c84SAndroid Build Coastguard Worker * @s: Decoder state allocated using xz_dec_init()
2646*cf5a6c84SAndroid Build Coastguard Worker * @b: Input and output buffers
2647*cf5a6c84SAndroid Build Coastguard Worker *
2648*cf5a6c84SAndroid Build Coastguard Worker * The possible return values depend on build options and operation mode.
2649*cf5a6c84SAndroid Build Coastguard Worker * See enum xz_ret for details.
2650*cf5a6c84SAndroid Build Coastguard Worker *
2651*cf5a6c84SAndroid Build Coastguard Worker * Note that if an error occurs in single-call mode (return value is not
2652*cf5a6c84SAndroid Build Coastguard Worker * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
2653*cf5a6c84SAndroid Build Coastguard Worker * contents of the output buffer from b->out[b->out_pos] onward are
2654*cf5a6c84SAndroid Build Coastguard Worker * undefined. This is true even after XZ_BUF_ERROR, because with some filter
2655*cf5a6c84SAndroid Build Coastguard Worker * chains, there may be a second pass over the output buffer, and this pass
2656*cf5a6c84SAndroid Build Coastguard Worker * cannot be properly done if the output buffer is truncated. Thus, you
2657*cf5a6c84SAndroid Build Coastguard Worker * cannot give the single-call decoder a too small buffer and then expect to
2658*cf5a6c84SAndroid Build Coastguard Worker * get that amount valid data from the beginning of the stream. You must use
2659*cf5a6c84SAndroid Build Coastguard Worker * the multi-call decoder if you don't want to uncompress the whole stream.
2660*cf5a6c84SAndroid Build Coastguard Worker *
2661*cf5a6c84SAndroid Build Coastguard Worker * xz_dec_run() is a wrapper for dec_main() to handle some special cases in
2662*cf5a6c84SAndroid Build Coastguard Worker * multi-call and single-call decoding.
2663*cf5a6c84SAndroid Build Coastguard Worker *
2664*cf5a6c84SAndroid Build Coastguard Worker * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we
2665*cf5a6c84SAndroid Build Coastguard Worker * are not going to make any progress anymore. This is to prevent the caller
2666*cf5a6c84SAndroid Build Coastguard Worker * from calling us infinitely when the input file is truncated or otherwise
2667*cf5a6c84SAndroid Build Coastguard Worker * corrupt. Since zlib-style API allows that the caller fills the input buffer
2668*cf5a6c84SAndroid Build Coastguard Worker * only when the decoder doesn't produce any new output, we have to be careful
2669*cf5a6c84SAndroid Build Coastguard Worker * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only
2670*cf5a6c84SAndroid Build Coastguard Worker * after the second consecutive call to xz_dec_run() that makes no progress.
2671*cf5a6c84SAndroid Build Coastguard Worker *
2672*cf5a6c84SAndroid Build Coastguard Worker * In single-call mode, if we couldn't decode everything and no error
2673*cf5a6c84SAndroid Build Coastguard Worker * occurred, either the input is truncated or the output buffer is too small.
2674*cf5a6c84SAndroid Build Coastguard Worker * Since we know that the last input byte never produces any output, we know
2675*cf5a6c84SAndroid Build Coastguard Worker * that if all the input was consumed and decoding wasn't finished, the file
2676*cf5a6c84SAndroid Build Coastguard Worker * must be corrupt. Otherwise the output buffer has to be too small or the
2677*cf5a6c84SAndroid Build Coastguard Worker * file is corrupt in a way that decoding it produces too big output.
2678*cf5a6c84SAndroid Build Coastguard Worker *
2679*cf5a6c84SAndroid Build Coastguard Worker * If single-call decoding fails, we reset b->in_pos and b->out_pos back to
2680*cf5a6c84SAndroid Build Coastguard Worker * their original values. This is because with some filter chains there won't
2681*cf5a6c84SAndroid Build Coastguard Worker * be any valid uncompressed data in the output buffer unless the decoding
2682*cf5a6c84SAndroid Build Coastguard Worker * actually succeeds (that's the price to pay of using the output buffer as
2683*cf5a6c84SAndroid Build Coastguard Worker * the workspace).
2684*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_run(struct xz_dec * s,struct xz_buf * b)2685*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
2686*cf5a6c84SAndroid Build Coastguard Worker {
2687*cf5a6c84SAndroid Build Coastguard Worker size_t in_start;
2688*cf5a6c84SAndroid Build Coastguard Worker size_t out_start;
2689*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2690*cf5a6c84SAndroid Build Coastguard Worker
2691*cf5a6c84SAndroid Build Coastguard Worker in_start = b->in_pos;
2692*cf5a6c84SAndroid Build Coastguard Worker out_start = b->out_pos;
2693*cf5a6c84SAndroid Build Coastguard Worker ret = dec_main(s, b);
2694*cf5a6c84SAndroid Build Coastguard Worker
2695*cf5a6c84SAndroid Build Coastguard Worker if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos) {
2696*cf5a6c84SAndroid Build Coastguard Worker if (s->allow_buf_error)
2697*cf5a6c84SAndroid Build Coastguard Worker ret = XZ_BUF_ERROR;
2698*cf5a6c84SAndroid Build Coastguard Worker
2699*cf5a6c84SAndroid Build Coastguard Worker s->allow_buf_error = 1;
2700*cf5a6c84SAndroid Build Coastguard Worker } else {
2701*cf5a6c84SAndroid Build Coastguard Worker s->allow_buf_error = 0;
2702*cf5a6c84SAndroid Build Coastguard Worker }
2703*cf5a6c84SAndroid Build Coastguard Worker
2704*cf5a6c84SAndroid Build Coastguard Worker return ret;
2705*cf5a6c84SAndroid Build Coastguard Worker }
2706*cf5a6c84SAndroid Build Coastguard Worker
2707*cf5a6c84SAndroid Build Coastguard Worker /**
2708*cf5a6c84SAndroid Build Coastguard Worker * xz_dec_reset() - Reset an already allocated decoder state
2709*cf5a6c84SAndroid Build Coastguard Worker * @s: Decoder state allocated using xz_dec_init()
2710*cf5a6c84SAndroid Build Coastguard Worker *
2711*cf5a6c84SAndroid Build Coastguard Worker * This function can be used to reset the multi-call decoder state without
2712*cf5a6c84SAndroid Build Coastguard Worker * freeing and reallocating memory with xz_dec_end() and xz_dec_init().
2713*cf5a6c84SAndroid Build Coastguard Worker *
2714*cf5a6c84SAndroid Build Coastguard Worker * In single-call mode, xz_dec_reset() is always called in the beginning of
2715*cf5a6c84SAndroid Build Coastguard Worker * xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in
2716*cf5a6c84SAndroid Build Coastguard Worker * multi-call mode.
2717*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_reset(struct xz_dec * s)2718*cf5a6c84SAndroid Build Coastguard Worker void xz_dec_reset(struct xz_dec *s)
2719*cf5a6c84SAndroid Build Coastguard Worker {
2720*cf5a6c84SAndroid Build Coastguard Worker s->sequence = SEQ_STREAM_HEADER;
2721*cf5a6c84SAndroid Build Coastguard Worker s->allow_buf_error = 0;
2722*cf5a6c84SAndroid Build Coastguard Worker s->pos = 0;
2723*cf5a6c84SAndroid Build Coastguard Worker s->crc = 0;
2724*cf5a6c84SAndroid Build Coastguard Worker memset(&s->block, 0, sizeof(s->block));
2725*cf5a6c84SAndroid Build Coastguard Worker memset(&s->index, 0, sizeof(s->index));
2726*cf5a6c84SAndroid Build Coastguard Worker s->temp.pos = 0;
2727*cf5a6c84SAndroid Build Coastguard Worker s->temp.size = STREAM_HEADER_SIZE;
2728*cf5a6c84SAndroid Build Coastguard Worker }
2729*cf5a6c84SAndroid Build Coastguard Worker
2730*cf5a6c84SAndroid Build Coastguard Worker /**
2731*cf5a6c84SAndroid Build Coastguard Worker * Allocate and initialize a XZ decoder state
2732*cf5a6c84SAndroid Build Coastguard Worker * @mode: Operation mode
2733*cf5a6c84SAndroid Build Coastguard Worker * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for
2734*cf5a6c84SAndroid Build Coastguard Worker * multi-call decoding. LZMA2 dictionary is always 2^n bytes
2735*cf5a6c84SAndroid Build Coastguard Worker * or 2^n + 2^(n-1) bytes (the latter sizes are less common
2736*cf5a6c84SAndroid Build Coastguard Worker * in practice), so other values for dict_max don't make sense.
2737*cf5a6c84SAndroid Build Coastguard Worker * In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB,
2738*cf5a6c84SAndroid Build Coastguard Worker * 512 KiB, and 1 MiB are probably the only reasonable values,
2739*cf5a6c84SAndroid Build Coastguard Worker * except for kernel and initramfs images where a bigger
2740*cf5a6c84SAndroid Build Coastguard Worker * dictionary can be fine and useful.
2741*cf5a6c84SAndroid Build Coastguard Worker *
2742*cf5a6c84SAndroid Build Coastguard Worker * dict_max specifies the maximum allowed dictionary size that xz_dec_run()
2743*cf5a6c84SAndroid Build Coastguard Worker * may allocate once it has parsed the dictionary size from the stream
2744*cf5a6c84SAndroid Build Coastguard Worker * headers. This way excessive allocations can be avoided while still
2745*cf5a6c84SAndroid Build Coastguard Worker * limiting the maximum memory usage to a sane value to prevent running the
2746*cf5a6c84SAndroid Build Coastguard Worker * system out of memory when decompressing streams from untrusted sources.
2747*cf5a6c84SAndroid Build Coastguard Worker *
2748*cf5a6c84SAndroid Build Coastguard Worker * returns NULL on failure.
2749*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_init(unsigned dict_max)2750*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec *xz_dec_init(unsigned dict_max)
2751*cf5a6c84SAndroid Build Coastguard Worker {
2752*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec *s = malloc(sizeof(*s));
2753*cf5a6c84SAndroid Build Coastguard Worker if (!s)
2754*cf5a6c84SAndroid Build Coastguard Worker return NULL;
2755*cf5a6c84SAndroid Build Coastguard Worker
2756*cf5a6c84SAndroid Build Coastguard Worker s->bcj = malloc(sizeof(*s->bcj));
2757*cf5a6c84SAndroid Build Coastguard Worker if (!s->bcj)
2758*cf5a6c84SAndroid Build Coastguard Worker goto error_bcj;
2759*cf5a6c84SAndroid Build Coastguard Worker
2760*cf5a6c84SAndroid Build Coastguard Worker s->lzma2 = xz_dec_lzma2_create(dict_max);
2761*cf5a6c84SAndroid Build Coastguard Worker if (!s->lzma2)
2762*cf5a6c84SAndroid Build Coastguard Worker goto error_lzma2;
2763*cf5a6c84SAndroid Build Coastguard Worker
2764*cf5a6c84SAndroid Build Coastguard Worker xz_dec_reset(s);
2765*cf5a6c84SAndroid Build Coastguard Worker return s;
2766*cf5a6c84SAndroid Build Coastguard Worker
2767*cf5a6c84SAndroid Build Coastguard Worker error_lzma2:
2768*cf5a6c84SAndroid Build Coastguard Worker free(s->bcj);
2769*cf5a6c84SAndroid Build Coastguard Worker error_bcj:
2770*cf5a6c84SAndroid Build Coastguard Worker free(s);
2771*cf5a6c84SAndroid Build Coastguard Worker return NULL;
2772*cf5a6c84SAndroid Build Coastguard Worker }
2773*cf5a6c84SAndroid Build Coastguard Worker
2774*cf5a6c84SAndroid Build Coastguard Worker /**
2775*cf5a6c84SAndroid Build Coastguard Worker * xz_dec_end() - Free the memory allocated for the decoder state
2776*cf5a6c84SAndroid Build Coastguard Worker * @s: Decoder state allocated using xz_dec_init(). If s is NULL,
2777*cf5a6c84SAndroid Build Coastguard Worker * this function does nothing.
2778*cf5a6c84SAndroid Build Coastguard Worker */
xz_dec_end(struct xz_dec * s)2779*cf5a6c84SAndroid Build Coastguard Worker void xz_dec_end(struct xz_dec *s)
2780*cf5a6c84SAndroid Build Coastguard Worker {
2781*cf5a6c84SAndroid Build Coastguard Worker if (s) {
2782*cf5a6c84SAndroid Build Coastguard Worker free((s->lzma2)->dict.buf);
2783*cf5a6c84SAndroid Build Coastguard Worker free(s->lzma2);
2784*cf5a6c84SAndroid Build Coastguard Worker
2785*cf5a6c84SAndroid Build Coastguard Worker free(s->bcj);
2786*cf5a6c84SAndroid Build Coastguard Worker free(s);
2787*cf5a6c84SAndroid Build Coastguard Worker }
2788*cf5a6c84SAndroid Build Coastguard Worker }
2789*cf5a6c84SAndroid Build Coastguard Worker
2790*cf5a6c84SAndroid Build Coastguard Worker static char in[BUFSIZ];
2791*cf5a6c84SAndroid Build Coastguard Worker static char out[BUFSIZ];
2792*cf5a6c84SAndroid Build Coastguard Worker
do_xzcat(int fd,char * name)2793*cf5a6c84SAndroid Build Coastguard Worker void do_xzcat(int fd, char *name)
2794*cf5a6c84SAndroid Build Coastguard Worker {
2795*cf5a6c84SAndroid Build Coastguard Worker struct xz_buf b;
2796*cf5a6c84SAndroid Build Coastguard Worker struct xz_dec *s;
2797*cf5a6c84SAndroid Build Coastguard Worker enum xz_ret ret;
2798*cf5a6c84SAndroid Build Coastguard Worker const char *msg;
2799*cf5a6c84SAndroid Build Coastguard Worker
2800*cf5a6c84SAndroid Build Coastguard Worker crc_init(xz_crc32_table, 1);
2801*cf5a6c84SAndroid Build Coastguard Worker const uint64_t poly = 0xC96C5795D7870F42ULL;
2802*cf5a6c84SAndroid Build Coastguard Worker unsigned i;
2803*cf5a6c84SAndroid Build Coastguard Worker unsigned j;
2804*cf5a6c84SAndroid Build Coastguard Worker uint64_t r;
2805*cf5a6c84SAndroid Build Coastguard Worker
2806*cf5a6c84SAndroid Build Coastguard Worker char *errors[] = {
2807*cf5a6c84SAndroid Build Coastguard Worker "Memory allocation failed",
2808*cf5a6c84SAndroid Build Coastguard Worker "Memory usage limit reached",
2809*cf5a6c84SAndroid Build Coastguard Worker "Not a .xz file",
2810*cf5a6c84SAndroid Build Coastguard Worker "Unsupported options in the .xz headers",
2811*cf5a6c84SAndroid Build Coastguard Worker // 2 things in the enum xz_ret use this
2812*cf5a6c84SAndroid Build Coastguard Worker "File is corrupt",
2813*cf5a6c84SAndroid Build Coastguard Worker "File is corrupt",
2814*cf5a6c84SAndroid Build Coastguard Worker };
2815*cf5a6c84SAndroid Build Coastguard Worker
2816*cf5a6c84SAndroid Build Coastguard Worker /* initialize CRC64 table*/
2817*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i < 256; ++i) {
2818*cf5a6c84SAndroid Build Coastguard Worker r = i;
2819*cf5a6c84SAndroid Build Coastguard Worker for (j = 0; j < 8; ++j)
2820*cf5a6c84SAndroid Build Coastguard Worker r = (r >> 1) ^ (poly & ~((r & 1) - 1));
2821*cf5a6c84SAndroid Build Coastguard Worker
2822*cf5a6c84SAndroid Build Coastguard Worker xz_crc64_table[i] = r;
2823*cf5a6c84SAndroid Build Coastguard Worker }
2824*cf5a6c84SAndroid Build Coastguard Worker
2825*cf5a6c84SAndroid Build Coastguard Worker /*
2826*cf5a6c84SAndroid Build Coastguard Worker * Support up to 64 MiB dictionary. The actually needed memory
2827*cf5a6c84SAndroid Build Coastguard Worker * is allocated once the headers have been parsed.
2828*cf5a6c84SAndroid Build Coastguard Worker */
2829*cf5a6c84SAndroid Build Coastguard Worker s = xz_dec_init(1 << 26);
2830*cf5a6c84SAndroid Build Coastguard Worker if (!s) {
2831*cf5a6c84SAndroid Build Coastguard Worker msg = "Memory allocation failed\n";
2832*cf5a6c84SAndroid Build Coastguard Worker goto error;
2833*cf5a6c84SAndroid Build Coastguard Worker }
2834*cf5a6c84SAndroid Build Coastguard Worker
2835*cf5a6c84SAndroid Build Coastguard Worker b.in = in;
2836*cf5a6c84SAndroid Build Coastguard Worker b.in_pos = 0;
2837*cf5a6c84SAndroid Build Coastguard Worker b.in_size = 0;
2838*cf5a6c84SAndroid Build Coastguard Worker b.out = out;
2839*cf5a6c84SAndroid Build Coastguard Worker b.out_pos = 0;
2840*cf5a6c84SAndroid Build Coastguard Worker b.out_size = BUFSIZ;
2841*cf5a6c84SAndroid Build Coastguard Worker
2842*cf5a6c84SAndroid Build Coastguard Worker for (;;) {
2843*cf5a6c84SAndroid Build Coastguard Worker if (b.in_pos == b.in_size) {
2844*cf5a6c84SAndroid Build Coastguard Worker b.in_size = read(fd, in, sizeof(in));
2845*cf5a6c84SAndroid Build Coastguard Worker b.in_pos = 0;
2846*cf5a6c84SAndroid Build Coastguard Worker }
2847*cf5a6c84SAndroid Build Coastguard Worker
2848*cf5a6c84SAndroid Build Coastguard Worker ret = xz_dec_run(s, &b);
2849*cf5a6c84SAndroid Build Coastguard Worker
2850*cf5a6c84SAndroid Build Coastguard Worker if (b.out_pos == sizeof(out)) {
2851*cf5a6c84SAndroid Build Coastguard Worker if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
2852*cf5a6c84SAndroid Build Coastguard Worker msg = "Write error\n";
2853*cf5a6c84SAndroid Build Coastguard Worker goto error;
2854*cf5a6c84SAndroid Build Coastguard Worker }
2855*cf5a6c84SAndroid Build Coastguard Worker
2856*cf5a6c84SAndroid Build Coastguard Worker b.out_pos = 0;
2857*cf5a6c84SAndroid Build Coastguard Worker }
2858*cf5a6c84SAndroid Build Coastguard Worker
2859*cf5a6c84SAndroid Build Coastguard Worker if (ret == XZ_OK || ret == XZ_UNSUPPORTED_CHECK)
2860*cf5a6c84SAndroid Build Coastguard Worker continue;
2861*cf5a6c84SAndroid Build Coastguard Worker
2862*cf5a6c84SAndroid Build Coastguard Worker if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
2863*cf5a6c84SAndroid Build Coastguard Worker msg = "Write error\n";
2864*cf5a6c84SAndroid Build Coastguard Worker goto error;
2865*cf5a6c84SAndroid Build Coastguard Worker }
2866*cf5a6c84SAndroid Build Coastguard Worker
2867*cf5a6c84SAndroid Build Coastguard Worker if (ret == XZ_STREAM_END) {
2868*cf5a6c84SAndroid Build Coastguard Worker xz_dec_end(s);
2869*cf5a6c84SAndroid Build Coastguard Worker return;
2870*cf5a6c84SAndroid Build Coastguard Worker }
2871*cf5a6c84SAndroid Build Coastguard Worker
2872*cf5a6c84SAndroid Build Coastguard Worker msg = (ret-3 < ARRAY_LEN(errors)) ? errors[ret-3] : "Bug!";
2873*cf5a6c84SAndroid Build Coastguard Worker goto error;
2874*cf5a6c84SAndroid Build Coastguard Worker }
2875*cf5a6c84SAndroid Build Coastguard Worker
2876*cf5a6c84SAndroid Build Coastguard Worker error:
2877*cf5a6c84SAndroid Build Coastguard Worker xz_dec_end(s);
2878*cf5a6c84SAndroid Build Coastguard Worker error_exit("%s", msg);
2879*cf5a6c84SAndroid Build Coastguard Worker }
2880*cf5a6c84SAndroid Build Coastguard Worker
xzcat_main(void)2881*cf5a6c84SAndroid Build Coastguard Worker void xzcat_main(void)
2882*cf5a6c84SAndroid Build Coastguard Worker {
2883*cf5a6c84SAndroid Build Coastguard Worker loopfiles(toys.optargs, do_xzcat);
2884*cf5a6c84SAndroid Build Coastguard Worker }
2885