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