1228753Smm/*-
2231200Smm * Copyright (c) 2009-2011 Michihiro NAKAJIMA
3228753Smm * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna
4228753Smm * All rights reserved.
5228753Smm *
6228753Smm * Redistribution and use in source and binary forms, with or without
7228753Smm * modification, are permitted provided that the following conditions
8228753Smm * are met:
9228753Smm * 1. Redistributions of source code must retain the above copyright
10228753Smm *    notice, this list of conditions and the following disclaimer.
11228753Smm * 2. Redistributions in binary form must reproduce the above copyright
12228753Smm *    notice, this list of conditions and the following disclaimer in the
13228753Smm *    documentation and/or other materials provided with the distribution.
14228753Smm *
15228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25228753Smm */
26228753Smm
27228753Smm#include "archive_platform.h"
28228753Smm
29231200Smm__FBSDID("$FreeBSD$");
30228753Smm
31228753Smm#ifdef HAVE_ERRNO_H
32228753Smm#include <errno.h>
33228753Smm#endif
34228753Smm#include <stdio.h>
35228753Smm#ifdef HAVE_STDLIB_H
36228753Smm#include <stdlib.h>
37228753Smm#endif
38228753Smm#ifdef HAVE_STRING_H
39228753Smm#include <string.h>
40228753Smm#endif
41228753Smm#ifdef HAVE_UNISTD_H
42228753Smm#include <unistd.h>
43228753Smm#endif
44228753Smm#if HAVE_LZMA_H
45228753Smm#include <lzma.h>
46228753Smm#elif HAVE_LZMADEC_H
47228753Smm#include <lzmadec.h>
48228753Smm#endif
49228753Smm
50228753Smm#include "archive.h"
51228753Smm#include "archive_endian.h"
52228753Smm#include "archive_private.h"
53228753Smm#include "archive_read_private.h"
54228753Smm
55228753Smm#if HAVE_LZMA_H && HAVE_LIBLZMA
56228753Smm
57228753Smmstruct private_data {
58228753Smm	lzma_stream	 stream;
59228753Smm	unsigned char	*out_block;
60228753Smm	size_t		 out_block_size;
61228753Smm	int64_t		 total_out;
62228753Smm	char		 eof; /* True = found end of compressed data. */
63231200Smm	char		 in_stream;
64231200Smm
65231200Smm	/* Following variables are used for lzip only. */
66231200Smm	char		 lzip_ver;
67231200Smm	uint32_t	 crc32;
68231200Smm	int64_t		 member_in;
69231200Smm	int64_t		 member_out;
70228753Smm};
71228753Smm
72231200Smm#if LZMA_VERSION_MAJOR >= 5
73231200Smm/* Effectively disable the limiter. */
74231200Smm#define LZMA_MEMLIMIT	UINT64_MAX
75231200Smm#else
76231200Smm/* NOTE: This needs to check memory size which running system has. */
77231200Smm#define LZMA_MEMLIMIT	(1U << 30)
78231200Smm#endif
79231200Smm
80231200Smm/* Combined lzip/lzma/xz filter */
81228753Smmstatic ssize_t	xz_filter_read(struct archive_read_filter *, const void **);
82228753Smmstatic int	xz_filter_close(struct archive_read_filter *);
83228753Smmstatic int	xz_lzma_bidder_init(struct archive_read_filter *);
84228753Smm
85228753Smm#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
86228753Smm
87228753Smmstruct private_data {
88228753Smm	lzmadec_stream	 stream;
89228753Smm	unsigned char	*out_block;
90228753Smm	size_t		 out_block_size;
91228753Smm	int64_t		 total_out;
92228753Smm	char		 eof; /* True = found end of compressed data. */
93228753Smm};
94228753Smm
95228753Smm/* Lzma-only filter */
96228753Smmstatic ssize_t	lzma_filter_read(struct archive_read_filter *, const void **);
97228753Smmstatic int	lzma_filter_close(struct archive_read_filter *);
98228753Smm#endif
99228753Smm
100228753Smm/*
101228753Smm * Note that we can detect xz and lzma compressed files even if we
102228753Smm * can't decompress them.  (In fact, we like detecting them because we
103228753Smm * can give better error messages.)  So the bid framework here gets
104228753Smm * compiled even if no lzma library is available.
105228753Smm */
106228753Smmstatic int	xz_bidder_bid(struct archive_read_filter_bidder *,
107228753Smm		    struct archive_read_filter *);
108228753Smmstatic int	xz_bidder_init(struct archive_read_filter *);
109228753Smmstatic int	lzma_bidder_bid(struct archive_read_filter_bidder *,
110228753Smm		    struct archive_read_filter *);
111228753Smmstatic int	lzma_bidder_init(struct archive_read_filter *);
112231200Smmstatic int	lzip_has_member(struct archive_read_filter *);
113231200Smmstatic int	lzip_bidder_bid(struct archive_read_filter_bidder *,
114231200Smm		    struct archive_read_filter *);
115231200Smmstatic int	lzip_bidder_init(struct archive_read_filter *);
116228753Smm
117231200Smm#if ARCHIVE_VERSION_NUMBER < 4000000
118231200Smm/* Deprecated; remove in libarchive 4.0 */
119228753Smmint
120231200Smmarchive_read_support_compression_xz(struct archive *a)
121228753Smm{
122231200Smm	return archive_read_support_filter_xz(a);
123231200Smm}
124231200Smm#endif
125231200Smm
126231200Smmint
127231200Smmarchive_read_support_filter_xz(struct archive *_a)
128231200Smm{
129228753Smm	struct archive_read *a = (struct archive_read *)_a;
130231200Smm	struct archive_read_filter_bidder *bidder;
131228753Smm
132231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
133231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_filter_xz");
134231200Smm
135231200Smm	if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
136228753Smm		return (ARCHIVE_FATAL);
137228753Smm
138228753Smm	bidder->data = NULL;
139248616Smm	bidder->name = "xz";
140228753Smm	bidder->bid = xz_bidder_bid;
141228753Smm	bidder->init = xz_bidder_init;
142228753Smm	bidder->options = NULL;
143228753Smm	bidder->free = NULL;
144228753Smm#if HAVE_LZMA_H && HAVE_LIBLZMA
145228753Smm	return (ARCHIVE_OK);
146228753Smm#else
147228753Smm	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
148248616Smm	    "Using external xz program for xz decompression");
149228753Smm	return (ARCHIVE_WARN);
150228753Smm#endif
151228753Smm}
152228753Smm
153231200Smm#if ARCHIVE_VERSION_NUMBER < 4000000
154228753Smmint
155231200Smmarchive_read_support_compression_lzma(struct archive *a)
156228753Smm{
157231200Smm	return archive_read_support_filter_lzma(a);
158231200Smm}
159231200Smm#endif
160231200Smm
161231200Smmint
162231200Smmarchive_read_support_filter_lzma(struct archive *_a)
163231200Smm{
164228753Smm	struct archive_read *a = (struct archive_read *)_a;
165231200Smm	struct archive_read_filter_bidder *bidder;
166228753Smm
167231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
168231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma");
169231200Smm
170231200Smm	if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
171228753Smm		return (ARCHIVE_FATAL);
172228753Smm
173228753Smm	bidder->data = NULL;
174248616Smm	bidder->name = "lzma";
175228753Smm	bidder->bid = lzma_bidder_bid;
176228753Smm	bidder->init = lzma_bidder_init;
177228753Smm	bidder->options = NULL;
178228753Smm	bidder->free = NULL;
179228753Smm#if HAVE_LZMA_H && HAVE_LIBLZMA
180228753Smm	return (ARCHIVE_OK);
181228753Smm#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
182228753Smm	return (ARCHIVE_OK);
183228753Smm#else
184228753Smm	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
185248616Smm	    "Using external lzma program for lzma decompression");
186228753Smm	return (ARCHIVE_WARN);
187228753Smm#endif
188228753Smm}
189228753Smm
190231200Smm
191231200Smm#if ARCHIVE_VERSION_NUMBER < 4000000
192231200Smmint
193231200Smmarchive_read_support_compression_lzip(struct archive *a)
194231200Smm{
195231200Smm	return archive_read_support_filter_lzip(a);
196231200Smm}
197231200Smm#endif
198231200Smm
199231200Smmint
200231200Smmarchive_read_support_filter_lzip(struct archive *_a)
201231200Smm{
202231200Smm	struct archive_read *a = (struct archive_read *)_a;
203231200Smm	struct archive_read_filter_bidder *bidder;
204231200Smm
205231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
206231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip");
207231200Smm
208231200Smm	if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
209231200Smm		return (ARCHIVE_FATAL);
210231200Smm
211231200Smm	bidder->data = NULL;
212248616Smm	bidder->name = "lzip";
213231200Smm	bidder->bid = lzip_bidder_bid;
214231200Smm	bidder->init = lzip_bidder_init;
215231200Smm	bidder->options = NULL;
216231200Smm	bidder->free = NULL;
217231200Smm#if HAVE_LZMA_H && HAVE_LIBLZMA
218231200Smm	return (ARCHIVE_OK);
219231200Smm#else
220231200Smm	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
221231200Smm	    "Using external lzip program for lzip decompression");
222231200Smm	return (ARCHIVE_WARN);
223231200Smm#endif
224231200Smm}
225231200Smm
226228753Smm/*
227228753Smm * Test whether we can handle this data.
228228753Smm */
229228753Smmstatic int
230228753Smmxz_bidder_bid(struct archive_read_filter_bidder *self,
231228753Smm    struct archive_read_filter *filter)
232228753Smm{
233228753Smm	const unsigned char *buffer;
234228753Smm	ssize_t avail;
235228753Smm
236228753Smm	(void)self; /* UNUSED */
237228753Smm
238228753Smm	buffer = __archive_read_filter_ahead(filter, 6, &avail);
239228753Smm	if (buffer == NULL)
240228753Smm		return (0);
241228753Smm
242228753Smm	/*
243228753Smm	 * Verify Header Magic Bytes : FD 37 7A 58 5A 00
244228753Smm	 */
245231200Smm	if (memcmp(buffer, "\xFD\x37\x7A\x58\x5A\x00", 6) != 0)
246228753Smm		return (0);
247228753Smm
248231200Smm	return (48);
249228753Smm}
250228753Smm
251228753Smm/*
252228753Smm * Test whether we can handle this data.
253228753Smm *
254228753Smm * <sigh> LZMA has a rather poor file signature.  Zeros do not
255228753Smm * make good signature bytes as a rule, and the only non-zero byte
256228753Smm * here is an ASCII character.  For example, an uncompressed tar
257228753Smm * archive whose first file is ']' would satisfy this check.  It may
258228753Smm * be necessary to exclude LZMA from compression_all() because of
259228753Smm * this.  Clients of libarchive would then have to explicitly enable
260228753Smm * LZMA checking instead of (or in addition to) compression_all() when
261228753Smm * they have other evidence (file name, command-line option) to go on.
262228753Smm */
263228753Smmstatic int
264228753Smmlzma_bidder_bid(struct archive_read_filter_bidder *self,
265228753Smm    struct archive_read_filter *filter)
266228753Smm{
267228753Smm	const unsigned char *buffer;
268228753Smm	ssize_t avail;
269228753Smm	uint32_t dicsize;
270228753Smm	uint64_t uncompressed_size;
271228753Smm	int bits_checked;
272228753Smm
273228753Smm	(void)self; /* UNUSED */
274228753Smm
275228753Smm	buffer = __archive_read_filter_ahead(filter, 14, &avail);
276228753Smm	if (buffer == NULL)
277228753Smm		return (0);
278228753Smm
279228753Smm	/* First byte of raw LZMA stream is commonly 0x5d.
280228753Smm	 * The first byte is a special number, which consists of
281228753Smm	 * three parameters of LZMA compression, a number of literal
282228753Smm	 * context bits(which is from 0 to 8, default is 3), a number
283228753Smm	 * of literal pos bits(which is from 0 to 4, default is 0),
284228753Smm	 * a number of pos bits(which is from 0 to 4, default is 2).
285228753Smm	 * The first byte is made by
286228753Smm	 * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit,
287228753Smm	 * and so the default value in this field is
288228753Smm	 * (2 * 5 + 0) * 9 + 3 = 0x5d.
289228753Smm	 * lzma of LZMA SDK has options to change those parameters.
290228753Smm	 * It means a range of this field is from 0 to 224. And lzma of
291228753Smm	 * XZ Utils with option -e records 0x5e in this field. */
292228753Smm	/* NOTE: If this checking of the first byte increases false
293228753Smm	 * recognition, we should allow only 0x5d and 0x5e for the first
294228753Smm	 * byte of LZMA stream. */
295228753Smm	bits_checked = 0;
296228753Smm	if (buffer[0] > (4 * 5 + 4) * 9 + 8)
297228753Smm		return (0);
298228753Smm	/* Most likely value in the first byte of LZMA stream. */
299228753Smm	if (buffer[0] == 0x5d || buffer[0] == 0x5e)
300228753Smm		bits_checked += 8;
301228753Smm
302228753Smm	/* Sixth through fourteenth bytes are uncompressed size,
303228753Smm	 * stored in little-endian order. `-1' means uncompressed
304228753Smm	 * size is unknown and lzma of XZ Utils always records `-1'
305228753Smm	 * in this field. */
306228753Smm	uncompressed_size = archive_le64dec(buffer+5);
307228753Smm	if (uncompressed_size == (uint64_t)ARCHIVE_LITERAL_LL(-1))
308228753Smm		bits_checked += 64;
309228753Smm
310228753Smm	/* Second through fifth bytes are dictionary size, stored in
311228753Smm	 * little-endian order. The minimum dictionary size is
312228753Smm	 * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option
313228753Smm	 * -d12 and the maxinam dictionary size is 1 << 27(128MiB)
314228753Smm	 * which the one uses with option -d27.
315228753Smm	 * NOTE: A comment of LZMA SDK source code says this dictionary
316228753Smm	 * range is from 1 << 12 to 1 << 30. */
317228753Smm	dicsize = archive_le32dec(buffer+1);
318228753Smm	switch (dicsize) {
319228753Smm	case 0x00001000:/* lzma of LZMA SDK option -d12. */
320228753Smm	case 0x00002000:/* lzma of LZMA SDK option -d13. */
321228753Smm	case 0x00004000:/* lzma of LZMA SDK option -d14. */
322228753Smm	case 0x00008000:/* lzma of LZMA SDK option -d15. */
323228753Smm	case 0x00010000:/* lzma of XZ Utils option -0 and -1.
324228753Smm			 * lzma of LZMA SDK option -d16. */
325228753Smm	case 0x00020000:/* lzma of LZMA SDK option -d17. */
326228753Smm	case 0x00040000:/* lzma of LZMA SDK option -d18. */
327228753Smm	case 0x00080000:/* lzma of XZ Utils option -2.
328228753Smm			 * lzma of LZMA SDK option -d19. */
329228753Smm	case 0x00100000:/* lzma of XZ Utils option -3.
330228753Smm			 * lzma of LZMA SDK option -d20. */
331228753Smm	case 0x00200000:/* lzma of XZ Utils option -4.
332228753Smm			 * lzma of LZMA SDK option -d21. */
333228753Smm	case 0x00400000:/* lzma of XZ Utils option -5.
334228753Smm			 * lzma of LZMA SDK option -d22. */
335228753Smm	case 0x00800000:/* lzma of XZ Utils option -6.
336228753Smm			 * lzma of LZMA SDK option -d23. */
337228753Smm	case 0x01000000:/* lzma of XZ Utils option -7.
338228753Smm			 * lzma of LZMA SDK option -d24. */
339228753Smm	case 0x02000000:/* lzma of XZ Utils option -8.
340228753Smm			 * lzma of LZMA SDK option -d25. */
341228753Smm	case 0x04000000:/* lzma of XZ Utils option -9.
342228753Smm			 * lzma of LZMA SDK option -d26. */
343228753Smm	case 0x08000000:/* lzma of LZMA SDK option -d27. */
344228753Smm		bits_checked += 32;
345228753Smm		break;
346228753Smm	default:
347228753Smm		/* If a memory usage for encoding was not enough on
348228753Smm		 * the platform where LZMA stream was made, lzma of
349228753Smm		 * XZ Utils automatically decreased the dictionary
350228753Smm		 * size to enough memory for encoding by 1Mi bytes
351228753Smm		 * (1 << 20).*/
352228753Smm		if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 &&
353228753Smm		    (dicsize & ((1 << 20)-1)) == 0 &&
354228753Smm		    bits_checked == 8 + 64) {
355228753Smm			bits_checked += 32;
356228753Smm			break;
357228753Smm		}
358228753Smm		/* Otherwise dictionary size is unlikely. But it is
359228753Smm		 * possible that someone makes lzma stream with
360228753Smm		 * liblzma/LZMA SDK in one's dictionary size. */
361228753Smm		return (0);
362228753Smm	}
363228753Smm
364228753Smm	/* TODO: The above test is still very weak.  It would be
365228753Smm	 * good to do better. */
366228753Smm
367228753Smm	return (bits_checked);
368228753Smm}
369228753Smm
370231200Smmstatic int
371231200Smmlzip_has_member(struct archive_read_filter *filter)
372231200Smm{
373231200Smm	const unsigned char *buffer;
374231200Smm	ssize_t avail;
375231200Smm	int bits_checked;
376231200Smm	int log2dic;
377231200Smm
378231200Smm	buffer = __archive_read_filter_ahead(filter, 6, &avail);
379231200Smm	if (buffer == NULL)
380231200Smm		return (0);
381231200Smm
382231200Smm	/*
383231200Smm	 * Verify Header Magic Bytes : 4C 5A 49 50 (`LZIP')
384231200Smm	 */
385231200Smm	bits_checked = 0;
386231200Smm	if (memcmp(buffer, "LZIP", 4) != 0)
387231200Smm		return (0);
388231200Smm	bits_checked += 32;
389231200Smm
390231200Smm	/* A version number must be 0 or 1 */
391231200Smm	if (buffer[4] != 0 && buffer[4] != 1)
392231200Smm		return (0);
393231200Smm	bits_checked += 8;
394231200Smm
395231200Smm	/* Dictionary size. */
396231200Smm	log2dic = buffer[5] & 0x1f;
397231200Smm	if (log2dic < 12 || log2dic > 27)
398231200Smm		return (0);
399231200Smm	bits_checked += 8;
400231200Smm
401231200Smm	return (bits_checked);
402231200Smm}
403231200Smm
404231200Smmstatic int
405231200Smmlzip_bidder_bid(struct archive_read_filter_bidder *self,
406231200Smm    struct archive_read_filter *filter)
407231200Smm{
408231200Smm
409231200Smm	(void)self; /* UNUSED */
410231200Smm	return (lzip_has_member(filter));
411231200Smm}
412231200Smm
413228753Smm#if HAVE_LZMA_H && HAVE_LIBLZMA
414228753Smm
415228753Smm/*
416228753Smm * liblzma 4.999.7 and later support both lzma and xz streams.
417228753Smm */
418228753Smmstatic int
419228753Smmxz_bidder_init(struct archive_read_filter *self)
420228753Smm{
421248616Smm	self->code = ARCHIVE_FILTER_XZ;
422228753Smm	self->name = "xz";
423228753Smm	return (xz_lzma_bidder_init(self));
424228753Smm}
425228753Smm
426228753Smmstatic int
427228753Smmlzma_bidder_init(struct archive_read_filter *self)
428228753Smm{
429248616Smm	self->code = ARCHIVE_FILTER_LZMA;
430228753Smm	self->name = "lzma";
431228753Smm	return (xz_lzma_bidder_init(self));
432228753Smm}
433228753Smm
434231200Smmstatic int
435231200Smmlzip_bidder_init(struct archive_read_filter *self)
436231200Smm{
437248616Smm	self->code = ARCHIVE_FILTER_LZIP;
438231200Smm	self->name = "lzip";
439231200Smm	return (xz_lzma_bidder_init(self));
440231200Smm}
441231200Smm
442228753Smm/*
443231200Smm * Set an error code and choose an error message
444231200Smm */
445231200Smmstatic void
446231200Smmset_error(struct archive_read_filter *self, int ret)
447231200Smm{
448231200Smm
449231200Smm	switch (ret) {
450231200Smm	case LZMA_STREAM_END: /* Found end of stream. */
451231200Smm	case LZMA_OK: /* Decompressor made some progress. */
452231200Smm		break;
453231200Smm	case LZMA_MEM_ERROR:
454231200Smm		archive_set_error(&self->archive->archive, ENOMEM,
455231200Smm		    "Lzma library error: Cannot allocate memory");
456231200Smm		break;
457231200Smm	case LZMA_MEMLIMIT_ERROR:
458231200Smm		archive_set_error(&self->archive->archive, ENOMEM,
459231200Smm		    "Lzma library error: Out of memory");
460231200Smm		break;
461231200Smm	case LZMA_FORMAT_ERROR:
462231200Smm		archive_set_error(&self->archive->archive,
463231200Smm		    ARCHIVE_ERRNO_MISC,
464231200Smm		    "Lzma library error: format not recognized");
465231200Smm		break;
466231200Smm	case LZMA_OPTIONS_ERROR:
467231200Smm		archive_set_error(&self->archive->archive,
468231200Smm		    ARCHIVE_ERRNO_MISC,
469231200Smm		    "Lzma library error: Invalid options");
470231200Smm		break;
471231200Smm	case LZMA_DATA_ERROR:
472231200Smm		archive_set_error(&self->archive->archive,
473231200Smm		    ARCHIVE_ERRNO_MISC,
474231200Smm		    "Lzma library error: Corrupted input data");
475231200Smm		break;
476231200Smm	case LZMA_BUF_ERROR:
477231200Smm		archive_set_error(&self->archive->archive,
478231200Smm		    ARCHIVE_ERRNO_MISC,
479231200Smm		    "Lzma library error:  No progress is possible");
480231200Smm		break;
481231200Smm	default:
482231200Smm		/* Return an error. */
483231200Smm		archive_set_error(&self->archive->archive,
484231200Smm		    ARCHIVE_ERRNO_MISC,
485231200Smm		    "Lzma decompression failed:  Unknown error");
486231200Smm		break;
487231200Smm	}
488231200Smm}
489231200Smm
490231200Smm/*
491228753Smm * Setup the callbacks.
492228753Smm */
493228753Smmstatic int
494228753Smmxz_lzma_bidder_init(struct archive_read_filter *self)
495228753Smm{
496228753Smm	static const size_t out_block_size = 64 * 1024;
497228753Smm	void *out_block;
498228753Smm	struct private_data *state;
499228753Smm	int ret;
500228753Smm
501228753Smm	state = (struct private_data *)calloc(sizeof(*state), 1);
502228753Smm	out_block = (unsigned char *)malloc(out_block_size);
503228753Smm	if (state == NULL || out_block == NULL) {
504228753Smm		archive_set_error(&self->archive->archive, ENOMEM,
505228753Smm		    "Can't allocate data for xz decompression");
506228753Smm		free(out_block);
507228753Smm		free(state);
508228753Smm		return (ARCHIVE_FATAL);
509228753Smm	}
510228753Smm
511228753Smm	self->data = state;
512228753Smm	state->out_block_size = out_block_size;
513228753Smm	state->out_block = out_block;
514228753Smm	self->read = xz_filter_read;
515228753Smm	self->skip = NULL; /* not supported */
516228753Smm	self->close = xz_filter_close;
517228753Smm
518228753Smm	state->stream.avail_in = 0;
519228753Smm
520228753Smm	state->stream.next_out = state->out_block;
521228753Smm	state->stream.avail_out = state->out_block_size;
522228753Smm
523231200Smm	state->crc32 = 0;
524248616Smm	if (self->code == ARCHIVE_FILTER_LZIP) {
525231200Smm		/*
526231200Smm		 * We have to read a lzip header and use it to initialize
527231200Smm		 * compression library, thus we cannot initialize the
528231200Smm		 * library for lzip here.
529231200Smm		 */
530231200Smm		state->in_stream = 0;
531231200Smm		return (ARCHIVE_OK);
532231200Smm	} else
533231200Smm		state->in_stream = 1;
534231200Smm
535231200Smm	/* Initialize compression library. */
536248616Smm	if (self->code == ARCHIVE_FILTER_XZ)
537228753Smm		ret = lzma_stream_decoder(&(state->stream),
538231200Smm		    LZMA_MEMLIMIT,/* memlimit */
539228753Smm		    LZMA_CONCATENATED);
540228753Smm	else
541228753Smm		ret = lzma_alone_decoder(&(state->stream),
542231200Smm		    LZMA_MEMLIMIT);/* memlimit */
543228753Smm
544228753Smm	if (ret == LZMA_OK)
545228753Smm		return (ARCHIVE_OK);
546228753Smm
547228753Smm	/* Library setup failed: Choose an error message and clean up. */
548231200Smm	set_error(self, ret);
549228753Smm
550228753Smm	free(state->out_block);
551228753Smm	free(state);
552228753Smm	self->data = NULL;
553228753Smm	return (ARCHIVE_FATAL);
554228753Smm}
555228753Smm
556231200Smmstatic int
557231200Smmlzip_init(struct archive_read_filter *self)
558231200Smm{
559231200Smm	struct private_data *state;
560231200Smm	const unsigned char *h;
561231200Smm	lzma_filter filters[2];
562231200Smm	unsigned char props[5];
563231200Smm	ssize_t avail_in;
564231200Smm	uint32_t dicsize;
565231200Smm	int log2dic, ret;
566231200Smm
567231200Smm	state = (struct private_data *)self->data;
568231200Smm	h = __archive_read_filter_ahead(self->upstream, 6, &avail_in);
569231200Smm	if (h == NULL)
570231200Smm		return (ARCHIVE_FATAL);
571231200Smm
572231200Smm	/* Get a version number. */
573231200Smm	state->lzip_ver = h[4];
574231200Smm
575231200Smm	/*
576231200Smm	 * Setup lzma property.
577231200Smm	 */
578231200Smm	props[0] = 0x5d;
579231200Smm
580231200Smm	/* Get dictionary size. */
581231200Smm	log2dic = h[5] & 0x1f;
582231200Smm	if (log2dic < 12 || log2dic > 27)
583231200Smm		return (ARCHIVE_FATAL);
584231200Smm	dicsize = 1U << log2dic;
585231200Smm	if (log2dic > 12)
586231200Smm		dicsize -= (dicsize / 16) * (h[5] >> 5);
587231200Smm	archive_le32enc(props+1, dicsize);
588231200Smm
589231200Smm	/* Consume lzip header. */
590231200Smm	__archive_read_filter_consume(self->upstream, 6);
591231200Smm	state->member_in = 6;
592231200Smm
593231200Smm	filters[0].id = LZMA_FILTER_LZMA1;
594231200Smm	filters[0].options = NULL;
595231200Smm	filters[1].id = LZMA_VLI_UNKNOWN;
596231200Smm	filters[1].options = NULL;
597231200Smm
598231200Smm	ret = lzma_properties_decode(&filters[0], NULL, props, sizeof(props));
599231200Smm	if (ret != LZMA_OK) {
600231200Smm		set_error(self, ret);
601231200Smm		return (ARCHIVE_FATAL);
602231200Smm	}
603231200Smm	ret = lzma_raw_decoder(&(state->stream), filters);
604231200Smm#if LZMA_VERSION < 50000030
605231200Smm	free(filters[0].options);
606231200Smm#endif
607231200Smm	if (ret != LZMA_OK) {
608231200Smm		set_error(self, ret);
609231200Smm		return (ARCHIVE_FATAL);
610231200Smm	}
611231200Smm	return (ARCHIVE_OK);
612231200Smm}
613231200Smm
614231200Smmstatic int
615231200Smmlzip_tail(struct archive_read_filter *self)
616231200Smm{
617231200Smm	struct private_data *state;
618231200Smm	const unsigned char *f;
619231200Smm	ssize_t avail_in;
620231200Smm	int tail;
621231200Smm
622231200Smm	state = (struct private_data *)self->data;
623231200Smm	if (state->lzip_ver == 0)
624231200Smm		tail = 12;
625231200Smm	else
626231200Smm		tail = 20;
627231200Smm	f = __archive_read_filter_ahead(self->upstream, tail, &avail_in);
628231200Smm	if (f == NULL && avail_in < 0)
629231200Smm		return (ARCHIVE_FATAL);
630231200Smm	if (avail_in < tail) {
631231200Smm		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
632231200Smm		    "Lzip: Remaining data is less bytes");
633231200Smm		return (ARCHIVE_FAILED);
634231200Smm	}
635231200Smm
636231200Smm	/* Check the crc32 value of the uncompressed data of the current
637231200Smm	 * member */
638231200Smm	if (state->crc32 != archive_le32dec(f)) {
639231200Smm		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
640231200Smm		    "Lzip: CRC32 error");
641231200Smm		return (ARCHIVE_FAILED);
642231200Smm	}
643231200Smm
644231200Smm	/* Check the uncompressed size of the current member */
645231200Smm	if ((uint64_t)state->member_out != archive_le64dec(f + 4)) {
646231200Smm		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
647231200Smm		    "Lzip: Uncompressed size error");
648231200Smm		return (ARCHIVE_FAILED);
649231200Smm	}
650231200Smm
651231200Smm	/* Check the total size of the current member */
652231200Smm	if (state->lzip_ver == 1 &&
653231200Smm	    (uint64_t)state->member_in + tail != archive_le64dec(f + 12)) {
654231200Smm		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
655231200Smm		    "Lzip: Member size error");
656231200Smm		return (ARCHIVE_FAILED);
657231200Smm	}
658231200Smm	__archive_read_filter_consume(self->upstream, tail);
659231200Smm
660231200Smm	/* If current lzip data consists of multi member, try decompressing
661231200Smm	 * a next member. */
662231200Smm	if (lzip_has_member(self->upstream) != 0) {
663231200Smm		state->in_stream = 0;
664231200Smm		state->crc32 = 0;
665231200Smm		state->member_out = 0;
666231200Smm		state->member_in = 0;
667231200Smm		state->eof = 0;
668231200Smm	}
669231200Smm	return (ARCHIVE_OK);
670231200Smm}
671231200Smm
672228753Smm/*
673228753Smm * Return the next block of decompressed data.
674228753Smm */
675228753Smmstatic ssize_t
676228753Smmxz_filter_read(struct archive_read_filter *self, const void **p)
677228753Smm{
678228753Smm	struct private_data *state;
679228753Smm	size_t decompressed;
680228753Smm	ssize_t avail_in;
681228753Smm	int ret;
682228753Smm
683228753Smm	state = (struct private_data *)self->data;
684228753Smm
685228753Smm	/* Empty our output buffer. */
686228753Smm	state->stream.next_out = state->out_block;
687228753Smm	state->stream.avail_out = state->out_block_size;
688228753Smm
689228753Smm	/* Try to fill the output buffer. */
690228753Smm	while (state->stream.avail_out > 0 && !state->eof) {
691231200Smm		if (!state->in_stream) {
692231200Smm			/*
693231200Smm			 * Initialize liblzma for lzip
694231200Smm			 */
695231200Smm			ret = lzip_init(self);
696231200Smm			if (ret != ARCHIVE_OK)
697231200Smm				return (ret);
698231200Smm			state->in_stream = 1;
699231200Smm		}
700228753Smm		state->stream.next_in =
701228753Smm		    __archive_read_filter_ahead(self->upstream, 1, &avail_in);
702231200Smm		if (state->stream.next_in == NULL && avail_in < 0) {
703231200Smm			archive_set_error(&self->archive->archive,
704231200Smm			    ARCHIVE_ERRNO_MISC,
705231200Smm			    "truncated input");
706228753Smm			return (ARCHIVE_FATAL);
707231200Smm		}
708228753Smm		state->stream.avail_in = avail_in;
709228753Smm
710228753Smm		/* Decompress as much as we can in one pass. */
711228753Smm		ret = lzma_code(&(state->stream),
712228753Smm		    (state->stream.avail_in == 0)? LZMA_FINISH: LZMA_RUN);
713228753Smm		switch (ret) {
714228753Smm		case LZMA_STREAM_END: /* Found end of stream. */
715228753Smm			state->eof = 1;
716228753Smm			/* FALL THROUGH */
717228753Smm		case LZMA_OK: /* Decompressor made some progress. */
718228753Smm			__archive_read_filter_consume(self->upstream,
719228753Smm			    avail_in - state->stream.avail_in);
720231200Smm			state->member_in +=
721231200Smm			    avail_in - state->stream.avail_in;
722228753Smm			break;
723228753Smm		default:
724231200Smm			set_error(self, ret);
725228753Smm			return (ARCHIVE_FATAL);
726228753Smm		}
727228753Smm	}
728228753Smm
729228753Smm	decompressed = state->stream.next_out - state->out_block;
730228753Smm	state->total_out += decompressed;
731231200Smm	state->member_out += decompressed;
732228753Smm	if (decompressed == 0)
733228753Smm		*p = NULL;
734231200Smm	else {
735228753Smm		*p = state->out_block;
736248616Smm		if (self->code == ARCHIVE_FILTER_LZIP) {
737231200Smm			state->crc32 = lzma_crc32(state->out_block,
738231200Smm			    decompressed, state->crc32);
739231200Smm			if (state->eof) {
740231200Smm				ret = lzip_tail(self);
741231200Smm				if (ret != ARCHIVE_OK)
742231200Smm					return (ret);
743231200Smm			}
744231200Smm		}
745231200Smm	}
746228753Smm	return (decompressed);
747228753Smm}
748228753Smm
749228753Smm/*
750228753Smm * Clean up the decompressor.
751228753Smm */
752228753Smmstatic int
753228753Smmxz_filter_close(struct archive_read_filter *self)
754228753Smm{
755228753Smm	struct private_data *state;
756228753Smm
757228753Smm	state = (struct private_data *)self->data;
758228753Smm	lzma_end(&(state->stream));
759228753Smm	free(state->out_block);
760228753Smm	free(state);
761228753Smm	return (ARCHIVE_OK);
762228753Smm}
763228753Smm
764228753Smm#else
765228753Smm
766228753Smm#if HAVE_LZMADEC_H && HAVE_LIBLZMADEC
767228753Smm
768228753Smm/*
769228753Smm * If we have the older liblzmadec library, then we can handle
770228753Smm * LZMA streams but not XZ streams.
771228753Smm */
772228753Smm
773228753Smm/*
774228753Smm * Setup the callbacks.
775228753Smm */
776228753Smmstatic int
777228753Smmlzma_bidder_init(struct archive_read_filter *self)
778228753Smm{
779228753Smm	static const size_t out_block_size = 64 * 1024;
780228753Smm	void *out_block;
781228753Smm	struct private_data *state;
782228753Smm	ssize_t ret, avail_in;
783228753Smm
784248616Smm	self->code = ARCHIVE_FILTER_LZMA;
785228753Smm	self->name = "lzma";
786228753Smm
787228753Smm	state = (struct private_data *)calloc(sizeof(*state), 1);
788228753Smm	out_block = (unsigned char *)malloc(out_block_size);
789228753Smm	if (state == NULL || out_block == NULL) {
790228753Smm		archive_set_error(&self->archive->archive, ENOMEM,
791228753Smm		    "Can't allocate data for lzma decompression");
792228753Smm		free(out_block);
793228753Smm		free(state);
794228753Smm		return (ARCHIVE_FATAL);
795228753Smm	}
796228753Smm
797228753Smm	self->data = state;
798228753Smm	state->out_block_size = out_block_size;
799228753Smm	state->out_block = out_block;
800228753Smm	self->read = lzma_filter_read;
801228753Smm	self->skip = NULL; /* not supported */
802228753Smm	self->close = lzma_filter_close;
803228753Smm
804228753Smm	/* Prime the lzma library with 18 bytes of input. */
805228753Smm	state->stream.next_in = (unsigned char *)(uintptr_t)
806228753Smm	    __archive_read_filter_ahead(self->upstream, 18, &avail_in);
807228753Smm	if (state->stream.next_in == NULL)
808228753Smm		return (ARCHIVE_FATAL);
809228753Smm	state->stream.avail_in = avail_in;
810228753Smm	state->stream.next_out = state->out_block;
811228753Smm	state->stream.avail_out = state->out_block_size;
812228753Smm
813228753Smm	/* Initialize compression library. */
814228753Smm	ret = lzmadec_init(&(state->stream));
815228753Smm	__archive_read_filter_consume(self->upstream,
816228753Smm	    avail_in - state->stream.avail_in);
817228753Smm	if (ret == LZMADEC_OK)
818228753Smm		return (ARCHIVE_OK);
819228753Smm
820228753Smm	/* Library setup failed: Clean up. */
821228753Smm	archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
822228753Smm	    "Internal error initializing lzma library");
823228753Smm
824228753Smm	/* Override the error message if we know what really went wrong. */
825228753Smm	switch (ret) {
826228753Smm	case LZMADEC_HEADER_ERROR:
827228753Smm		archive_set_error(&self->archive->archive,
828228753Smm		    ARCHIVE_ERRNO_MISC,
829228753Smm		    "Internal error initializing compression library: "
830228753Smm		    "invalid header");
831228753Smm		break;
832228753Smm	case LZMADEC_MEM_ERROR:
833228753Smm		archive_set_error(&self->archive->archive, ENOMEM,
834228753Smm		    "Internal error initializing compression library: "
835228753Smm		    "out of memory");
836228753Smm		break;
837228753Smm	}
838228753Smm
839228753Smm	free(state->out_block);
840228753Smm	free(state);
841228753Smm	self->data = NULL;
842228753Smm	return (ARCHIVE_FATAL);
843228753Smm}
844228753Smm
845228753Smm/*
846228753Smm * Return the next block of decompressed data.
847228753Smm */
848228753Smmstatic ssize_t
849228753Smmlzma_filter_read(struct archive_read_filter *self, const void **p)
850228753Smm{
851228753Smm	struct private_data *state;
852228753Smm	size_t decompressed;
853228753Smm	ssize_t avail_in, ret;
854228753Smm
855228753Smm	state = (struct private_data *)self->data;
856228753Smm
857228753Smm	/* Empty our output buffer. */
858228753Smm	state->stream.next_out = state->out_block;
859228753Smm	state->stream.avail_out = state->out_block_size;
860228753Smm
861228753Smm	/* Try to fill the output buffer. */
862228753Smm	while (state->stream.avail_out > 0 && !state->eof) {
863228753Smm		state->stream.next_in = (unsigned char *)(uintptr_t)
864228753Smm		    __archive_read_filter_ahead(self->upstream, 1, &avail_in);
865231200Smm		if (state->stream.next_in == NULL && avail_in < 0) {
866231200Smm			archive_set_error(&self->archive->archive,
867231200Smm			    ARCHIVE_ERRNO_MISC,
868231200Smm			    "truncated lzma input");
869228753Smm			return (ARCHIVE_FATAL);
870231200Smm		}
871228753Smm		state->stream.avail_in = avail_in;
872228753Smm
873228753Smm		/* Decompress as much as we can in one pass. */
874228753Smm		ret = lzmadec_decode(&(state->stream), avail_in == 0);
875228753Smm		switch (ret) {
876228753Smm		case LZMADEC_STREAM_END: /* Found end of stream. */
877228753Smm			state->eof = 1;
878228753Smm			/* FALL THROUGH */
879228753Smm		case LZMADEC_OK: /* Decompressor made some progress. */
880228753Smm			__archive_read_filter_consume(self->upstream,
881228753Smm			    avail_in - state->stream.avail_in);
882228753Smm			break;
883228753Smm		case LZMADEC_BUF_ERROR: /* Insufficient input data? */
884228753Smm			archive_set_error(&self->archive->archive,
885228753Smm			    ARCHIVE_ERRNO_MISC,
886228753Smm			    "Insufficient compressed data");
887228753Smm			return (ARCHIVE_FATAL);
888228753Smm		default:
889228753Smm			/* Return an error. */
890228753Smm			archive_set_error(&self->archive->archive,
891228753Smm			    ARCHIVE_ERRNO_MISC,
892228753Smm			    "Lzma decompression failed");
893228753Smm			return (ARCHIVE_FATAL);
894228753Smm		}
895228753Smm	}
896228753Smm
897228753Smm	decompressed = state->stream.next_out - state->out_block;
898228753Smm	state->total_out += decompressed;
899228753Smm	if (decompressed == 0)
900228753Smm		*p = NULL;
901228753Smm	else
902228753Smm		*p = state->out_block;
903228753Smm	return (decompressed);
904228753Smm}
905228753Smm
906228753Smm/*
907228753Smm * Clean up the decompressor.
908228753Smm */
909228753Smmstatic int
910228753Smmlzma_filter_close(struct archive_read_filter *self)
911228753Smm{
912228753Smm	struct private_data *state;
913228753Smm	int ret;
914228753Smm
915228753Smm	state = (struct private_data *)self->data;
916228753Smm	ret = ARCHIVE_OK;
917228753Smm	switch (lzmadec_end(&(state->stream))) {
918228753Smm	case LZMADEC_OK:
919228753Smm		break;
920228753Smm	default:
921228753Smm		archive_set_error(&(self->archive->archive),
922228753Smm		    ARCHIVE_ERRNO_MISC,
923228753Smm		    "Failed to clean up %s compressor",
924228753Smm		    self->archive->archive.compression_name);
925228753Smm		ret = ARCHIVE_FATAL;
926228753Smm	}
927228753Smm
928228753Smm	free(state->out_block);
929228753Smm	free(state);
930228753Smm	return (ret);
931228753Smm}
932228753Smm
933228753Smm#else
934228753Smm
935228753Smm/*
936228753Smm *
937228753Smm * If we have no suitable library on this system, we can't actually do
938228753Smm * the decompression.  We can, however, still detect compressed
939228753Smm * archives and emit a useful message.
940228753Smm *
941228753Smm */
942228753Smmstatic int
943228753Smmlzma_bidder_init(struct archive_read_filter *self)
944228753Smm{
945228753Smm	int r;
946228753Smm
947248616Smm	r = __archive_read_program(self, "lzma -d -qq");
948228753Smm	/* Note: We set the format here even if __archive_read_program()
949228753Smm	 * above fails.  We do, after all, know what the format is
950228753Smm	 * even if we weren't able to read it. */
951248616Smm	self->code = ARCHIVE_FILTER_LZMA;
952228753Smm	self->name = "lzma";
953228753Smm	return (r);
954228753Smm}
955228753Smm
956228753Smm#endif /* HAVE_LZMADEC_H */
957228753Smm
958228753Smm
959228753Smmstatic int
960228753Smmxz_bidder_init(struct archive_read_filter *self)
961228753Smm{
962228753Smm	int r;
963228753Smm
964248616Smm	r = __archive_read_program(self, "xz -d -qq");
965228753Smm	/* Note: We set the format here even if __archive_read_program()
966228753Smm	 * above fails.  We do, after all, know what the format is
967228753Smm	 * even if we weren't able to read it. */
968248616Smm	self->code = ARCHIVE_FILTER_XZ;
969228753Smm	self->name = "xz";
970228753Smm	return (r);
971228753Smm}
972228753Smm
973231200Smmstatic int
974231200Smmlzip_bidder_init(struct archive_read_filter *self)
975231200Smm{
976231200Smm	int r;
977228753Smm
978248616Smm	r = __archive_read_program(self, "lzip -d -q");
979231200Smm	/* Note: We set the format here even if __archive_read_program()
980231200Smm	 * above fails.  We do, after all, know what the format is
981231200Smm	 * even if we weren't able to read it. */
982248616Smm	self->code = ARCHIVE_FILTER_LZIP;
983231200Smm	self->name = "lzip";
984231200Smm	return (r);
985231200Smm}
986231200Smm
987231200Smm
988228753Smm#endif /* HAVE_LZMA_H */
989