1299425Smm/*- 2299425Smm * Copyright (c) 2014 Michihiro NAKAJIMA 3299425Smm * All rights reserved. 4299425Smm * 5299425Smm * Redistribution and use in source and binary forms, with or without 6299425Smm * modification, are permitted provided that the following conditions 7299425Smm * are met: 8299425Smm * 1. Redistributions of source code must retain the above copyright 9299425Smm * notice, this list of conditions and the following disclaimer. 10299425Smm * 2. Redistributions in binary form must reproduce the above copyright 11299425Smm * notice, this list of conditions and the following disclaimer in the 12299425Smm * documentation and/or other materials provided with the distribution. 13299425Smm * 14299425Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15299425Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16299425Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17299425Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18299425Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19299425Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20299425Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21299425Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22299425Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23299425Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24299425Smm */ 25299425Smm 26299425Smm#include "archive_platform.h" 27299425Smm 28299425Smm__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c 353377 2019-10-09 22:19:48Z mm $"); 29299425Smm 30299425Smm#ifdef HAVE_ERRNO_H 31299425Smm#include <errno.h> 32299425Smm#endif 33299425Smm#include <stdio.h> 34299425Smm#ifdef HAVE_STDLIB_H 35299425Smm#include <stdlib.h> 36299425Smm#endif 37299425Smm#ifdef HAVE_STRING_H 38299425Smm#include <string.h> 39299425Smm#endif 40299425Smm#ifdef HAVE_UNISTD_H 41299425Smm#include <unistd.h> 42299425Smm#endif 43299425Smm#ifdef HAVE_LZ4_H 44299425Smm#include <lz4.h> 45299425Smm#endif 46299425Smm 47299425Smm#include "archive.h" 48299425Smm#include "archive_endian.h" 49299425Smm#include "archive_private.h" 50299425Smm#include "archive_read_private.h" 51299425Smm#include "archive_xxhash.h" 52299425Smm 53299425Smm#define LZ4_MAGICNUMBER 0x184d2204 54299425Smm#define LZ4_SKIPPABLED 0x184d2a50 55299425Smm#define LZ4_LEGACY 0x184c2102 56299425Smm 57299425Smm#if defined(HAVE_LIBLZ4) 58299425Smmstruct private_data { 59299425Smm enum { SELECT_STREAM, 60299425Smm READ_DEFAULT_STREAM, 61299425Smm READ_DEFAULT_BLOCK, 62299425Smm READ_LEGACY_STREAM, 63299425Smm READ_LEGACY_BLOCK, 64299425Smm } stage; 65299425Smm struct { 66299425Smm unsigned block_independence:1; 67299425Smm unsigned block_checksum:3; 68299425Smm unsigned stream_size:1; 69299425Smm unsigned stream_checksum:1; 70299425Smm unsigned preset_dictionary:1; 71299425Smm int block_maximum_size; 72299425Smm } flags; 73299425Smm int64_t stream_size; 74299425Smm uint32_t dict_id; 75299425Smm char *out_block; 76299425Smm size_t out_block_size; 77299425Smm 78299425Smm /* Bytes read but not yet consumed via __archive_read_consume() */ 79299425Smm size_t unconsumed; 80299425Smm size_t decoded_size; 81299425Smm void *xxh32_state; 82299425Smm 83299425Smm char valid; /* True = decompressor is initialized */ 84299425Smm char eof; /* True = found end of compressed data. */ 85299425Smm}; 86299425Smm 87299425Smm#define LEGACY_BLOCK_SIZE (8 * 1024 * 1024) 88299425Smm 89299425Smm/* Lz4 filter */ 90299425Smmstatic ssize_t lz4_filter_read(struct archive_read_filter *, const void **); 91299425Smmstatic int lz4_filter_close(struct archive_read_filter *); 92299425Smm#endif 93299425Smm 94299425Smm/* 95299425Smm * Note that we can detect lz4 archives even if we can't decompress 96299425Smm * them. (In fact, we like detecting them because we can give better 97299425Smm * error messages.) So the bid framework here gets compiled even 98299425Smm * if liblz4 is unavailable. 99299425Smm */ 100299425Smmstatic int lz4_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *); 101299425Smmstatic int lz4_reader_init(struct archive_read_filter *); 102299425Smmstatic int lz4_reader_free(struct archive_read_filter_bidder *); 103299425Smm#if defined(HAVE_LIBLZ4) 104299425Smmstatic ssize_t lz4_filter_read_default_stream(struct archive_read_filter *, 105299425Smm const void **); 106299425Smmstatic ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *, 107299425Smm const void **); 108299425Smm#endif 109299425Smm 110299425Smmint 111299425Smmarchive_read_support_filter_lz4(struct archive *_a) 112299425Smm{ 113299425Smm struct archive_read *a = (struct archive_read *)_a; 114299425Smm struct archive_read_filter_bidder *reader; 115299425Smm 116299425Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, 117299425Smm ARCHIVE_STATE_NEW, "archive_read_support_filter_lz4"); 118299425Smm 119299425Smm if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) 120299425Smm return (ARCHIVE_FATAL); 121299425Smm 122299425Smm reader->data = NULL; 123299425Smm reader->name = "lz4"; 124299425Smm reader->bid = lz4_reader_bid; 125299425Smm reader->init = lz4_reader_init; 126299425Smm reader->options = NULL; 127299425Smm reader->free = lz4_reader_free; 128299425Smm#if defined(HAVE_LIBLZ4) 129299425Smm return (ARCHIVE_OK); 130299425Smm#else 131299425Smm archive_set_error(_a, ARCHIVE_ERRNO_MISC, 132299425Smm "Using external lz4 program"); 133299425Smm return (ARCHIVE_WARN); 134299425Smm#endif 135299425Smm} 136299425Smm 137299425Smmstatic int 138299425Smmlz4_reader_free(struct archive_read_filter_bidder *self){ 139299425Smm (void)self; /* UNUSED */ 140299425Smm return (ARCHIVE_OK); 141299425Smm} 142299425Smm 143299425Smm/* 144299425Smm * Test whether we can handle this data. 145299425Smm * 146299425Smm * This logic returns zero if any part of the signature fails. It 147299425Smm * also tries to Do The Right Thing if a very short buffer prevents us 148299425Smm * from verifying as much as we would like. 149299425Smm */ 150299425Smmstatic int 151299425Smmlz4_reader_bid(struct archive_read_filter_bidder *self, 152299425Smm struct archive_read_filter *filter) 153299425Smm{ 154299425Smm const unsigned char *buffer; 155299425Smm ssize_t avail; 156299425Smm int bits_checked; 157299425Smm uint32_t number; 158299425Smm 159299425Smm (void)self; /* UNUSED */ 160299425Smm 161299425Smm /* Minimal lz4 archive is 11 bytes. */ 162299425Smm buffer = __archive_read_filter_ahead(filter, 11, &avail); 163299425Smm if (buffer == NULL) 164299425Smm return (0); 165299425Smm 166299425Smm /* First four bytes must be LZ4 magic numbers. */ 167299425Smm bits_checked = 0; 168299425Smm if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) { 169299425Smm unsigned char flag, BD; 170299425Smm 171299425Smm bits_checked += 32; 172299425Smm /* Next follows a stream descriptor. */ 173299425Smm /* Descriptor Flags. */ 174299425Smm flag = buffer[4]; 175299425Smm /* A version number must be "01". */ 176299425Smm if (((flag & 0xc0) >> 6) != 1) 177299425Smm return (0); 178299425Smm /* A reserved bit must be "0". */ 179299425Smm if (flag & 2) 180299425Smm return (0); 181299425Smm bits_checked += 8; 182299425Smm BD = buffer[5]; 183313571Smm /* A block maximum size should be more than 3. */ 184299425Smm if (((BD & 0x70) >> 4) < 4) 185299425Smm return (0); 186299425Smm /* Reserved bits must be "0". */ 187299425Smm if (BD & ~0x70) 188299425Smm return (0); 189299425Smm bits_checked += 8; 190299425Smm } else if (number == LZ4_LEGACY) { 191299425Smm bits_checked += 32; 192299425Smm } 193299425Smm 194299425Smm return (bits_checked); 195299425Smm} 196299425Smm 197299425Smm#if !defined(HAVE_LIBLZ4) 198299425Smm 199299425Smm/* 200299425Smm * If we don't have the library on this system, we can't actually do the 201299425Smm * decompression. We can, however, still detect compressed archives 202299425Smm * and emit a useful message. 203299425Smm */ 204299425Smmstatic int 205299425Smmlz4_reader_init(struct archive_read_filter *self) 206299425Smm{ 207299425Smm int r; 208299425Smm 209299425Smm r = __archive_read_program(self, "lz4 -d -q"); 210299425Smm /* Note: We set the format here even if __archive_read_program() 211299425Smm * above fails. We do, after all, know what the format is 212299425Smm * even if we weren't able to read it. */ 213299425Smm self->code = ARCHIVE_FILTER_LZ4; 214299425Smm self->name = "lz4"; 215299425Smm return (r); 216299425Smm} 217299425Smm 218299425Smm 219299425Smm#else 220299425Smm 221299425Smm/* 222299425Smm * Setup the callbacks. 223299425Smm */ 224299425Smmstatic int 225299425Smmlz4_reader_init(struct archive_read_filter *self) 226299425Smm{ 227299425Smm struct private_data *state; 228299425Smm 229299425Smm self->code = ARCHIVE_FILTER_LZ4; 230299425Smm self->name = "lz4"; 231299425Smm 232299425Smm state = (struct private_data *)calloc(sizeof(*state), 1); 233299425Smm if (state == NULL) { 234299425Smm archive_set_error(&self->archive->archive, ENOMEM, 235299425Smm "Can't allocate data for lz4 decompression"); 236299425Smm return (ARCHIVE_FATAL); 237299425Smm } 238299425Smm 239299425Smm self->data = state; 240299425Smm state->stage = SELECT_STREAM; 241299425Smm self->read = lz4_filter_read; 242299425Smm self->skip = NULL; /* not supported */ 243299425Smm self->close = lz4_filter_close; 244299425Smm 245299425Smm return (ARCHIVE_OK); 246299425Smm} 247299425Smm 248299425Smmstatic int 249299425Smmlz4_allocate_out_block(struct archive_read_filter *self) 250299425Smm{ 251299425Smm struct private_data *state = (struct private_data *)self->data; 252299425Smm size_t out_block_size = state->flags.block_maximum_size; 253299425Smm void *out_block; 254299425Smm 255299425Smm if (!state->flags.block_independence) 256299425Smm out_block_size += 64 * 1024; 257299425Smm if (state->out_block_size < out_block_size) { 258299425Smm free(state->out_block); 259299425Smm out_block = (unsigned char *)malloc(out_block_size); 260299425Smm state->out_block_size = out_block_size; 261299425Smm if (out_block == NULL) { 262299425Smm archive_set_error(&self->archive->archive, ENOMEM, 263299425Smm "Can't allocate data for lz4 decompression"); 264299425Smm return (ARCHIVE_FATAL); 265299425Smm } 266299425Smm state->out_block = out_block; 267299425Smm } 268299425Smm if (!state->flags.block_independence) 269299425Smm memset(state->out_block, 0, 64 * 1024); 270299425Smm return (ARCHIVE_OK); 271299425Smm} 272299425Smm 273299425Smmstatic int 274299425Smmlz4_allocate_out_block_for_legacy(struct archive_read_filter *self) 275299425Smm{ 276299425Smm struct private_data *state = (struct private_data *)self->data; 277299425Smm size_t out_block_size = LEGACY_BLOCK_SIZE; 278299425Smm void *out_block; 279299425Smm 280299425Smm if (state->out_block_size < out_block_size) { 281299425Smm free(state->out_block); 282299425Smm out_block = (unsigned char *)malloc(out_block_size); 283299425Smm state->out_block_size = out_block_size; 284299425Smm if (out_block == NULL) { 285299425Smm archive_set_error(&self->archive->archive, ENOMEM, 286299425Smm "Can't allocate data for lz4 decompression"); 287299425Smm return (ARCHIVE_FATAL); 288299425Smm } 289299425Smm state->out_block = out_block; 290299425Smm } 291299425Smm return (ARCHIVE_OK); 292299425Smm} 293299425Smm 294299425Smm/* 295299425Smm * Return the next block of decompressed data. 296299425Smm */ 297299425Smmstatic ssize_t 298299425Smmlz4_filter_read(struct archive_read_filter *self, const void **p) 299299425Smm{ 300299425Smm struct private_data *state = (struct private_data *)self->data; 301299425Smm ssize_t ret; 302299425Smm 303299425Smm if (state->eof) { 304299425Smm *p = NULL; 305299425Smm return (0); 306299425Smm } 307299425Smm 308299425Smm __archive_read_filter_consume(self->upstream, state->unconsumed); 309299425Smm state->unconsumed = 0; 310299425Smm 311299425Smm switch (state->stage) { 312299425Smm case SELECT_STREAM: 313299425Smm break; 314299425Smm case READ_DEFAULT_STREAM: 315299425Smm case READ_LEGACY_STREAM: 316299425Smm /* Reading a lz4 stream already failed. */ 317299425Smm archive_set_error(&self->archive->archive, 318299425Smm ARCHIVE_ERRNO_MISC, "Invalid sequence."); 319299425Smm return (ARCHIVE_FATAL); 320299425Smm case READ_DEFAULT_BLOCK: 321299425Smm ret = lz4_filter_read_default_stream(self, p); 322299425Smm if (ret != 0 || state->stage != SELECT_STREAM) 323299425Smm return ret; 324299425Smm break; 325299425Smm case READ_LEGACY_BLOCK: 326299425Smm ret = lz4_filter_read_legacy_stream(self, p); 327299425Smm if (ret != 0 || state->stage != SELECT_STREAM) 328299425Smm return ret; 329299425Smm break; 330299425Smm default: 331299425Smm archive_set_error(&self->archive->archive, 332299425Smm ARCHIVE_ERRNO_MISC, "Program error."); 333299425Smm return (ARCHIVE_FATAL); 334299425Smm break; 335299425Smm } 336299425Smm 337299425Smm while (state->stage == SELECT_STREAM) { 338299425Smm const char *read_buf; 339299425Smm 340299425Smm /* Read a magic number. */ 341299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 4, 342299425Smm NULL); 343299425Smm if (read_buf == NULL) { 344299425Smm state->eof = 1; 345299425Smm *p = NULL; 346299425Smm return (0); 347299425Smm } 348299425Smm uint32_t number = archive_le32dec(read_buf); 349299425Smm __archive_read_filter_consume(self->upstream, 4); 350299425Smm if (number == LZ4_MAGICNUMBER) 351299425Smm return lz4_filter_read_default_stream(self, p); 352299425Smm else if (number == LZ4_LEGACY) 353299425Smm return lz4_filter_read_legacy_stream(self, p); 354299425Smm else if ((number & ~0xF) == LZ4_SKIPPABLED) { 355299425Smm read_buf = __archive_read_filter_ahead( 356299425Smm self->upstream, 4, NULL); 357299425Smm if (read_buf == NULL) { 358299425Smm archive_set_error( 359299425Smm &self->archive->archive, 360299425Smm ARCHIVE_ERRNO_MISC, 361299425Smm "Malformed lz4 data"); 362299425Smm return (ARCHIVE_FATAL); 363299425Smm } 364299425Smm uint32_t skip_bytes = archive_le32dec(read_buf); 365299425Smm __archive_read_filter_consume(self->upstream, 366299425Smm 4 + skip_bytes); 367299425Smm } else { 368299425Smm /* Ignore following unrecognized data. */ 369299425Smm state->eof = 1; 370299425Smm *p = NULL; 371299425Smm return (0); 372299425Smm } 373299425Smm } 374299425Smm state->eof = 1; 375299425Smm *p = NULL; 376299425Smm return (0); 377299425Smm} 378299425Smm 379299425Smmstatic int 380299425Smmlz4_filter_read_descriptor(struct archive_read_filter *self) 381299425Smm{ 382299425Smm struct private_data *state = (struct private_data *)self->data; 383299425Smm const char *read_buf; 384299425Smm ssize_t bytes_remaining; 385299425Smm ssize_t descriptor_bytes; 386299425Smm unsigned char flag, bd; 387299425Smm unsigned int chsum, chsum_verifier; 388299425Smm 389299425Smm /* Make sure we have 2 bytes for flags. */ 390299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 2, 391299425Smm &bytes_remaining); 392299425Smm if (read_buf == NULL) { 393299425Smm archive_set_error(&self->archive->archive, 394299425Smm ARCHIVE_ERRNO_MISC, 395299425Smm "truncated lz4 input"); 396299425Smm return (ARCHIVE_FATAL); 397299425Smm } 398299425Smm 399299425Smm /* 400299425Smm Parse flags. 401299425Smm */ 402299425Smm flag = (unsigned char)read_buf[0]; 403299425Smm /* Verify version number. */ 404299425Smm if ((flag & 0xc0) != 1<<6) 405299425Smm goto malformed_error; 406299425Smm /* A reserved bit must be zero. */ 407299425Smm if (flag & 0x02) 408299425Smm goto malformed_error; 409299425Smm state->flags.block_independence = (flag & 0x20) != 0; 410299425Smm state->flags.block_checksum = (flag & 0x10)?4:0; 411299425Smm state->flags.stream_size = (flag & 0x08) != 0; 412299425Smm state->flags.stream_checksum = (flag & 0x04) != 0; 413299425Smm state->flags.preset_dictionary = (flag & 0x01) != 0; 414299425Smm 415299425Smm /* BD */ 416299425Smm bd = (unsigned char)read_buf[1]; 417299425Smm /* Reserved bits must be zero. */ 418299425Smm if (bd & 0x8f) 419299425Smm goto malformed_error; 420313571Smm /* Get a maximum block size. */ 421299425Smm switch (read_buf[1] >> 4) { 422299425Smm case 4: /* 64 KB */ 423299425Smm state->flags.block_maximum_size = 64 * 1024; 424299425Smm break; 425299425Smm case 5: /* 256 KB */ 426299425Smm state->flags.block_maximum_size = 256 * 1024; 427299425Smm break; 428299425Smm case 6: /* 1 MB */ 429299425Smm state->flags.block_maximum_size = 1024 * 1024; 430299425Smm break; 431299425Smm case 7: /* 4 MB */ 432299425Smm state->flags.block_maximum_size = 4 * 1024 * 1024; 433299425Smm break; 434299425Smm default: 435299425Smm goto malformed_error; 436299425Smm } 437299425Smm 438299425Smm /* Read the whole descriptor in a stream block. */ 439299425Smm descriptor_bytes = 3; 440299425Smm if (state->flags.stream_size) 441299425Smm descriptor_bytes += 8; 442299425Smm if (state->flags.preset_dictionary) 443299425Smm descriptor_bytes += 4; 444299425Smm if (bytes_remaining < descriptor_bytes) { 445299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 446299425Smm descriptor_bytes, &bytes_remaining); 447299425Smm if (read_buf == NULL) { 448299425Smm archive_set_error(&self->archive->archive, 449299425Smm ARCHIVE_ERRNO_MISC, 450299425Smm "truncated lz4 input"); 451299425Smm return (ARCHIVE_FATAL); 452299425Smm } 453299425Smm } 454299425Smm /* Check if a descriptor is corrupted */ 455299425Smm chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0); 456299425Smm chsum = (chsum >> 8) & 0xff; 457299425Smm chsum_verifier = read_buf[descriptor_bytes-1] & 0xff; 458299425Smm if (chsum != chsum_verifier) 459299425Smm goto malformed_error; 460299425Smm 461299425Smm __archive_read_filter_consume(self->upstream, descriptor_bytes); 462299425Smm 463353377Smm /* Make sure we have a large enough buffer for uncompressed data. */ 464299425Smm if (lz4_allocate_out_block(self) != ARCHIVE_OK) 465299425Smm return (ARCHIVE_FATAL); 466299425Smm if (state->flags.stream_checksum) 467299425Smm state->xxh32_state = __archive_xxhash.XXH32_init(0); 468299425Smm 469299425Smm state->decoded_size = 0; 470299425Smm /* Success */ 471299425Smm return (ARCHIVE_OK); 472299425Smmmalformed_error: 473299425Smm archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 474299425Smm "malformed lz4 data"); 475299425Smm return (ARCHIVE_FATAL); 476299425Smm} 477299425Smm 478299425Smmstatic ssize_t 479299425Smmlz4_filter_read_data_block(struct archive_read_filter *self, const void **p) 480299425Smm{ 481299425Smm struct private_data *state = (struct private_data *)self->data; 482299425Smm ssize_t compressed_size; 483299425Smm const char *read_buf; 484299425Smm ssize_t bytes_remaining; 485299425Smm int checksum_size; 486299425Smm ssize_t uncompressed_size; 487299425Smm size_t prefix64k; 488299425Smm 489299425Smm *p = NULL; 490299425Smm 491299425Smm /* Make sure we have 4 bytes for a block size. */ 492299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 4, 493299425Smm &bytes_remaining); 494299425Smm if (read_buf == NULL) 495299425Smm goto truncated_error; 496299425Smm compressed_size = archive_le32dec(read_buf); 497318483Smm if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size) 498299425Smm goto malformed_error; 499299425Smm /* A compressed size == 0 means the end of stream blocks. */ 500299425Smm if (compressed_size == 0) { 501299425Smm __archive_read_filter_consume(self->upstream, 4); 502299425Smm return 0; 503299425Smm } 504299425Smm 505299425Smm checksum_size = state->flags.block_checksum; 506299425Smm /* Check if the block is uncompressed. */ 507318483Smm if (compressed_size & 0x80000000U) { 508318483Smm compressed_size &= 0x7fffffff; 509299425Smm uncompressed_size = compressed_size; 510299425Smm } else 511299425Smm uncompressed_size = 0;/* Unknown yet. */ 512299425Smm 513299425Smm /* 514299425Smm Unfortunately, lz4 decompression API requires a whole block 515299425Smm for its decompression speed, so we read a whole block and allocate 516299425Smm a huge buffer used for decoded data. 517299425Smm */ 518299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 519299425Smm 4 + compressed_size + checksum_size, &bytes_remaining); 520299425Smm if (read_buf == NULL) 521299425Smm goto truncated_error; 522299425Smm 523353377Smm /* Optional processing, checking a block sum. */ 524299425Smm if (checksum_size) { 525299425Smm unsigned int chsum = __archive_xxhash.XXH32( 526299425Smm read_buf + 4, (int)compressed_size, 0); 527299425Smm unsigned int chsum_block = 528299425Smm archive_le32dec(read_buf + 4 + compressed_size); 529299425Smm if (chsum != chsum_block) 530299425Smm goto malformed_error; 531299425Smm } 532299425Smm 533299425Smm 534299425Smm /* If the block is uncompressed, there is nothing to do. */ 535299425Smm if (uncompressed_size) { 536299425Smm /* Prepare a prefix 64k block for next block. */ 537299425Smm if (!state->flags.block_independence) { 538299425Smm prefix64k = 64 * 1024; 539299425Smm if (uncompressed_size < (ssize_t)prefix64k) { 540299425Smm memcpy(state->out_block 541299425Smm + prefix64k - uncompressed_size, 542299425Smm read_buf + 4, 543299425Smm uncompressed_size); 544299425Smm memset(state->out_block, 0, 545299425Smm prefix64k - uncompressed_size); 546299425Smm } else { 547299425Smm memcpy(state->out_block, 548299425Smm read_buf + 4 549299425Smm + uncompressed_size - prefix64k, 550299425Smm prefix64k); 551299425Smm } 552299425Smm state->decoded_size = 0; 553299425Smm } 554299425Smm state->unconsumed = 4 + uncompressed_size + checksum_size; 555299425Smm *p = read_buf + 4; 556299425Smm return uncompressed_size; 557299425Smm } 558299425Smm 559299425Smm /* 560299425Smm Decompress a block data. 561299425Smm */ 562299425Smm if (state->flags.block_independence) { 563299425Smm prefix64k = 0; 564299425Smm uncompressed_size = LZ4_decompress_safe(read_buf + 4, 565299425Smm state->out_block, (int)compressed_size, 566299425Smm state->flags.block_maximum_size); 567299425Smm } else { 568299425Smm prefix64k = 64 * 1024; 569299425Smm if (state->decoded_size) { 570299425Smm if (state->decoded_size < prefix64k) { 571299425Smm memmove(state->out_block 572299425Smm + prefix64k - state->decoded_size, 573299425Smm state->out_block + prefix64k, 574299425Smm state->decoded_size); 575299425Smm memset(state->out_block, 0, 576299425Smm prefix64k - state->decoded_size); 577299425Smm } else { 578299425Smm memmove(state->out_block, 579299425Smm state->out_block + state->decoded_size, 580299425Smm prefix64k); 581299425Smm } 582299425Smm } 583299425Smm#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 584299425Smm uncompressed_size = LZ4_decompress_safe_usingDict( 585299425Smm read_buf + 4, 586299425Smm state->out_block + prefix64k, (int)compressed_size, 587299425Smm state->flags.block_maximum_size, 588299425Smm state->out_block, 589299425Smm prefix64k); 590299425Smm#else 591299425Smm uncompressed_size = LZ4_decompress_safe_withPrefix64k( 592299425Smm read_buf + 4, 593299425Smm state->out_block + prefix64k, (int)compressed_size, 594299425Smm state->flags.block_maximum_size); 595299425Smm#endif 596299425Smm } 597299425Smm 598305192Smm /* Check if an error occurred in the decompression process. */ 599299425Smm if (uncompressed_size < 0) { 600299425Smm archive_set_error(&(self->archive->archive), 601299425Smm ARCHIVE_ERRNO_MISC, "lz4 decompression failed"); 602299425Smm return (ARCHIVE_FATAL); 603299425Smm } 604299425Smm 605299425Smm state->unconsumed = 4 + compressed_size + checksum_size; 606299425Smm *p = state->out_block + prefix64k; 607299425Smm state->decoded_size = uncompressed_size; 608299425Smm return uncompressed_size; 609299425Smm 610299425Smmmalformed_error: 611299425Smm archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 612299425Smm "malformed lz4 data"); 613299425Smm return (ARCHIVE_FATAL); 614299425Smmtruncated_error: 615299425Smm archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 616299425Smm "truncated lz4 input"); 617299425Smm return (ARCHIVE_FATAL); 618299425Smm} 619299425Smm 620299425Smmstatic ssize_t 621299425Smmlz4_filter_read_default_stream(struct archive_read_filter *self, const void **p) 622299425Smm{ 623299425Smm struct private_data *state = (struct private_data *)self->data; 624299425Smm const char *read_buf; 625299425Smm ssize_t bytes_remaining; 626299425Smm ssize_t ret; 627299425Smm 628299425Smm if (state->stage == SELECT_STREAM) { 629299425Smm state->stage = READ_DEFAULT_STREAM; 630313571Smm /* First, read a descriptor. */ 631299425Smm if((ret = lz4_filter_read_descriptor(self)) != ARCHIVE_OK) 632299425Smm return (ret); 633299425Smm state->stage = READ_DEFAULT_BLOCK; 634299425Smm } 635299425Smm /* Decompress a block. */ 636299425Smm ret = lz4_filter_read_data_block(self, p); 637299425Smm 638299425Smm /* If the end of block is detected, change the filter status 639299425Smm to read next stream. */ 640299425Smm if (ret == 0 && *p == NULL) 641299425Smm state->stage = SELECT_STREAM; 642299425Smm 643353377Smm /* Optional processing, checking a stream sum. */ 644299425Smm if (state->flags.stream_checksum) { 645299425Smm if (state->stage == SELECT_STREAM) { 646299425Smm unsigned int checksum; 647299425Smm unsigned int checksum_stream; 648299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 649299425Smm 4, &bytes_remaining); 650299425Smm if (read_buf == NULL) { 651299425Smm archive_set_error(&self->archive->archive, 652299425Smm ARCHIVE_ERRNO_MISC, "truncated lz4 input"); 653299425Smm return (ARCHIVE_FATAL); 654299425Smm } 655299425Smm checksum = archive_le32dec(read_buf); 656299425Smm __archive_read_filter_consume(self->upstream, 4); 657299425Smm checksum_stream = __archive_xxhash.XXH32_digest( 658299425Smm state->xxh32_state); 659299425Smm state->xxh32_state = NULL; 660299425Smm if (checksum != checksum_stream) { 661299425Smm archive_set_error(&self->archive->archive, 662299425Smm ARCHIVE_ERRNO_MISC, 663353377Smm "lz4 stream checksum error"); 664299425Smm return (ARCHIVE_FATAL); 665299425Smm } 666299425Smm } else if (ret > 0) 667299425Smm __archive_xxhash.XXH32_update(state->xxh32_state, 668299425Smm *p, (int)ret); 669299425Smm } 670299425Smm return (ret); 671299425Smm} 672299425Smm 673299425Smmstatic ssize_t 674299425Smmlz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p) 675299425Smm{ 676299425Smm struct private_data *state = (struct private_data *)self->data; 677353377Smm uint32_t compressed; 678299425Smm const char *read_buf; 679299425Smm ssize_t ret; 680299425Smm 681299425Smm *p = NULL; 682299425Smm ret = lz4_allocate_out_block_for_legacy(self); 683299425Smm if (ret != ARCHIVE_OK) 684299425Smm return ret; 685299425Smm 686299425Smm /* Make sure we have 4 bytes for a block size. */ 687299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 4, NULL); 688299425Smm if (read_buf == NULL) { 689299425Smm if (state->stage == SELECT_STREAM) { 690299425Smm state->stage = READ_LEGACY_STREAM; 691299425Smm archive_set_error(&self->archive->archive, 692299425Smm ARCHIVE_ERRNO_MISC, 693299425Smm "truncated lz4 input"); 694299425Smm return (ARCHIVE_FATAL); 695299425Smm } 696299425Smm state->stage = SELECT_STREAM; 697299425Smm return 0; 698299425Smm } 699299425Smm state->stage = READ_LEGACY_BLOCK; 700299425Smm compressed = archive_le32dec(read_buf); 701299425Smm if (compressed > LZ4_COMPRESSBOUND(LEGACY_BLOCK_SIZE)) { 702299425Smm state->stage = SELECT_STREAM; 703299425Smm return 0; 704299425Smm } 705299425Smm 706299425Smm /* Make sure we have a whole block. */ 707299425Smm read_buf = __archive_read_filter_ahead(self->upstream, 708299425Smm 4 + compressed, NULL); 709313571Smm if (read_buf == NULL) { 710313571Smm archive_set_error(&(self->archive->archive), 711313571Smm ARCHIVE_ERRNO_MISC, "truncated lz4 input"); 712313571Smm return (ARCHIVE_FATAL); 713313571Smm } 714299425Smm ret = LZ4_decompress_safe(read_buf + 4, state->out_block, 715299425Smm compressed, (int)state->out_block_size); 716299425Smm if (ret < 0) { 717299425Smm archive_set_error(&(self->archive->archive), 718299425Smm ARCHIVE_ERRNO_MISC, "lz4 decompression failed"); 719299425Smm return (ARCHIVE_FATAL); 720299425Smm } 721299425Smm *p = state->out_block; 722299425Smm state->unconsumed = 4 + compressed; 723299425Smm return ret; 724299425Smm} 725299425Smm 726299425Smm/* 727299425Smm * Clean up the decompressor. 728299425Smm */ 729299425Smmstatic int 730299425Smmlz4_filter_close(struct archive_read_filter *self) 731299425Smm{ 732299425Smm struct private_data *state; 733299425Smm int ret = ARCHIVE_OK; 734299425Smm 735299425Smm state = (struct private_data *)self->data; 736299425Smm free(state->xxh32_state); 737299425Smm free(state->out_block); 738299425Smm free(state); 739299425Smm return (ret); 740299425Smm} 741299425Smm 742299425Smm#endif /* HAVE_LIBLZ4 */ 743