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