1231200Smm/*-
2232153Smm * Copyright (c) 2010-2012 Michihiro NAKAJIMA
3231200Smm * All rights reserved.
4231200Smm *
5231200Smm * Redistribution and use in source and binary forms, with or without
6231200Smm * modification, are permitted provided that the following conditions
7231200Smm * are met:
8231200Smm * 1. Redistributions of source code must retain the above copyright
9231200Smm *    notice, this list of conditions and the following disclaimer.
10231200Smm * 2. Redistributions in binary form must reproduce the above copyright
11231200Smm *    notice, this list of conditions and the following disclaimer in the
12231200Smm *    documentation and/or other materials provided with the distribution.
13231200Smm *
14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24231200Smm */
25231200Smm
26231200Smm#include "archive_platform.h"
27231200Smm
28231200Smm#ifdef HAVE_ERRNO_H
29231200Smm#include <errno.h>
30231200Smm#endif
31231200Smm#ifdef HAVE_LIMITS_H
32231200Smm#include <limits.h>
33231200Smm#endif
34231200Smm#ifdef HAVE_STDLIB_H
35231200Smm#include <stdlib.h>
36231200Smm#endif
37231200Smm#ifdef HAVE_STRING_H
38231200Smm#include <string.h>
39231200Smm#endif
40231200Smm#ifdef HAVE_ZLIB_H
41231200Smm#include <zlib.h>
42231200Smm#endif
43231200Smm
44231200Smm#include "archive.h"
45231200Smm#include "archive_entry.h"
46231200Smm#include "archive_entry_locale.h"
47231200Smm#include "archive_private.h"
48231200Smm#include "archive_read_private.h"
49231200Smm#include "archive_endian.h"
50231200Smm
51231200Smm
52231200Smmstruct lzx_dec {
53231200Smm	/* Decoding status. */
54231200Smm	int     		 state;
55231200Smm
56231200Smm	/*
57231200Smm	 * Window to see last decoded data, from 32KBi to 2MBi.
58231200Smm	 */
59231200Smm	int			 w_size;
60231200Smm	int			 w_mask;
61231200Smm	/* Window buffer, which is a loop buffer. */
62231200Smm	unsigned char		*w_buff;
63231200Smm	/* The insert position to the window. */
64231200Smm	int			 w_pos;
65231200Smm	/* The position where we can copy decoded code from the window. */
66231200Smm	int     		 copy_pos;
67231200Smm	/* The length how many bytes we can copy decoded code from
68231200Smm	 * the window. */
69231200Smm	int     		 copy_len;
70311042Smm	/* Translation reversal for x86 processor CALL byte sequence(E8).
71231200Smm	 * This is used for LZX only. */
72231200Smm	uint32_t		 translation_size;
73231200Smm	char			 translation;
74231200Smm	char			 block_type;
75231200Smm#define VERBATIM_BLOCK		1
76231200Smm#define ALIGNED_OFFSET_BLOCK	2
77231200Smm#define UNCOMPRESSED_BLOCK	3
78231200Smm	size_t			 block_size;
79231200Smm	size_t			 block_bytes_avail;
80231200Smm	/* Repeated offset. */
81231200Smm	int			 r0, r1, r2;
82231200Smm	unsigned char		 rbytes[4];
83231200Smm	int			 rbytes_avail;
84231200Smm	int			 length_header;
85231200Smm	int			 position_slot;
86231200Smm	int			 offset_bits;
87231200Smm
88231200Smm	struct lzx_pos_tbl {
89231200Smm		int		 base;
90231200Smm		int		 footer_bits;
91231200Smm	}			*pos_tbl;
92231200Smm	/*
93231200Smm	 * Bit stream reader.
94231200Smm	 */
95231200Smm	struct lzx_br {
96231200Smm#define CACHE_TYPE		uint64_t
97231200Smm#define CACHE_BITS		(8 * sizeof(CACHE_TYPE))
98231200Smm	 	/* Cache buffer. */
99231200Smm		CACHE_TYPE	 cache_buffer;
100231200Smm		/* Indicates how many bits avail in cache_buffer. */
101231200Smm		int		 cache_avail;
102231200Smm		unsigned char	 odd;
103231200Smm		char		 have_odd;
104231200Smm	} br;
105231200Smm
106231200Smm	/*
107231200Smm	 * Huffman coding.
108231200Smm	 */
109231200Smm	struct huffman {
110231200Smm		int		 len_size;
111231200Smm		int		 freq[17];
112231200Smm		unsigned char	*bitlen;
113231200Smm
114231200Smm		/*
115231200Smm		 * Use a index table. It's faster than searching a huffman
116231200Smm		 * coding tree, which is a binary tree. But a use of a large
117231200Smm		 * index table causes L1 cache read miss many times.
118231200Smm		 */
119231200Smm		int		 max_bits;
120231200Smm		int		 tbl_bits;
121231200Smm		int		 tree_used;
122231200Smm		/* Direct access table. */
123231200Smm		uint16_t	*tbl;
124231200Smm	}			 at, lt, mt, pt;
125231200Smm
126231200Smm	int			 loop;
127231200Smm	int			 error;
128231200Smm};
129231200Smm
130231200Smmstatic const int slots[] = {
131231200Smm	30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290
132231200Smm};
133231200Smm#define SLOT_BASE	15
134231200Smm#define SLOT_MAX	21/*->25*/
135231200Smm
136231200Smmstruct lzx_stream {
137231200Smm	const unsigned char	*next_in;
138231200Smm	int64_t			 avail_in;
139231200Smm	int64_t			 total_in;
140231200Smm	unsigned char		*next_out;
141231200Smm	int64_t			 avail_out;
142231200Smm	int64_t			 total_out;
143231200Smm	struct lzx_dec		*ds;
144231200Smm};
145231200Smm
146231200Smm/*
147231200Smm * Cabinet file definitions.
148231200Smm */
149231200Smm/* CFHEADER offset */
150231200Smm#define CFHEADER_signature	0
151231200Smm#define CFHEADER_cbCabinet	8
152231200Smm#define CFHEADER_coffFiles	16
153231200Smm#define CFHEADER_versionMinor	24
154231200Smm#define CFHEADER_versionMajor	25
155231200Smm#define CFHEADER_cFolders	26
156231200Smm#define CFHEADER_cFiles		28
157231200Smm#define CFHEADER_flags		30
158231200Smm#define CFHEADER_setID		32
159231200Smm#define CFHEADER_iCabinet	34
160231200Smm#define CFHEADER_cbCFHeader	36
161231200Smm#define CFHEADER_cbCFFolder	38
162231200Smm#define CFHEADER_cbCFData	39
163231200Smm
164231200Smm/* CFFOLDER offset */
165231200Smm#define CFFOLDER_coffCabStart	0
166231200Smm#define CFFOLDER_cCFData	4
167231200Smm#define CFFOLDER_typeCompress	6
168231200Smm#define CFFOLDER_abReserve	8
169231200Smm
170231200Smm/* CFFILE offset */
171231200Smm#define CFFILE_cbFile		0
172231200Smm#define CFFILE_uoffFolderStart	4
173231200Smm#define CFFILE_iFolder		8
174231200Smm#define CFFILE_date_time	10
175231200Smm#define CFFILE_attribs		14
176231200Smm
177231200Smm/* CFDATA offset */
178231200Smm#define CFDATA_csum		0
179231200Smm#define CFDATA_cbData		4
180231200Smm#define CFDATA_cbUncomp		6
181231200Smm
182316338Smmstatic const char * const compression_name[] = {
183231200Smm	"NONE",
184231200Smm	"MSZIP",
185231200Smm	"Quantum",
186231200Smm	"LZX",
187231200Smm};
188231200Smm
189231200Smmstruct cfdata {
190231200Smm	/* Sum value of this CFDATA. */
191231200Smm	uint32_t		 sum;
192231200Smm	uint16_t		 compressed_size;
193231200Smm	uint16_t		 compressed_bytes_remaining;
194231200Smm	uint16_t		 uncompressed_size;
195231200Smm	uint16_t		 uncompressed_bytes_remaining;
196231200Smm	/* To know how many bytes we have decompressed. */
197231200Smm	uint16_t		 uncompressed_avail;
198231200Smm	/* Offset from the beginning of compressed data of this CFDATA */
199231200Smm	uint16_t		 read_offset;
200231200Smm	int64_t			 unconsumed;
201231200Smm	/* To keep memory image of this CFDATA to compute the sum. */
202231200Smm	size_t			 memimage_size;
203231200Smm	unsigned char		*memimage;
204231200Smm	/* Result of calculation of sum. */
205231200Smm	uint32_t		 sum_calculated;
206231200Smm	unsigned char		 sum_extra[4];
207231200Smm	int			 sum_extra_avail;
208231200Smm	const void		*sum_ptr;
209231200Smm};
210231200Smm
211231200Smmstruct cffolder {
212231200Smm	uint32_t		 cfdata_offset_in_cab;
213231200Smm	uint16_t		 cfdata_count;
214231200Smm	uint16_t		 comptype;
215231200Smm#define COMPTYPE_NONE		0x0000
216231200Smm#define COMPTYPE_MSZIP		0x0001
217231200Smm#define COMPTYPE_QUANTUM	0x0002
218231200Smm#define COMPTYPE_LZX		0x0003
219231200Smm	uint16_t		 compdata;
220231200Smm	const char		*compname;
221231200Smm	/* At the time reading CFDATA */
222231200Smm	struct cfdata		 cfdata;
223231200Smm	int			 cfdata_index;
224231200Smm	/* Flags to mark progress of decompression. */
225231200Smm	char			 decompress_init;
226231200Smm};
227231200Smm
228231200Smmstruct cffile {
229231200Smm	uint32_t		 uncompressed_size;
230231200Smm	uint32_t		 offset;
231231200Smm	time_t			 mtime;
232231200Smm	uint16_t	 	 folder;
233231200Smm#define iFoldCONTINUED_FROM_PREV	0xFFFD
234231200Smm#define iFoldCONTINUED_TO_NEXT		0xFFFE
235231200Smm#define iFoldCONTINUED_PREV_AND_NEXT	0xFFFF
236231200Smm	unsigned char		 attr;
237231200Smm#define ATTR_RDONLY		0x01
238231200Smm#define ATTR_NAME_IS_UTF	0x80
239231200Smm	struct archive_string 	 pathname;
240231200Smm};
241231200Smm
242231200Smmstruct cfheader {
243231200Smm	/* Total bytes of all file size in a Cabinet. */
244231200Smm	uint32_t		 total_bytes;
245231200Smm	uint32_t		 files_offset;
246231200Smm	uint16_t		 folder_count;
247231200Smm	uint16_t		 file_count;
248231200Smm	uint16_t		 flags;
249231200Smm#define PREV_CABINET	0x0001
250231200Smm#define NEXT_CABINET	0x0002
251231200Smm#define RESERVE_PRESENT	0x0004
252231200Smm	uint16_t		 setid;
253231200Smm	uint16_t		 cabinet;
254231200Smm	/* Version number. */
255231200Smm	unsigned char		 major;
256231200Smm	unsigned char		 minor;
257231200Smm	unsigned char		 cffolder;
258231200Smm	unsigned char		 cfdata;
259231200Smm	/* All folders in a cabinet. */
260231200Smm	struct cffolder		*folder_array;
261231200Smm	/* All files in a cabinet. */
262231200Smm	struct cffile		*file_array;
263231200Smm	int			 file_index;
264231200Smm};
265231200Smm
266231200Smmstruct cab {
267231200Smm	/* entry_bytes_remaining is the number of bytes we expect.	    */
268231200Smm	int64_t			 entry_offset;
269231200Smm	int64_t			 entry_bytes_remaining;
270231200Smm	int64_t			 entry_unconsumed;
271231200Smm	int64_t			 entry_compressed_bytes_read;
272231200Smm	int64_t			 entry_uncompressed_bytes_read;
273231200Smm	struct cffolder		*entry_cffolder;
274231200Smm	struct cffile		*entry_cffile;
275231200Smm	struct cfdata		*entry_cfdata;
276231200Smm
277231200Smm	/* Offset from beginning of a cabinet file. */
278231200Smm	int64_t			 cab_offset;
279231200Smm	struct cfheader		 cfheader;
280231200Smm	struct archive_wstring	 ws;
281231200Smm
282231200Smm	/* Flag to mark progress that an archive was read their first header.*/
283231200Smm	char			 found_header;
284231200Smm	char			 end_of_archive;
285231200Smm	char			 end_of_entry;
286231200Smm	char			 end_of_entry_cleanup;
287238856Smm	char			 read_data_invoked;
288238856Smm	int64_t			 bytes_skipped;
289231200Smm
290231200Smm	unsigned char		*uncompressed_buffer;
291231200Smm	size_t			 uncompressed_buffer_size;
292231200Smm
293231200Smm	int			 init_default_conversion;
294231200Smm	struct archive_string_conv *sconv;
295231200Smm	struct archive_string_conv *sconv_default;
296231200Smm	struct archive_string_conv *sconv_utf8;
297231200Smm	char			 format_name[64];
298231200Smm
299231200Smm#ifdef HAVE_ZLIB_H
300231200Smm	z_stream		 stream;
301231200Smm	char			 stream_valid;
302231200Smm#endif
303231200Smm	struct lzx_stream	 xstrm;
304231200Smm};
305231200Smm
306231200Smmstatic int	archive_read_format_cab_bid(struct archive_read *, int);
307231200Smmstatic int	archive_read_format_cab_options(struct archive_read *,
308231200Smm		    const char *, const char *);
309231200Smmstatic int	archive_read_format_cab_read_header(struct archive_read *,
310231200Smm		    struct archive_entry *);
311231200Smmstatic int	archive_read_format_cab_read_data(struct archive_read *,
312231200Smm		    const void **, size_t *, int64_t *);
313231200Smmstatic int	archive_read_format_cab_read_data_skip(struct archive_read *);
314231200Smmstatic int	archive_read_format_cab_cleanup(struct archive_read *);
315231200Smm
316231200Smmstatic int	cab_skip_sfx(struct archive_read *);
317231200Smmstatic time_t	cab_dos_time(const unsigned char *);
318231200Smmstatic int	cab_read_data(struct archive_read *, const void **,
319231200Smm		    size_t *, int64_t *);
320231200Smmstatic int	cab_read_header(struct archive_read *);
321231200Smmstatic uint32_t cab_checksum_cfdata_4(const void *, size_t bytes, uint32_t);
322231200Smmstatic uint32_t cab_checksum_cfdata(const void *, size_t bytes, uint32_t);
323231200Smmstatic void	cab_checksum_update(struct archive_read *, size_t);
324231200Smmstatic int	cab_checksum_finish(struct archive_read *);
325231200Smmstatic int	cab_next_cfdata(struct archive_read *);
326231200Smmstatic const void *cab_read_ahead_cfdata(struct archive_read *, ssize_t *);
327231200Smmstatic const void *cab_read_ahead_cfdata_none(struct archive_read *, ssize_t *);
328231200Smmstatic const void *cab_read_ahead_cfdata_deflate(struct archive_read *,
329231200Smm		    ssize_t *);
330231200Smmstatic const void *cab_read_ahead_cfdata_lzx(struct archive_read *,
331231200Smm		    ssize_t *);
332231200Smmstatic int64_t	cab_consume_cfdata(struct archive_read *, int64_t);
333231200Smmstatic int64_t	cab_minimum_consume_cfdata(struct archive_read *, int64_t);
334231200Smmstatic int	lzx_decode_init(struct lzx_stream *, int);
335231200Smmstatic int	lzx_read_blocks(struct lzx_stream *, int);
336231200Smmstatic int	lzx_decode_blocks(struct lzx_stream *, int);
337231200Smmstatic void	lzx_decode_free(struct lzx_stream *);
338231200Smmstatic void	lzx_translation(struct lzx_stream *, void *, size_t, uint32_t);
339231200Smmstatic void	lzx_cleanup_bitstream(struct lzx_stream *);
340231200Smmstatic int	lzx_decode(struct lzx_stream *, int);
341231200Smmstatic int	lzx_read_pre_tree(struct lzx_stream *);
342231200Smmstatic int	lzx_read_bitlen(struct lzx_stream *, struct huffman *, int);
343231200Smmstatic int	lzx_huffman_init(struct huffman *, size_t, int);
344231200Smmstatic void	lzx_huffman_free(struct huffman *);
345231200Smmstatic int	lzx_make_huffman_table(struct huffman *);
346232153Smmstatic inline int lzx_decode_huffman(struct huffman *, unsigned);
347231200Smm
348231200Smm
349231200Smmint
350231200Smmarchive_read_support_format_cab(struct archive *_a)
351231200Smm{
352231200Smm	struct archive_read *a = (struct archive_read *)_a;
353231200Smm	struct cab *cab;
354231200Smm	int r;
355231200Smm
356231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
357231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_format_cab");
358231200Smm
359231200Smm	cab = (struct cab *)calloc(1, sizeof(*cab));
360231200Smm	if (cab == NULL) {
361231200Smm		archive_set_error(&a->archive, ENOMEM,
362231200Smm		    "Can't allocate CAB data");
363231200Smm		return (ARCHIVE_FATAL);
364231200Smm	}
365231200Smm	archive_string_init(&cab->ws);
366231200Smm	archive_wstring_ensure(&cab->ws, 256);
367231200Smm
368231200Smm	r = __archive_read_register_format(a,
369231200Smm	    cab,
370231200Smm	    "cab",
371231200Smm	    archive_read_format_cab_bid,
372231200Smm	    archive_read_format_cab_options,
373231200Smm	    archive_read_format_cab_read_header,
374231200Smm	    archive_read_format_cab_read_data,
375231200Smm	    archive_read_format_cab_read_data_skip,
376248616Smm	    NULL,
377302001Smm	    archive_read_format_cab_cleanup,
378302001Smm	    NULL,
379302001Smm	    NULL);
380231200Smm
381231200Smm	if (r != ARCHIVE_OK)
382231200Smm		free(cab);
383231200Smm	return (ARCHIVE_OK);
384231200Smm}
385231200Smm
386231200Smmstatic int
387231200Smmfind_cab_magic(const char *p)
388231200Smm{
389231200Smm	switch (p[4]) {
390231200Smm	case 0:
391231200Smm		/*
392231200Smm		 * Note: Self-Extraction program has 'MSCF' string in their
393231200Smm		 * program. If we were finding 'MSCF' string only, we got
394231200Smm		 * wrong place for Cabinet header, thus, we have to check
395231200Smm		 * following four bytes which are reserved and must be set
396231200Smm		 * to zero.
397231200Smm		 */
398231200Smm		if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
399231200Smm			return 0;
400231200Smm		return 5;
401231200Smm	case 'F': return 1;
402231200Smm	case 'C': return 2;
403231200Smm	case 'S': return 3;
404231200Smm	case 'M': return 4;
405231200Smm	default:  return 5;
406231200Smm	}
407231200Smm}
408231200Smm
409231200Smmstatic int
410231200Smmarchive_read_format_cab_bid(struct archive_read *a, int best_bid)
411231200Smm{
412231200Smm	const char *p;
413231200Smm	ssize_t bytes_avail, offset, window;
414231200Smm
415231200Smm	/* If there's already a better bid than we can ever
416231200Smm	   make, don't bother testing. */
417231200Smm	if (best_bid > 64)
418231200Smm		return (-1);
419231200Smm
420231200Smm	if ((p = __archive_read_ahead(a, 8, NULL)) == NULL)
421231200Smm		return (-1);
422231200Smm
423231200Smm	if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
424231200Smm		return (64);
425231200Smm
426231200Smm	/*
427231200Smm	 * Attempt to handle self-extracting archives
428231200Smm	 * by noting a PE header and searching forward
429231200Smm	 * up to 128k for a 'MSCF' marker.
430231200Smm	 */
431231200Smm	if (p[0] == 'M' && p[1] == 'Z') {
432231200Smm		offset = 0;
433231200Smm		window = 4096;
434231200Smm		while (offset < (1024 * 128)) {
435231200Smm			const char *h = __archive_read_ahead(a, offset + window,
436231200Smm			    &bytes_avail);
437231200Smm			if (h == NULL) {
438231200Smm				/* Remaining bytes are less than window. */
439231200Smm				window >>= 1;
440231200Smm				if (window < 128)
441231200Smm					return (0);
442231200Smm				continue;
443231200Smm			}
444231200Smm			p = h + offset;
445231200Smm			while (p + 8 < h + bytes_avail) {
446231200Smm				int next;
447231200Smm				if ((next = find_cab_magic(p)) == 0)
448231200Smm					return (64);
449231200Smm				p += next;
450231200Smm			}
451231200Smm			offset = p - h;
452231200Smm		}
453231200Smm	}
454231200Smm	return (0);
455231200Smm}
456231200Smm
457231200Smmstatic int
458231200Smmarchive_read_format_cab_options(struct archive_read *a,
459231200Smm    const char *key, const char *val)
460231200Smm{
461231200Smm	struct cab *cab;
462231200Smm	int ret = ARCHIVE_FAILED;
463231200Smm
464231200Smm	cab = (struct cab *)(a->format->data);
465231200Smm	if (strcmp(key, "hdrcharset")  == 0) {
466231200Smm		if (val == NULL || val[0] == 0)
467231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
468231200Smm			    "cab: hdrcharset option needs a character-set name");
469231200Smm		else {
470231200Smm			cab->sconv = archive_string_conversion_from_charset(
471231200Smm			    &a->archive, val, 0);
472231200Smm			if (cab->sconv != NULL)
473231200Smm				ret = ARCHIVE_OK;
474231200Smm			else
475231200Smm				ret = ARCHIVE_FATAL;
476231200Smm		}
477232153Smm		return (ret);
478232153Smm	}
479231200Smm
480232153Smm	/* Note: The "warn" return is just to inform the options
481232153Smm	 * supervisor that we didn't handle it.  It will generate
482232153Smm	 * a suitable error if no one used this option. */
483232153Smm	return (ARCHIVE_WARN);
484231200Smm}
485231200Smm
486231200Smmstatic int
487231200Smmcab_skip_sfx(struct archive_read *a)
488231200Smm{
489231200Smm	const char *p, *q;
490231200Smm	size_t skip;
491231200Smm	ssize_t bytes, window;
492231200Smm
493231200Smm	window = 4096;
494231200Smm	for (;;) {
495231200Smm		const char *h = __archive_read_ahead(a, window, &bytes);
496231200Smm		if (h == NULL) {
497231200Smm			/* Remaining size are less than window. */
498231200Smm			window >>= 1;
499231200Smm			if (window < 128) {
500231200Smm				archive_set_error(&a->archive,
501231200Smm				    ARCHIVE_ERRNO_FILE_FORMAT,
502231200Smm				    "Couldn't find out CAB header");
503231200Smm				return (ARCHIVE_FATAL);
504231200Smm			}
505231200Smm			continue;
506231200Smm		}
507231200Smm		p = h;
508231200Smm		q = p + bytes;
509231200Smm
510231200Smm		/*
511231200Smm		 * Scan ahead until we find something that looks
512231200Smm		 * like the cab header.
513231200Smm		 */
514231200Smm		while (p + 8 < q) {
515231200Smm			int next;
516231200Smm			if ((next = find_cab_magic(p)) == 0) {
517231200Smm				skip = p - h;
518231200Smm				__archive_read_consume(a, skip);
519231200Smm				return (ARCHIVE_OK);
520231200Smm			}
521231200Smm			p += next;
522231200Smm		}
523231200Smm		skip = p - h;
524231200Smm		__archive_read_consume(a, skip);
525231200Smm	}
526231200Smm}
527231200Smm
528231200Smmstatic int
529231200Smmtruncated_error(struct archive_read *a)
530231200Smm{
531231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
532231200Smm	    "Truncated CAB header");
533231200Smm	return (ARCHIVE_FATAL);
534231200Smm}
535231200Smm
536248616Smmstatic ssize_t
537231200Smmcab_strnlen(const unsigned char *p, size_t maxlen)
538231200Smm{
539231200Smm	size_t i;
540231200Smm
541231200Smm	for (i = 0; i <= maxlen; i++) {
542231200Smm		if (p[i] == 0)
543231200Smm			break;
544231200Smm	}
545231200Smm	if (i > maxlen)
546231200Smm		return (-1);/* invalid */
547248616Smm	return ((ssize_t)i);
548231200Smm}
549231200Smm
550231200Smm/* Read bytes as much as remaining. */
551231200Smmstatic const void *
552231200Smmcab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail)
553231200Smm{
554231200Smm	const void *p;
555231200Smm
556231200Smm	while (min > 0) {
557231200Smm		p = __archive_read_ahead(a, min, avail);
558231200Smm		if (p != NULL)
559231200Smm			return (p);
560231200Smm		min--;
561231200Smm	}
562231200Smm	return (NULL);
563231200Smm}
564231200Smm
565231200Smm/* Convert a path separator '\' -> '/' */
566231200Smmstatic int
567231200Smmcab_convert_path_separator_1(struct archive_string *fn, unsigned char attr)
568231200Smm{
569231200Smm	size_t i;
570231200Smm	int mb;
571231200Smm
572231200Smm	/* Easy check if we have '\' in multi-byte string. */
573231200Smm	mb = 0;
574231200Smm	for (i = 0; i < archive_strlen(fn); i++) {
575231200Smm		if (fn->s[i] == '\\') {
576231200Smm			if (mb) {
577231200Smm				/* This may be second byte of multi-byte
578231200Smm				 * character. */
579231200Smm				break;
580231200Smm			}
581231200Smm			fn->s[i] = '/';
582231200Smm			mb = 0;
583231200Smm		} else if ((fn->s[i] & 0x80) && !(attr & ATTR_NAME_IS_UTF))
584231200Smm			mb = 1;
585231200Smm		else
586231200Smm			mb = 0;
587231200Smm	}
588231200Smm	if (i == archive_strlen(fn))
589231200Smm		return (0);
590231200Smm	return (-1);
591231200Smm}
592231200Smm
593231200Smm/*
594231200Smm * Replace a character '\' with '/' in wide character.
595231200Smm */
596231200Smmstatic void
597231200Smmcab_convert_path_separator_2(struct cab *cab, struct archive_entry *entry)
598231200Smm{
599231200Smm	const wchar_t *wp;
600231200Smm	size_t i;
601231200Smm
602231200Smm	/* If a conversion to wide character failed, force the replacement. */
603231200Smm	if ((wp = archive_entry_pathname_w(entry)) != NULL) {
604231200Smm		archive_wstrcpy(&(cab->ws), wp);
605231200Smm		for (i = 0; i < archive_strlen(&(cab->ws)); i++) {
606231200Smm			if (cab->ws.s[i] == L'\\')
607231200Smm				cab->ws.s[i] = L'/';
608231200Smm		}
609231200Smm		archive_entry_copy_pathname_w(entry, cab->ws.s);
610231200Smm	}
611231200Smm}
612231200Smm
613231200Smm/*
614231200Smm * Read CFHEADER, CFFOLDER and CFFILE.
615231200Smm */
616231200Smmstatic int
617231200Smmcab_read_header(struct archive_read *a)
618231200Smm{
619231200Smm	const unsigned char *p;
620231200Smm	struct cab *cab;
621231200Smm	struct cfheader *hd;
622231200Smm	size_t bytes, used;
623248616Smm	ssize_t len;
624231200Smm	int64_t skip;
625248616Smm	int err, i;
626231200Smm	int cur_folder, prev_folder;
627231200Smm	uint32_t offset32;
628231200Smm
629231200Smm	a->archive.archive_format = ARCHIVE_FORMAT_CAB;
630231200Smm	if (a->archive.archive_format_name == NULL)
631231200Smm		a->archive.archive_format_name = "CAB";
632231200Smm
633231200Smm	if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
634231200Smm		return (truncated_error(a));
635231200Smm
636231200Smm	cab = (struct cab *)(a->format->data);
637231200Smm	if (cab->found_header == 0 &&
638231200Smm	    p[0] == 'M' && p[1] == 'Z') {
639311042Smm		/* This is an executable?  Must be self-extracting... */
640231200Smm		err = cab_skip_sfx(a);
641231200Smm		if (err < ARCHIVE_WARN)
642231200Smm			return (err);
643231200Smm
644311042Smm		/* Re-read header after processing the SFX. */
645311042Smm		if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
646231200Smm			return (truncated_error(a));
647231200Smm	}
648231200Smm
649231200Smm	cab->cab_offset = 0;
650231200Smm	/*
651231200Smm	 * Read CFHEADER.
652231200Smm	 */
653231200Smm	hd = &cab->cfheader;
654231200Smm	if (p[CFHEADER_signature+0] != 'M' || p[CFHEADER_signature+1] != 'S' ||
655231200Smm	    p[CFHEADER_signature+2] != 'C' || p[CFHEADER_signature+3] != 'F') {
656231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
657231200Smm		    "Couldn't find out CAB header");
658231200Smm		return (ARCHIVE_FATAL);
659231200Smm	}
660231200Smm	hd->total_bytes = archive_le32dec(p + CFHEADER_cbCabinet);
661231200Smm	hd->files_offset = archive_le32dec(p + CFHEADER_coffFiles);
662231200Smm	hd->minor = p[CFHEADER_versionMinor];
663231200Smm	hd->major = p[CFHEADER_versionMajor];
664231200Smm	hd->folder_count = archive_le16dec(p + CFHEADER_cFolders);
665231200Smm	if (hd->folder_count == 0)
666231200Smm		goto invalid;
667231200Smm	hd->file_count = archive_le16dec(p + CFHEADER_cFiles);
668231200Smm	if (hd->file_count == 0)
669231200Smm		goto invalid;
670231200Smm	hd->flags = archive_le16dec(p + CFHEADER_flags);
671231200Smm	hd->setid = archive_le16dec(p + CFHEADER_setID);
672231200Smm	hd->cabinet = archive_le16dec(p + CFHEADER_iCabinet);
673231200Smm	used = CFHEADER_iCabinet + 2;
674231200Smm	if (hd->flags & RESERVE_PRESENT) {
675231200Smm		uint16_t cfheader;
676231200Smm		cfheader = archive_le16dec(p + CFHEADER_cbCFHeader);
677231200Smm		if (cfheader > 60000U)
678231200Smm			goto invalid;
679231200Smm		hd->cffolder = p[CFHEADER_cbCFFolder];
680231200Smm		hd->cfdata = p[CFHEADER_cbCFData];
681231200Smm		used += 4;/* cbCFHeader, cbCFFolder and cbCFData */
682231200Smm		used += cfheader;/* abReserve */
683231200Smm	} else
684231200Smm		hd->cffolder = 0;/* Avoid compiling warning. */
685231200Smm	if (hd->flags & PREV_CABINET) {
686231200Smm		/* How many bytes are used for szCabinetPrev. */
687231200Smm		if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
688231200Smm			return (truncated_error(a));
689231200Smm		if ((len = cab_strnlen(p + used, 255)) <= 0)
690231200Smm			goto invalid;
691231200Smm		used += len + 1;
692231200Smm		/* How many bytes are used for szDiskPrev. */
693231200Smm		if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
694231200Smm			return (truncated_error(a));
695231200Smm		if ((len = cab_strnlen(p + used, 255)) <= 0)
696231200Smm			goto invalid;
697231200Smm		used += len + 1;
698231200Smm	}
699231200Smm	if (hd->flags & NEXT_CABINET) {
700231200Smm		/* How many bytes are used for szCabinetNext. */
701231200Smm		if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
702231200Smm			return (truncated_error(a));
703231200Smm		if ((len = cab_strnlen(p + used, 255)) <= 0)
704231200Smm			goto invalid;
705231200Smm		used += len + 1;
706231200Smm		/* How many bytes are used for szDiskNext. */
707231200Smm		if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
708231200Smm			return (truncated_error(a));
709231200Smm		if ((len = cab_strnlen(p + used, 255)) <= 0)
710231200Smm			goto invalid;
711231200Smm		used += len + 1;
712231200Smm	}
713231200Smm	__archive_read_consume(a, used);
714231200Smm	cab->cab_offset += used;
715231200Smm	used = 0;
716231200Smm
717231200Smm	/*
718231200Smm	 * Read CFFOLDER.
719231200Smm	 */
720231200Smm	hd->folder_array = (struct cffolder *)calloc(
721231200Smm	    hd->folder_count, sizeof(struct cffolder));
722231200Smm	if (hd->folder_array == NULL)
723231200Smm		goto nomem;
724231200Smm
725231200Smm	bytes = 8;
726231200Smm	if (hd->flags & RESERVE_PRESENT)
727231200Smm		bytes += hd->cffolder;
728231200Smm	bytes *= hd->folder_count;
729231200Smm	if ((p = __archive_read_ahead(a, bytes, NULL)) == NULL)
730231200Smm		return (truncated_error(a));
731231200Smm	offset32 = 0;
732231200Smm	for (i = 0; i < hd->folder_count; i++) {
733231200Smm		struct cffolder *folder = &(hd->folder_array[i]);
734231200Smm		folder->cfdata_offset_in_cab =
735231200Smm		    archive_le32dec(p + CFFOLDER_coffCabStart);
736231200Smm		folder->cfdata_count = archive_le16dec(p+CFFOLDER_cCFData);
737231200Smm		folder->comptype =
738231200Smm		    archive_le16dec(p+CFFOLDER_typeCompress) & 0x0F;
739231200Smm		folder->compdata =
740231200Smm		    archive_le16dec(p+CFFOLDER_typeCompress) >> 8;
741231200Smm		/* Get a compression name. */
742231200Smm		if (folder->comptype <
743231200Smm		    sizeof(compression_name) / sizeof(compression_name[0]))
744231200Smm			folder->compname = compression_name[folder->comptype];
745231200Smm		else
746231200Smm			folder->compname = "UNKNOWN";
747231200Smm		p += 8;
748231200Smm		used += 8;
749231200Smm		if (hd->flags & RESERVE_PRESENT) {
750231200Smm			p += hd->cffolder;/* abReserve */
751231200Smm			used += hd->cffolder;
752231200Smm		}
753231200Smm		/*
754231200Smm		 * Sanity check if each data is acceptable.
755231200Smm		 */
756231200Smm		if (offset32 >= folder->cfdata_offset_in_cab)
757231200Smm			goto invalid;
758231200Smm		offset32 = folder->cfdata_offset_in_cab;
759231200Smm
760231200Smm		/* Set a request to initialize zlib for the CFDATA of
761231200Smm		 * this folder. */
762231200Smm		folder->decompress_init = 0;
763231200Smm	}
764231200Smm	__archive_read_consume(a, used);
765231200Smm	cab->cab_offset += used;
766231200Smm
767231200Smm	/*
768231200Smm	 * Read CFFILE.
769231200Smm	 */
770231200Smm	/* Seek read pointer to the offset of CFFILE if needed. */
771231200Smm	skip = (int64_t)hd->files_offset - cab->cab_offset;
772231200Smm	if (skip <  0) {
773231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
774231200Smm		    "Invalid offset of CFFILE %jd < %jd",
775231200Smm		    (intmax_t)hd->files_offset, (intmax_t)cab->cab_offset);
776231200Smm		return (ARCHIVE_FATAL);
777231200Smm	}
778231200Smm	if (skip) {
779231200Smm		__archive_read_consume(a, skip);
780231200Smm		cab->cab_offset += skip;
781231200Smm	}
782231200Smm	/* Allocate memory for CFDATA */
783231200Smm	hd->file_array = (struct cffile *)calloc(
784231200Smm	    hd->file_count, sizeof(struct cffile));
785231200Smm	if (hd->file_array == NULL)
786231200Smm		goto nomem;
787231200Smm
788231200Smm	prev_folder = -1;
789231200Smm	for (i = 0; i < hd->file_count; i++) {
790231200Smm		struct cffile *file = &(hd->file_array[i]);
791231200Smm		ssize_t avail;
792231200Smm
793231200Smm		if ((p = __archive_read_ahead(a, 16, NULL)) == NULL)
794231200Smm			return (truncated_error(a));
795231200Smm		file->uncompressed_size = archive_le32dec(p + CFFILE_cbFile);
796231200Smm		file->offset = archive_le32dec(p + CFFILE_uoffFolderStart);
797231200Smm		file->folder = archive_le16dec(p + CFFILE_iFolder);
798231200Smm		file->mtime = cab_dos_time(p + CFFILE_date_time);
799238856Smm		file->attr = (uint8_t)archive_le16dec(p + CFFILE_attribs);
800231200Smm		__archive_read_consume(a, 16);
801231200Smm
802231200Smm		cab->cab_offset += 16;
803231200Smm		if ((p = cab_read_ahead_remaining(a, 256, &avail)) == NULL)
804231200Smm			return (truncated_error(a));
805231200Smm		if ((len = cab_strnlen(p, avail-1)) <= 0)
806231200Smm			goto invalid;
807231200Smm
808231200Smm		/* Copy a pathname.  */
809231200Smm		archive_string_init(&(file->pathname));
810231200Smm		archive_strncpy(&(file->pathname), p, len);
811231200Smm		__archive_read_consume(a, len + 1);
812231200Smm		cab->cab_offset += len + 1;
813231200Smm
814231200Smm		/*
815231200Smm		 * Sanity check if each data is acceptable.
816231200Smm		 */
817231200Smm		if (file->uncompressed_size > 0x7FFF8000)
818231200Smm			goto invalid;/* Too large */
819231200Smm		if ((int64_t)file->offset + (int64_t)file->uncompressed_size
820231200Smm		    > ARCHIVE_LITERAL_LL(0x7FFF8000))
821231200Smm			goto invalid;/* Too large */
822231200Smm		switch (file->folder) {
823231200Smm		case iFoldCONTINUED_TO_NEXT:
824231200Smm			/* This must be last file in a folder. */
825231200Smm			if (i != hd->file_count -1)
826231200Smm				goto invalid;
827231200Smm			cur_folder = hd->folder_count -1;
828231200Smm			break;
829231200Smm		case iFoldCONTINUED_PREV_AND_NEXT:
830231200Smm			/* This must be only one file in a folder. */
831231200Smm			if (hd->file_count != 1)
832231200Smm				goto invalid;
833231200Smm			/* FALL THROUGH */
834231200Smm		case iFoldCONTINUED_FROM_PREV:
835231200Smm			/* This must be first file in a folder. */
836231200Smm			if (i != 0)
837231200Smm				goto invalid;
838231200Smm			prev_folder = cur_folder = 0;
839231200Smm			offset32 = file->offset;
840231200Smm			break;
841231200Smm		default:
842231200Smm			if (file->folder >= hd->folder_count)
843231200Smm				goto invalid;
844231200Smm			cur_folder = file->folder;
845231200Smm			break;
846231200Smm		}
847231200Smm		/* Dot not back track. */
848231200Smm		if (cur_folder < prev_folder)
849231200Smm			goto invalid;
850231200Smm		if (cur_folder != prev_folder)
851231200Smm			offset32 = 0;
852231200Smm		prev_folder = cur_folder;
853231200Smm
854231200Smm		/* Make sure there are not any blanks from last file
855231200Smm		 * contents. */
856231200Smm		if (offset32 != file->offset)
857231200Smm			goto invalid;
858231200Smm		offset32 += file->uncompressed_size;
859231200Smm
860231200Smm		/* CFDATA is available for file contents. */
861231200Smm		if (file->uncompressed_size > 0 &&
862231200Smm		    hd->folder_array[cur_folder].cfdata_count == 0)
863231200Smm			goto invalid;
864231200Smm	}
865231200Smm
866231200Smm	if (hd->cabinet != 0 || hd->flags & (PREV_CABINET | NEXT_CABINET)) {
867231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
868231200Smm		    "Multivolume cabinet file is unsupported");
869231200Smm		return (ARCHIVE_WARN);
870231200Smm	}
871231200Smm	return (ARCHIVE_OK);
872231200Smminvalid:
873231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
874231200Smm	    "Invalid CAB header");
875231200Smm	return (ARCHIVE_FATAL);
876231200Smmnomem:
877231200Smm	archive_set_error(&a->archive, ENOMEM,
878231200Smm	    "Can't allocate memory for CAB data");
879231200Smm	return (ARCHIVE_FATAL);
880231200Smm}
881231200Smm
882231200Smmstatic int
883231200Smmarchive_read_format_cab_read_header(struct archive_read *a,
884231200Smm    struct archive_entry *entry)
885231200Smm{
886231200Smm	struct cab *cab;
887231200Smm	struct cfheader *hd;
888231200Smm	struct cffolder *prev_folder;
889231200Smm	struct cffile *file;
890231200Smm	struct archive_string_conv *sconv;
891231200Smm	int err = ARCHIVE_OK, r;
892231200Smm
893231200Smm	cab = (struct cab *)(a->format->data);
894231200Smm	if (cab->found_header == 0) {
895231200Smm		err = cab_read_header(a);
896231200Smm		if (err < ARCHIVE_WARN)
897231200Smm			return (err);
898231200Smm		/* We've found the header. */
899231200Smm		cab->found_header = 1;
900231200Smm	}
901231200Smm	hd = &cab->cfheader;
902231200Smm
903231200Smm	if (hd->file_index >= hd->file_count) {
904231200Smm		cab->end_of_archive = 1;
905231200Smm		return (ARCHIVE_EOF);
906231200Smm	}
907231200Smm	file = &hd->file_array[hd->file_index++];
908231200Smm
909231200Smm	cab->end_of_entry = 0;
910231200Smm	cab->end_of_entry_cleanup = 0;
911231200Smm	cab->entry_compressed_bytes_read = 0;
912231200Smm	cab->entry_uncompressed_bytes_read = 0;
913231200Smm	cab->entry_unconsumed = 0;
914231200Smm	cab->entry_cffile = file;
915231200Smm
916231200Smm	/*
917231200Smm	 * Choose a proper folder.
918231200Smm	 */
919231200Smm	prev_folder = cab->entry_cffolder;
920231200Smm	switch (file->folder) {
921231200Smm	case iFoldCONTINUED_FROM_PREV:
922231200Smm	case iFoldCONTINUED_PREV_AND_NEXT:
923231200Smm		cab->entry_cffolder = &hd->folder_array[0];
924231200Smm		break;
925231200Smm	case iFoldCONTINUED_TO_NEXT:
926231200Smm		cab->entry_cffolder = &hd->folder_array[hd->folder_count-1];
927231200Smm		break;
928231200Smm	default:
929231200Smm		cab->entry_cffolder = &hd->folder_array[file->folder];
930231200Smm		break;
931231200Smm	}
932231200Smm	/* If a cffolder of this file is changed, reset a cfdata to read
933231200Smm	 * file contents from next cfdata. */
934231200Smm	if (prev_folder != cab->entry_cffolder)
935231200Smm		cab->entry_cfdata = NULL;
936231200Smm
937231200Smm	/* If a pathname is UTF-8, prepare a string conversion object
938231200Smm	 * for UTF-8 and use it. */
939231200Smm	if (file->attr & ATTR_NAME_IS_UTF) {
940231200Smm		if (cab->sconv_utf8 == NULL) {
941231200Smm			cab->sconv_utf8 =
942231200Smm			    archive_string_conversion_from_charset(
943231200Smm				&(a->archive), "UTF-8", 1);
944231200Smm			if (cab->sconv_utf8 == NULL)
945231200Smm				return (ARCHIVE_FATAL);
946231200Smm		}
947231200Smm		sconv = cab->sconv_utf8;
948231200Smm	} else if (cab->sconv != NULL) {
949231200Smm		/* Choose the conversion specified by the option. */
950231200Smm		sconv = cab->sconv;
951231200Smm	} else {
952231200Smm		/* Choose the default conversion. */
953231200Smm		if (!cab->init_default_conversion) {
954231200Smm			cab->sconv_default =
955231200Smm			    archive_string_default_conversion_for_read(
956231200Smm			      &(a->archive));
957231200Smm			cab->init_default_conversion = 1;
958231200Smm		}
959231200Smm		sconv = cab->sconv_default;
960231200Smm	}
961231200Smm
962231200Smm	/*
963231200Smm	 * Set a default value and common data
964231200Smm	 */
965231200Smm	r = cab_convert_path_separator_1(&(file->pathname), file->attr);
966231200Smm	if (archive_entry_copy_pathname_l(entry, file->pathname.s,
967231200Smm	    archive_strlen(&(file->pathname)), sconv) != 0) {
968231200Smm		if (errno == ENOMEM) {
969231200Smm			archive_set_error(&a->archive, ENOMEM,
970231200Smm			    "Can't allocate memory for Pathname");
971231200Smm			return (ARCHIVE_FATAL);
972231200Smm		}
973231200Smm		archive_set_error(&a->archive,
974231200Smm		    ARCHIVE_ERRNO_FILE_FORMAT,
975231200Smm		    "Pathname cannot be converted "
976231200Smm		    "from %s to current locale.",
977231200Smm		    archive_string_conversion_charset_name(sconv));
978231200Smm		err = ARCHIVE_WARN;
979231200Smm	}
980231200Smm	if (r < 0) {
981231200Smm		/* Convert a path separator '\' -> '/' */
982231200Smm		cab_convert_path_separator_2(cab, entry);
983231200Smm	}
984231200Smm
985231200Smm	archive_entry_set_size(entry, file->uncompressed_size);
986231200Smm	if (file->attr & ATTR_RDONLY)
987231200Smm		archive_entry_set_mode(entry, AE_IFREG | 0555);
988231200Smm	else
989238856Smm		archive_entry_set_mode(entry, AE_IFREG | 0666);
990231200Smm	archive_entry_set_mtime(entry, file->mtime, 0);
991231200Smm
992231200Smm	cab->entry_bytes_remaining = file->uncompressed_size;
993231200Smm	cab->entry_offset = 0;
994231200Smm	/* We don't need compress data. */
995231200Smm	if (file->uncompressed_size == 0)
996231200Smm		cab->end_of_entry_cleanup = cab->end_of_entry = 1;
997231200Smm
998231200Smm	/* Set up a more descriptive format name. */
999231200Smm	sprintf(cab->format_name, "CAB %d.%d (%s)",
1000231200Smm	    hd->major, hd->minor, cab->entry_cffolder->compname);
1001231200Smm	a->archive.archive_format_name = cab->format_name;
1002231200Smm
1003231200Smm	return (err);
1004231200Smm}
1005231200Smm
1006231200Smmstatic int
1007231200Smmarchive_read_format_cab_read_data(struct archive_read *a,
1008231200Smm    const void **buff, size_t *size, int64_t *offset)
1009231200Smm{
1010231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1011231200Smm	int r;
1012231200Smm
1013231200Smm	switch (cab->entry_cffile->folder) {
1014231200Smm	case iFoldCONTINUED_FROM_PREV:
1015231200Smm	case iFoldCONTINUED_TO_NEXT:
1016231200Smm	case iFoldCONTINUED_PREV_AND_NEXT:
1017231200Smm		*buff = NULL;
1018231200Smm		*size = 0;
1019231200Smm		*offset = 0;
1020231200Smm		archive_clear_error(&a->archive);
1021231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1022231200Smm		    "Cannot restore this file split in multivolume.");
1023231200Smm		return (ARCHIVE_FAILED);
1024231200Smm	default:
1025231200Smm		break;
1026231200Smm	}
1027238856Smm	if (cab->read_data_invoked == 0) {
1028238856Smm		if (cab->bytes_skipped) {
1029238856Smm			if (cab->entry_cfdata == NULL) {
1030238856Smm				r = cab_next_cfdata(a);
1031238856Smm				if (r < 0)
1032238856Smm					return (r);
1033238856Smm			}
1034238856Smm			if (cab_consume_cfdata(a, cab->bytes_skipped) < 0)
1035238856Smm				return (ARCHIVE_FATAL);
1036238856Smm			cab->bytes_skipped = 0;
1037238856Smm		}
1038238856Smm		cab->read_data_invoked = 1;
1039238856Smm	}
1040231200Smm	if (cab->entry_unconsumed) {
1041231200Smm		/* Consume as much as the compressor actually used. */
1042238856Smm		r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
1043231200Smm		cab->entry_unconsumed = 0;
1044231200Smm		if (r < 0)
1045231200Smm			return (r);
1046231200Smm	}
1047231200Smm	if (cab->end_of_archive || cab->end_of_entry) {
1048231200Smm		if (!cab->end_of_entry_cleanup) {
1049231200Smm			/* End-of-entry cleanup done. */
1050231200Smm			cab->end_of_entry_cleanup = 1;
1051231200Smm		}
1052231200Smm		*offset = cab->entry_offset;
1053231200Smm		*size = 0;
1054231200Smm		*buff = NULL;
1055231200Smm		return (ARCHIVE_EOF);
1056231200Smm	}
1057231200Smm
1058231200Smm	return (cab_read_data(a, buff, size, offset));
1059231200Smm}
1060231200Smm
1061231200Smmstatic uint32_t
1062231200Smmcab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed)
1063231200Smm{
1064231200Smm	const unsigned char *b;
1065248616Smm	unsigned u32num;
1066231200Smm	uint32_t sum;
1067231200Smm
1068248616Smm	u32num = (unsigned)bytes / 4;
1069231200Smm	sum = seed;
1070231200Smm	b = p;
1071248616Smm	for (;u32num > 0; --u32num) {
1072231200Smm		sum ^= archive_le32dec(b);
1073231200Smm		b += 4;
1074231200Smm	}
1075231200Smm	return (sum);
1076231200Smm}
1077231200Smm
1078231200Smmstatic uint32_t
1079231200Smmcab_checksum_cfdata(const void *p, size_t bytes, uint32_t seed)
1080231200Smm{
1081231200Smm	const unsigned char *b;
1082231200Smm	uint32_t sum;
1083231200Smm	uint32_t t;
1084231200Smm
1085231200Smm	sum = cab_checksum_cfdata_4(p, bytes, seed);
1086231200Smm	b = p;
1087231200Smm	b += bytes & ~3;
1088231200Smm	t = 0;
1089231200Smm	switch (bytes & 3) {
1090231200Smm	case 3:
1091231200Smm		t |= ((uint32_t)(*b++)) << 16;
1092231200Smm		/* FALL THROUGH */
1093231200Smm	case 2:
1094231200Smm		t |= ((uint32_t)(*b++)) << 8;
1095231200Smm		/* FALL THROUGH */
1096231200Smm	case 1:
1097231200Smm		t |= *b;
1098231200Smm		/* FALL THROUGH */
1099231200Smm	default:
1100231200Smm		break;
1101231200Smm	}
1102231200Smm	sum ^= t;
1103231200Smm
1104231200Smm	return (sum);
1105231200Smm}
1106231200Smm
1107231200Smmstatic void
1108231200Smmcab_checksum_update(struct archive_read *a, size_t bytes)
1109231200Smm{
1110231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1111231200Smm	struct cfdata *cfdata = cab->entry_cfdata;
1112231200Smm	const unsigned char *p;
1113231200Smm	size_t sumbytes;
1114231200Smm
1115231200Smm	if (cfdata->sum == 0 || cfdata->sum_ptr == NULL)
1116231200Smm		return;
1117231200Smm	/*
1118231200Smm	 * Calculate the sum of this CFDATA.
1119231200Smm	 * Make sure CFDATA must be calculated in four bytes.
1120231200Smm	 */
1121231200Smm	p = cfdata->sum_ptr;
1122231200Smm	sumbytes = bytes;
1123231200Smm	if (cfdata->sum_extra_avail) {
1124231200Smm		while (cfdata->sum_extra_avail < 4 && sumbytes > 0) {
1125231200Smm			cfdata->sum_extra[
1126231200Smm			    cfdata->sum_extra_avail++] = *p++;
1127231200Smm			sumbytes--;
1128231200Smm		}
1129231200Smm		if (cfdata->sum_extra_avail == 4) {
1130231200Smm			cfdata->sum_calculated = cab_checksum_cfdata_4(
1131231200Smm			    cfdata->sum_extra, 4, cfdata->sum_calculated);
1132231200Smm			cfdata->sum_extra_avail = 0;
1133231200Smm		}
1134231200Smm	}
1135231200Smm	if (sumbytes) {
1136231200Smm		int odd = sumbytes & 3;
1137231200Smm		if (sumbytes - odd > 0)
1138231200Smm			cfdata->sum_calculated = cab_checksum_cfdata_4(
1139231200Smm			    p, sumbytes - odd, cfdata->sum_calculated);
1140231200Smm		if (odd)
1141231200Smm			memcpy(cfdata->sum_extra, p + sumbytes - odd, odd);
1142231200Smm		cfdata->sum_extra_avail = odd;
1143231200Smm	}
1144231200Smm	cfdata->sum_ptr = NULL;
1145231200Smm}
1146231200Smm
1147231200Smmstatic int
1148231200Smmcab_checksum_finish(struct archive_read *a)
1149231200Smm{
1150231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1151231200Smm	struct cfdata *cfdata = cab->entry_cfdata;
1152231200Smm	int l;
1153231200Smm
1154231200Smm	/* Do not need to compute a sum. */
1155231200Smm	if (cfdata->sum == 0)
1156231200Smm		return (ARCHIVE_OK);
1157231200Smm
1158231200Smm	/*
1159231200Smm	 * Calculate the sum of remaining CFDATA.
1160231200Smm	 */
1161231200Smm	if (cfdata->sum_extra_avail) {
1162231200Smm		cfdata->sum_calculated =
1163231200Smm		    cab_checksum_cfdata(cfdata->sum_extra,
1164231200Smm		       cfdata->sum_extra_avail, cfdata->sum_calculated);
1165231200Smm		cfdata->sum_extra_avail = 0;
1166231200Smm	}
1167231200Smm
1168231200Smm	l = 4;
1169231200Smm	if (cab->cfheader.flags & RESERVE_PRESENT)
1170231200Smm		l += cab->cfheader.cfdata;
1171231200Smm	cfdata->sum_calculated = cab_checksum_cfdata(
1172231200Smm	    cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
1173231200Smm	if (cfdata->sum_calculated != cfdata->sum) {
1174231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1175368708Smm		    "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
1176231200Smm		    cab->entry_cffolder->cfdata_index -1,
1177231200Smm		    cfdata->sum, cfdata->sum_calculated,
1178231200Smm		    cfdata->compressed_size);
1179231200Smm		return (ARCHIVE_FAILED);
1180231200Smm	}
1181231200Smm	return (ARCHIVE_OK);
1182231200Smm}
1183231200Smm
1184231200Smm/*
1185231200Smm * Read CFDATA if needed.
1186231200Smm */
1187231200Smmstatic int
1188231200Smmcab_next_cfdata(struct archive_read *a)
1189231200Smm{
1190231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1191231200Smm	struct cfdata *cfdata = cab->entry_cfdata;
1192231200Smm
1193231200Smm	/* There are remaining bytes in current CFDATA, use it first. */
1194231200Smm	if (cfdata != NULL && cfdata->uncompressed_bytes_remaining > 0)
1195231200Smm		return (ARCHIVE_OK);
1196231200Smm
1197231200Smm	if (cfdata == NULL) {
1198231200Smm		int64_t skip;
1199231200Smm
1200231200Smm		cab->entry_cffolder->cfdata_index = 0;
1201231200Smm
1202231200Smm		/* Seek read pointer to the offset of CFDATA if needed. */
1203231200Smm		skip = cab->entry_cffolder->cfdata_offset_in_cab
1204231200Smm			- cab->cab_offset;
1205231200Smm		if (skip < 0) {
1206231200Smm			int folder_index;
1207231200Smm			switch (cab->entry_cffile->folder) {
1208231200Smm			case iFoldCONTINUED_FROM_PREV:
1209231200Smm			case iFoldCONTINUED_PREV_AND_NEXT:
1210231200Smm				folder_index = 0;
1211231200Smm				break;
1212231200Smm			case iFoldCONTINUED_TO_NEXT:
1213231200Smm				folder_index = cab->cfheader.folder_count-1;
1214231200Smm				break;
1215231200Smm			default:
1216231200Smm				folder_index = cab->entry_cffile->folder;
1217231200Smm				break;
1218231200Smm			}
1219231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1220231200Smm			    "Invalid offset of CFDATA in folder(%d) %jd < %jd",
1221231200Smm			    folder_index,
1222231200Smm			    (intmax_t)cab->entry_cffolder->cfdata_offset_in_cab,
1223231200Smm			    (intmax_t)cab->cab_offset);
1224231200Smm			return (ARCHIVE_FATAL);
1225231200Smm		}
1226231200Smm		if (skip > 0) {
1227231200Smm			if (__archive_read_consume(a, skip) < 0)
1228231200Smm				return (ARCHIVE_FATAL);
1229231200Smm			cab->cab_offset =
1230231200Smm			    cab->entry_cffolder->cfdata_offset_in_cab;
1231231200Smm		}
1232231200Smm	}
1233231200Smm
1234231200Smm	/*
1235231200Smm	 * Read a CFDATA.
1236231200Smm	 */
1237231200Smm	if (cab->entry_cffolder->cfdata_index <
1238231200Smm	    cab->entry_cffolder->cfdata_count) {
1239231200Smm		const unsigned char *p;
1240231200Smm		int l;
1241231200Smm
1242231200Smm		cfdata = &(cab->entry_cffolder->cfdata);
1243231200Smm		cab->entry_cffolder->cfdata_index++;
1244231200Smm		cab->entry_cfdata = cfdata;
1245231200Smm		cfdata->sum_calculated = 0;
1246231200Smm		cfdata->sum_extra_avail = 0;
1247231200Smm		cfdata->sum_ptr = NULL;
1248231200Smm		l = 8;
1249231200Smm		if (cab->cfheader.flags & RESERVE_PRESENT)
1250231200Smm			l += cab->cfheader.cfdata;
1251231200Smm		if ((p = __archive_read_ahead(a, l, NULL)) == NULL)
1252231200Smm			return (truncated_error(a));
1253231200Smm		cfdata->sum = archive_le32dec(p + CFDATA_csum);
1254231200Smm		cfdata->compressed_size = archive_le16dec(p + CFDATA_cbData);
1255231200Smm		cfdata->compressed_bytes_remaining = cfdata->compressed_size;
1256231200Smm		cfdata->uncompressed_size =
1257231200Smm		    archive_le16dec(p + CFDATA_cbUncomp);
1258231200Smm		cfdata->uncompressed_bytes_remaining =
1259231200Smm		    cfdata->uncompressed_size;
1260231200Smm		cfdata->uncompressed_avail = 0;
1261231200Smm		cfdata->read_offset = 0;
1262231200Smm		cfdata->unconsumed = 0;
1263231200Smm
1264231200Smm		/*
1265231200Smm		 * Sanity check if data size is acceptable.
1266231200Smm		 */
1267231200Smm		if (cfdata->compressed_size == 0 ||
1268231200Smm		    cfdata->compressed_size > (0x8000+6144))
1269231200Smm			goto invalid;
1270231200Smm		if (cfdata->uncompressed_size > 0x8000)
1271231200Smm			goto invalid;
1272231200Smm		if (cfdata->uncompressed_size == 0) {
1273231200Smm			switch (cab->entry_cffile->folder) {
1274231200Smm			case iFoldCONTINUED_PREV_AND_NEXT:
1275231200Smm			case iFoldCONTINUED_TO_NEXT:
1276231200Smm				break;
1277231200Smm			case iFoldCONTINUED_FROM_PREV:
1278231200Smm			default:
1279231200Smm				goto invalid;
1280231200Smm			}
1281231200Smm		}
1282231200Smm		/* If CFDATA is not last in a folder, an uncompressed
1283231200Smm		 * size must be 0x8000(32KBi) */
1284231200Smm		if ((cab->entry_cffolder->cfdata_index <
1285231200Smm		     cab->entry_cffolder->cfdata_count) &&
1286231200Smm		       cfdata->uncompressed_size != 0x8000)
1287231200Smm			goto invalid;
1288231200Smm
1289231200Smm		/* A compressed data size and an uncompressed data size must
1290231200Smm		 * be the same in no compression mode. */
1291231200Smm		if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
1292231200Smm		    cfdata->compressed_size != cfdata->uncompressed_size)
1293231200Smm			goto invalid;
1294231200Smm
1295231200Smm		/*
1296231200Smm		 * Save CFDATA image for sum check.
1297231200Smm		 */
1298231200Smm		if (cfdata->memimage_size < (size_t)l) {
1299231200Smm			free(cfdata->memimage);
1300231200Smm			cfdata->memimage = malloc(l);
1301231200Smm			if (cfdata->memimage == NULL) {
1302231200Smm				archive_set_error(&a->archive, ENOMEM,
1303231200Smm				    "Can't allocate memory for CAB data");
1304231200Smm				return (ARCHIVE_FATAL);
1305231200Smm			}
1306231200Smm			cfdata->memimage_size = l;
1307231200Smm		}
1308231200Smm		memcpy(cfdata->memimage, p, l);
1309231200Smm
1310231200Smm		/* Consume bytes as much as we used. */
1311231200Smm		__archive_read_consume(a, l);
1312231200Smm		cab->cab_offset += l;
1313231200Smm	} else if (cab->entry_cffolder->cfdata_count > 0) {
1314231200Smm		/* Run out of all CFDATA in a folder. */
1315231200Smm		cfdata->compressed_size = 0;
1316231200Smm		cfdata->uncompressed_size = 0;
1317231200Smm		cfdata->compressed_bytes_remaining = 0;
1318231200Smm		cfdata->uncompressed_bytes_remaining = 0;
1319231200Smm	} else {
1320231200Smm		/* Current folder does not have any CFDATA. */
1321231200Smm		cfdata = &(cab->entry_cffolder->cfdata);
1322231200Smm		cab->entry_cfdata = cfdata;
1323231200Smm		memset(cfdata, 0, sizeof(*cfdata));
1324231200Smm	}
1325231200Smm	return (ARCHIVE_OK);
1326231200Smminvalid:
1327231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1328231200Smm	    "Invalid CFDATA");
1329231200Smm	return (ARCHIVE_FATAL);
1330231200Smm}
1331231200Smm
1332231200Smm/*
1333231200Smm * Read ahead CFDATA.
1334231200Smm */
1335231200Smmstatic const void *
1336231200Smmcab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail)
1337231200Smm{
1338231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1339231200Smm	int err;
1340231200Smm
1341231200Smm	err = cab_next_cfdata(a);
1342231200Smm	if (err < ARCHIVE_OK) {
1343231200Smm		*avail = err;
1344231200Smm		return (NULL);
1345231200Smm	}
1346231200Smm
1347231200Smm	switch (cab->entry_cffolder->comptype) {
1348231200Smm	case COMPTYPE_NONE:
1349231200Smm		return (cab_read_ahead_cfdata_none(a, avail));
1350231200Smm	case COMPTYPE_MSZIP:
1351231200Smm		return (cab_read_ahead_cfdata_deflate(a, avail));
1352231200Smm	case COMPTYPE_LZX:
1353231200Smm		return (cab_read_ahead_cfdata_lzx(a, avail));
1354231200Smm	default: /* Unsupported compression. */
1355231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1356231200Smm		    "Unsupported CAB compression : %s",
1357231200Smm		    cab->entry_cffolder->compname);
1358231200Smm		*avail = ARCHIVE_FAILED;
1359231200Smm		return (NULL);
1360231200Smm	}
1361231200Smm}
1362231200Smm
1363231200Smm/*
1364231200Smm * Read ahead CFDATA as uncompressed data.
1365231200Smm */
1366231200Smmstatic const void *
1367231200Smmcab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
1368231200Smm{
1369231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1370231200Smm	struct cfdata *cfdata;
1371231200Smm	const void *d;
1372231200Smm
1373231200Smm	cfdata = cab->entry_cfdata;
1374231200Smm
1375238856Smm	/*
1376238856Smm	 * Note: '1' here is a performance optimization.
1377238856Smm	 * Recall that the decompression layer returns a count of
1378238856Smm	 * available bytes; asking for more than that forces the
1379238856Smm	 * decompressor to combine reads by copying data.
1380238856Smm	 */
1381238856Smm	d = __archive_read_ahead(a, 1, avail);
1382238856Smm	if (*avail <= 0) {
1383238856Smm		*avail = truncated_error(a);
1384238856Smm		return (NULL);
1385238856Smm	}
1386238856Smm	if (*avail > cfdata->uncompressed_bytes_remaining)
1387238856Smm		*avail = cfdata->uncompressed_bytes_remaining;
1388238856Smm	cfdata->uncompressed_avail = cfdata->uncompressed_size;
1389238856Smm	cfdata->unconsumed = *avail;
1390238856Smm	cfdata->sum_ptr = d;
1391231200Smm	return (d);
1392231200Smm}
1393231200Smm
1394231200Smm/*
1395231200Smm * Read ahead CFDATA as deflate data.
1396231200Smm */
1397231200Smm#ifdef HAVE_ZLIB_H
1398231200Smmstatic const void *
1399231200Smmcab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
1400231200Smm{
1401231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1402231200Smm	struct cfdata *cfdata;
1403231200Smm	const void *d;
1404231200Smm	int r, mszip;
1405231200Smm	uint16_t uavail;
1406231200Smm	char eod = 0;
1407231200Smm
1408231200Smm	cfdata = cab->entry_cfdata;
1409231200Smm	/* If the buffer hasn't been allocated, allocate it now. */
1410231200Smm	if (cab->uncompressed_buffer == NULL) {
1411231200Smm		cab->uncompressed_buffer_size = 0x8000;
1412231200Smm		cab->uncompressed_buffer
1413231200Smm		    = (unsigned char *)malloc(cab->uncompressed_buffer_size);
1414231200Smm		if (cab->uncompressed_buffer == NULL) {
1415231200Smm			archive_set_error(&a->archive, ENOMEM,
1416231200Smm			    "No memory for CAB reader");
1417231200Smm			*avail = ARCHIVE_FATAL;
1418231200Smm			return (NULL);
1419231200Smm		}
1420231200Smm	}
1421231200Smm
1422231200Smm	uavail = cfdata->uncompressed_avail;
1423231200Smm	if (uavail == cfdata->uncompressed_size) {
1424231200Smm		d = cab->uncompressed_buffer + cfdata->read_offset;
1425231200Smm		*avail = uavail - cfdata->read_offset;
1426231200Smm		return (d);
1427231200Smm	}
1428231200Smm
1429231200Smm	if (!cab->entry_cffolder->decompress_init) {
1430231200Smm		cab->stream.next_in = NULL;
1431231200Smm		cab->stream.avail_in = 0;
1432231200Smm		cab->stream.total_in = 0;
1433231200Smm		cab->stream.next_out = NULL;
1434231200Smm		cab->stream.avail_out = 0;
1435231200Smm		cab->stream.total_out = 0;
1436231200Smm		if (cab->stream_valid)
1437231200Smm			r = inflateReset(&cab->stream);
1438231200Smm		else
1439231200Smm			r = inflateInit2(&cab->stream,
1440231200Smm			    -15 /* Don't check for zlib header */);
1441231200Smm		if (r != Z_OK) {
1442231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1443231200Smm			    "Can't initialize deflate decompression.");
1444231200Smm			*avail = ARCHIVE_FATAL;
1445231200Smm			return (NULL);
1446231200Smm		}
1447231200Smm		/* Stream structure has been set up. */
1448231200Smm		cab->stream_valid = 1;
1449231200Smm		/* We've initialized decompression for this stream. */
1450231200Smm		cab->entry_cffolder->decompress_init = 1;
1451231200Smm	}
1452231200Smm
1453231200Smm	if (cfdata->compressed_bytes_remaining == cfdata->compressed_size)
1454231200Smm		mszip = 2;
1455231200Smm	else
1456231200Smm		mszip = 0;
1457231200Smm	eod = 0;
1458231200Smm	cab->stream.total_out = uavail;
1459231200Smm	/*
1460231200Smm	 * We always uncompress all data in current CFDATA.
1461231200Smm	 */
1462231200Smm	while (!eod && cab->stream.total_out < cfdata->uncompressed_size) {
1463231200Smm		ssize_t bytes_avail;
1464231200Smm
1465231200Smm		cab->stream.next_out =
1466231200Smm		    cab->uncompressed_buffer + cab->stream.total_out;
1467231200Smm		cab->stream.avail_out =
1468231200Smm		    cfdata->uncompressed_size - cab->stream.total_out;
1469231200Smm
1470231200Smm		d = __archive_read_ahead(a, 1, &bytes_avail);
1471231200Smm		if (bytes_avail <= 0) {
1472231200Smm			*avail = truncated_error(a);
1473231200Smm			return (NULL);
1474231200Smm		}
1475231200Smm		if (bytes_avail > cfdata->compressed_bytes_remaining)
1476231200Smm			bytes_avail = cfdata->compressed_bytes_remaining;
1477231200Smm		/*
1478231200Smm		 * A bug in zlib.h: stream.next_in should be marked 'const'
1479231200Smm		 * but isn't (the library never alters data through the
1480231200Smm		 * next_in pointer, only reads it).  The result: this ugly
1481231200Smm		 * cast to remove 'const'.
1482231200Smm		 */
1483231200Smm		cab->stream.next_in = (Bytef *)(uintptr_t)d;
1484248616Smm		cab->stream.avail_in = (uInt)bytes_avail;
1485231200Smm		cab->stream.total_in = 0;
1486231200Smm
1487231200Smm		/* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
1488231200Smm		if (mszip > 0) {
1489313571Smm			if (bytes_avail <= 0)
1490313571Smm				goto nomszip;
1491231200Smm			if (bytes_avail <= mszip) {
1492231200Smm				if (mszip == 2) {
1493231200Smm					if (cab->stream.next_in[0] != 0x43)
1494231200Smm						goto nomszip;
1495231200Smm					if (bytes_avail > 1 &&
1496231200Smm					    cab->stream.next_in[1] != 0x4b)
1497231200Smm						goto nomszip;
1498231200Smm				} else if (cab->stream.next_in[0] != 0x4b)
1499231200Smm					goto nomszip;
1500231200Smm				cfdata->unconsumed = bytes_avail;
1501231200Smm				cfdata->sum_ptr = d;
1502231200Smm				if (cab_minimum_consume_cfdata(
1503231200Smm				    a, cfdata->unconsumed) < 0) {
1504231200Smm					*avail = ARCHIVE_FATAL;
1505231200Smm					return (NULL);
1506231200Smm				}
1507248616Smm				mszip -= (int)bytes_avail;
1508231200Smm				continue;
1509231200Smm			}
1510231200Smm			if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
1511231200Smm				goto nomszip;
1512348608Smm			else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
1513348608Smm			    cab->stream.next_in[1] != 0x4b))
1514231200Smm				goto nomszip;
1515231200Smm			cab->stream.next_in += mszip;
1516231200Smm			cab->stream.avail_in -= mszip;
1517231200Smm			cab->stream.total_in += mszip;
1518231200Smm			mszip = 0;
1519231200Smm		}
1520231200Smm
1521231200Smm		r = inflate(&cab->stream, 0);
1522231200Smm		switch (r) {
1523231200Smm		case Z_OK:
1524231200Smm			break;
1525231200Smm		case Z_STREAM_END:
1526231200Smm			eod = 1;
1527231200Smm			break;
1528231200Smm		default:
1529231200Smm			goto zlibfailed;
1530231200Smm		}
1531231200Smm		cfdata->unconsumed = cab->stream.total_in;
1532231200Smm		cfdata->sum_ptr = d;
1533231200Smm		if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
1534231200Smm			*avail = ARCHIVE_FATAL;
1535231200Smm			return (NULL);
1536231200Smm		}
1537231200Smm	}
1538238856Smm	uavail = (uint16_t)cab->stream.total_out;
1539231200Smm
1540231200Smm	if (uavail < cfdata->uncompressed_size) {
1541231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1542231200Smm		    "Invalid uncompressed size (%d < %d)",
1543231200Smm		    uavail, cfdata->uncompressed_size);
1544231200Smm		*avail = ARCHIVE_FATAL;
1545231200Smm		return (NULL);
1546231200Smm	}
1547231200Smm
1548231200Smm	/*
1549231200Smm	 * Note: I suspect there is a bug in makecab.exe because, in rare
1550231200Smm	 * case, compressed bytes are still remaining regardless we have
1551311042Smm	 * gotten all uncompressed bytes, which size is recorded in CFDATA,
1552231200Smm	 * as much as we need, and we have to use the garbage so as to
1553231200Smm	 * correctly compute the sum of CFDATA accordingly.
1554231200Smm	 */
1555231200Smm	if (cfdata->compressed_bytes_remaining > 0) {
1556231200Smm		ssize_t bytes_avail;
1557231200Smm
1558231200Smm		d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
1559231200Smm		    &bytes_avail);
1560231200Smm		if (bytes_avail <= 0) {
1561231200Smm			*avail = truncated_error(a);
1562231200Smm			return (NULL);
1563231200Smm		}
1564231200Smm		cfdata->unconsumed = cfdata->compressed_bytes_remaining;
1565231200Smm		cfdata->sum_ptr = d;
1566231200Smm		if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
1567231200Smm			*avail = ARCHIVE_FATAL;
1568231200Smm			return (NULL);
1569231200Smm		}
1570231200Smm	}
1571231200Smm
1572231200Smm	/*
1573231200Smm	 * Set dictionary data for decompressing of next CFDATA, which
1574231200Smm	 * in the same folder. This is why we always do decompress CFDATA
1575231200Smm	 * even if beginning CFDATA or some of CFDATA are not used in
1576231200Smm	 * skipping file data.
1577231200Smm	 */
1578231200Smm	if (cab->entry_cffolder->cfdata_index <
1579231200Smm	    cab->entry_cffolder->cfdata_count) {
1580231200Smm		r = inflateReset(&cab->stream);
1581231200Smm		if (r != Z_OK)
1582231200Smm			goto zlibfailed;
1583231200Smm		r = inflateSetDictionary(&cab->stream,
1584231200Smm		    cab->uncompressed_buffer, cfdata->uncompressed_size);
1585231200Smm		if (r != Z_OK)
1586231200Smm			goto zlibfailed;
1587231200Smm	}
1588231200Smm
1589231200Smm	d = cab->uncompressed_buffer + cfdata->read_offset;
1590231200Smm	*avail = uavail - cfdata->read_offset;
1591231200Smm	cfdata->uncompressed_avail = uavail;
1592231200Smm
1593231200Smm	return (d);
1594231200Smm
1595231200Smmzlibfailed:
1596231200Smm	switch (r) {
1597231200Smm	case Z_MEM_ERROR:
1598231200Smm		archive_set_error(&a->archive, ENOMEM,
1599231200Smm		    "Out of memory for deflate decompression");
1600231200Smm		break;
1601231200Smm	default:
1602231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1603231200Smm		    "Deflate decompression failed (%d)", r);
1604231200Smm		break;
1605231200Smm	}
1606231200Smm	*avail = ARCHIVE_FATAL;
1607231200Smm	return (NULL);
1608231200Smmnomszip:
1609231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1610231200Smm	    "CFDATA incorrect(no MSZIP signature)");
1611231200Smm	*avail = ARCHIVE_FATAL;
1612231200Smm	return (NULL);
1613231200Smm}
1614231200Smm
1615231200Smm#else /* HAVE_ZLIB_H */
1616231200Smm
1617231200Smmstatic const void *
1618231200Smmcab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
1619231200Smm{
1620231200Smm	*avail = ARCHIVE_FATAL;
1621231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1622231200Smm	    "libarchive compiled without deflate support (no libz)");
1623231200Smm	return (NULL);
1624231200Smm}
1625231200Smm
1626231200Smm#endif /* HAVE_ZLIB_H */
1627231200Smm
1628231200Smmstatic const void *
1629231200Smmcab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
1630231200Smm{
1631231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1632231200Smm	struct cfdata *cfdata;
1633231200Smm	const void *d;
1634231200Smm	int r;
1635231200Smm	uint16_t uavail;
1636231200Smm
1637231200Smm	cfdata = cab->entry_cfdata;
1638231200Smm	/* If the buffer hasn't been allocated, allocate it now. */
1639231200Smm	if (cab->uncompressed_buffer == NULL) {
1640231200Smm		cab->uncompressed_buffer_size = 0x8000;
1641231200Smm		cab->uncompressed_buffer
1642231200Smm		    = (unsigned char *)malloc(cab->uncompressed_buffer_size);
1643231200Smm		if (cab->uncompressed_buffer == NULL) {
1644231200Smm			archive_set_error(&a->archive, ENOMEM,
1645231200Smm			    "No memory for CAB reader");
1646231200Smm			*avail = ARCHIVE_FATAL;
1647231200Smm			return (NULL);
1648231200Smm		}
1649231200Smm	}
1650231200Smm
1651231200Smm	uavail = cfdata->uncompressed_avail;
1652231200Smm	if (uavail == cfdata->uncompressed_size) {
1653231200Smm		d = cab->uncompressed_buffer + cfdata->read_offset;
1654231200Smm		*avail = uavail - cfdata->read_offset;
1655231200Smm		return (d);
1656231200Smm	}
1657231200Smm
1658231200Smm	if (!cab->entry_cffolder->decompress_init) {
1659231200Smm		r = lzx_decode_init(&cab->xstrm,
1660231200Smm		    cab->entry_cffolder->compdata);
1661231200Smm		if (r != ARCHIVE_OK) {
1662231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1663231200Smm			    "Can't initialize LZX decompression.");
1664231200Smm			*avail = ARCHIVE_FATAL;
1665231200Smm			return (NULL);
1666231200Smm		}
1667231200Smm		/* We've initialized decompression for this stream. */
1668231200Smm		cab->entry_cffolder->decompress_init = 1;
1669231200Smm	}
1670231200Smm
1671231200Smm	/* Clean up remaining bits of previous CFDATA. */
1672231200Smm	lzx_cleanup_bitstream(&cab->xstrm);
1673231200Smm	cab->xstrm.total_out = uavail;
1674231200Smm	while (cab->xstrm.total_out < cfdata->uncompressed_size) {
1675231200Smm		ssize_t bytes_avail;
1676231200Smm
1677231200Smm		cab->xstrm.next_out =
1678231200Smm		    cab->uncompressed_buffer + cab->xstrm.total_out;
1679231200Smm		cab->xstrm.avail_out =
1680231200Smm		    cfdata->uncompressed_size - cab->xstrm.total_out;
1681231200Smm
1682231200Smm		d = __archive_read_ahead(a, 1, &bytes_avail);
1683231200Smm		if (bytes_avail <= 0) {
1684231200Smm			archive_set_error(&a->archive,
1685231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT,
1686231200Smm			    "Truncated CAB file data");
1687231200Smm			*avail = ARCHIVE_FATAL;
1688231200Smm			return (NULL);
1689231200Smm		}
1690231200Smm		if (bytes_avail > cfdata->compressed_bytes_remaining)
1691231200Smm			bytes_avail = cfdata->compressed_bytes_remaining;
1692231200Smm
1693231200Smm		cab->xstrm.next_in = d;
1694231200Smm		cab->xstrm.avail_in = bytes_avail;
1695231200Smm		cab->xstrm.total_in = 0;
1696231200Smm		r = lzx_decode(&cab->xstrm,
1697231200Smm		    cfdata->compressed_bytes_remaining == bytes_avail);
1698231200Smm		switch (r) {
1699231200Smm		case ARCHIVE_OK:
1700231200Smm		case ARCHIVE_EOF:
1701231200Smm			break;
1702231200Smm		default:
1703231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1704231200Smm			    "LZX decompression failed (%d)", r);
1705231200Smm			*avail = ARCHIVE_FATAL;
1706231200Smm			return (NULL);
1707231200Smm		}
1708231200Smm		cfdata->unconsumed = cab->xstrm.total_in;
1709231200Smm		cfdata->sum_ptr = d;
1710231200Smm		if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
1711231200Smm			*avail = ARCHIVE_FATAL;
1712231200Smm			return (NULL);
1713231200Smm		}
1714231200Smm	}
1715231200Smm
1716238856Smm	uavail = (uint16_t)cab->xstrm.total_out;
1717231200Smm	/*
1718231200Smm	 * Make sure a read pointer advances to next CFDATA.
1719231200Smm	 */
1720231200Smm	if (cfdata->compressed_bytes_remaining > 0) {
1721231200Smm		ssize_t bytes_avail;
1722231200Smm
1723231200Smm		d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
1724231200Smm		    &bytes_avail);
1725231200Smm		if (bytes_avail <= 0) {
1726231200Smm			*avail = truncated_error(a);
1727231200Smm			return (NULL);
1728231200Smm		}
1729231200Smm		cfdata->unconsumed = cfdata->compressed_bytes_remaining;
1730231200Smm		cfdata->sum_ptr = d;
1731231200Smm		if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
1732231200Smm			*avail = ARCHIVE_FATAL;
1733231200Smm			return (NULL);
1734231200Smm		}
1735231200Smm	}
1736231200Smm
1737231200Smm	/*
1738311042Smm	 * Translation reversal of x86 processor CALL byte sequence(E8).
1739231200Smm	 */
1740231200Smm	lzx_translation(&cab->xstrm, cab->uncompressed_buffer,
1741231200Smm	    cfdata->uncompressed_size,
1742231200Smm	    (cab->entry_cffolder->cfdata_index-1) * 0x8000);
1743231200Smm
1744231200Smm	d = cab->uncompressed_buffer + cfdata->read_offset;
1745231200Smm	*avail = uavail - cfdata->read_offset;
1746231200Smm	cfdata->uncompressed_avail = uavail;
1747231200Smm
1748231200Smm	return (d);
1749231200Smm}
1750231200Smm
1751231200Smm/*
1752231200Smm * Consume CFDATA.
1753231200Smm * We always decompress CFDATA to consume CFDATA as much as we need
1754231200Smm * in uncompressed bytes because all CFDATA in a folder are related
1755231200Smm * so we do not skip any CFDATA without decompressing.
1756231200Smm * Note: If the folder of a CFFILE is iFoldCONTINUED_PREV_AND_NEXT or
1757231200Smm * iFoldCONTINUED_FROM_PREV, we won't decompress because a CFDATA for
1758231200Smm * the CFFILE is remaining bytes of previous Multivolume CAB file.
1759231200Smm */
1760231200Smmstatic int64_t
1761231200Smmcab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
1762231200Smm{
1763231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1764231200Smm	struct cfdata *cfdata;
1765231200Smm	int64_t cbytes, rbytes;
1766231200Smm	int err;
1767231200Smm
1768231200Smm	rbytes = cab_minimum_consume_cfdata(a, consumed_bytes);
1769231200Smm	if (rbytes < 0)
1770231200Smm		return (ARCHIVE_FATAL);
1771231200Smm
1772231200Smm	cfdata = cab->entry_cfdata;
1773231200Smm	while (rbytes > 0) {
1774231200Smm		ssize_t avail;
1775231200Smm
1776231200Smm		if (cfdata->compressed_size == 0) {
1777231200Smm			archive_set_error(&a->archive,
1778231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT,
1779231200Smm			    "Invalid CFDATA");
1780231200Smm			return (ARCHIVE_FATAL);
1781231200Smm		}
1782231200Smm		cbytes = cfdata->uncompressed_bytes_remaining;
1783231200Smm		if (cbytes > rbytes)
1784231200Smm			cbytes = rbytes;
1785231200Smm		rbytes -= cbytes;
1786231200Smm
1787231200Smm		if (cfdata->uncompressed_avail == 0 &&
1788238856Smm		   (cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT ||
1789238856Smm		    cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
1790231200Smm			/* We have not read any data yet. */
1791231200Smm			if (cbytes == cfdata->uncompressed_bytes_remaining) {
1792231200Smm				/* Skip whole current CFDATA. */
1793231200Smm				__archive_read_consume(a,
1794231200Smm				    cfdata->compressed_size);
1795231200Smm				cab->cab_offset += cfdata->compressed_size;
1796231200Smm				cfdata->compressed_bytes_remaining = 0;
1797231200Smm				cfdata->uncompressed_bytes_remaining = 0;
1798231200Smm				err = cab_next_cfdata(a);
1799231200Smm				if (err < 0)
1800231200Smm					return (err);
1801231200Smm				cfdata = cab->entry_cfdata;
1802231200Smm				if (cfdata->uncompressed_size == 0) {
1803231200Smm					switch (cab->entry_cffile->folder) {
1804231200Smm					case iFoldCONTINUED_PREV_AND_NEXT:
1805231200Smm					case iFoldCONTINUED_TO_NEXT:
1806231200Smm					case iFoldCONTINUED_FROM_PREV:
1807231200Smm						rbytes = 0;
1808231200Smm						break;
1809231200Smm					default:
1810231200Smm						break;
1811231200Smm					}
1812231200Smm				}
1813231200Smm				continue;
1814231200Smm			}
1815238856Smm			cfdata->read_offset += (uint16_t)cbytes;
1816238856Smm			cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
1817231200Smm			break;
1818231200Smm		} else if (cbytes == 0) {
1819231200Smm			err = cab_next_cfdata(a);
1820231200Smm			if (err < 0)
1821231200Smm				return (err);
1822231200Smm			cfdata = cab->entry_cfdata;
1823231200Smm			if (cfdata->uncompressed_size == 0) {
1824231200Smm				switch (cab->entry_cffile->folder) {
1825231200Smm				case iFoldCONTINUED_PREV_AND_NEXT:
1826231200Smm				case iFoldCONTINUED_TO_NEXT:
1827231200Smm				case iFoldCONTINUED_FROM_PREV:
1828231200Smm					return (ARCHIVE_FATAL);
1829231200Smm				default:
1830231200Smm					break;
1831231200Smm				}
1832231200Smm			}
1833231200Smm			continue;
1834231200Smm		}
1835231200Smm		while (cbytes > 0) {
1836231200Smm			(void)cab_read_ahead_cfdata(a, &avail);
1837231200Smm			if (avail <= 0)
1838231200Smm				return (ARCHIVE_FATAL);
1839231200Smm			if (avail > cbytes)
1840238856Smm				avail = (ssize_t)cbytes;
1841231200Smm			if (cab_minimum_consume_cfdata(a, avail) < 0)
1842231200Smm				return (ARCHIVE_FATAL);
1843231200Smm			cbytes -= avail;
1844231200Smm		}
1845231200Smm	}
1846231200Smm	return (consumed_bytes);
1847231200Smm}
1848231200Smm
1849231200Smm/*
1850231200Smm * Consume CFDATA as much as we have already gotten and
1851231200Smm * compute the sum of CFDATA.
1852231200Smm */
1853231200Smmstatic int64_t
1854231200Smmcab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
1855231200Smm{
1856231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1857231200Smm	struct cfdata *cfdata;
1858231200Smm	int64_t cbytes, rbytes;
1859231200Smm	int err;
1860231200Smm
1861231200Smm	cfdata = cab->entry_cfdata;
1862231200Smm	rbytes = consumed_bytes;
1863231200Smm	if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
1864231200Smm		if (consumed_bytes < cfdata->unconsumed)
1865231200Smm			cbytes = consumed_bytes;
1866231200Smm		else
1867231200Smm			cbytes = cfdata->unconsumed;
1868231200Smm		rbytes -= cbytes;
1869238856Smm		cfdata->read_offset += (uint16_t)cbytes;
1870238856Smm		cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
1871231200Smm		cfdata->unconsumed -= cbytes;
1872231200Smm	} else {
1873231200Smm		cbytes = cfdata->uncompressed_avail - cfdata->read_offset;
1874231200Smm		if (cbytes > 0) {
1875231200Smm			if (consumed_bytes < cbytes)
1876231200Smm				cbytes = consumed_bytes;
1877231200Smm			rbytes -= cbytes;
1878238856Smm			cfdata->read_offset += (uint16_t)cbytes;
1879238856Smm			cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
1880231200Smm		}
1881231200Smm
1882231200Smm		if (cfdata->unconsumed) {
1883231200Smm			cbytes = cfdata->unconsumed;
1884231200Smm			cfdata->unconsumed = 0;
1885231200Smm		} else
1886231200Smm			cbytes = 0;
1887231200Smm	}
1888231200Smm	if (cbytes) {
1889231200Smm		/* Compute the sum. */
1890238856Smm		cab_checksum_update(a, (size_t)cbytes);
1891231200Smm
1892231200Smm		/* Consume as much as the compressor actually used. */
1893231200Smm		__archive_read_consume(a, cbytes);
1894231200Smm		cab->cab_offset += cbytes;
1895238856Smm		cfdata->compressed_bytes_remaining -= (uint16_t)cbytes;
1896231200Smm		if (cfdata->compressed_bytes_remaining == 0) {
1897231200Smm			err = cab_checksum_finish(a);
1898231200Smm			if (err < 0)
1899231200Smm				return (err);
1900231200Smm		}
1901231200Smm	}
1902231200Smm	return (rbytes);
1903231200Smm}
1904231200Smm
1905231200Smm/*
1906231200Smm * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
1907231200Smm * cab->end_of_entry if it consumes all of the data.
1908231200Smm */
1909231200Smmstatic int
1910231200Smmcab_read_data(struct archive_read *a, const void **buff,
1911231200Smm    size_t *size, int64_t *offset)
1912231200Smm{
1913231200Smm	struct cab *cab = (struct cab *)(a->format->data);
1914231200Smm	ssize_t bytes_avail;
1915231200Smm
1916231200Smm	if (cab->entry_bytes_remaining == 0) {
1917231200Smm		*buff = NULL;
1918231200Smm		*size = 0;
1919231200Smm		*offset = cab->entry_offset;
1920231200Smm		cab->end_of_entry = 1;
1921231200Smm		return (ARCHIVE_OK);
1922231200Smm	}
1923231200Smm
1924231200Smm	*buff = cab_read_ahead_cfdata(a, &bytes_avail);
1925231200Smm	if (bytes_avail <= 0) {
1926231200Smm		*buff = NULL;
1927231200Smm		*size = 0;
1928231200Smm		*offset = 0;
1929231200Smm		if (bytes_avail == 0 &&
1930231200Smm		    cab->entry_cfdata->uncompressed_size == 0) {
1931231200Smm			/* All of CFDATA in a folder has been handled. */
1932231200Smm			archive_set_error(&a->archive,
1933231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA");
1934231200Smm			return (ARCHIVE_FATAL);
1935231200Smm		} else
1936248616Smm			return ((int)bytes_avail);
1937231200Smm	}
1938231200Smm	if (bytes_avail > cab->entry_bytes_remaining)
1939238856Smm		bytes_avail = (ssize_t)cab->entry_bytes_remaining;
1940231200Smm
1941231200Smm	*size = bytes_avail;
1942231200Smm	*offset = cab->entry_offset;
1943231200Smm	cab->entry_offset += bytes_avail;
1944231200Smm	cab->entry_bytes_remaining -= bytes_avail;
1945231200Smm	if (cab->entry_bytes_remaining == 0)
1946231200Smm		cab->end_of_entry = 1;
1947231200Smm	cab->entry_unconsumed = bytes_avail;
1948238856Smm	if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
1949238856Smm		/* Don't consume more than current entry used. */
1950238856Smm		if (cab->entry_cfdata->unconsumed > cab->entry_unconsumed)
1951238856Smm			cab->entry_cfdata->unconsumed = cab->entry_unconsumed;
1952238856Smm	}
1953231200Smm	return (ARCHIVE_OK);
1954231200Smm}
1955231200Smm
1956231200Smmstatic int
1957231200Smmarchive_read_format_cab_read_data_skip(struct archive_read *a)
1958231200Smm{
1959231200Smm	struct cab *cab;
1960231200Smm	int64_t bytes_skipped;
1961231200Smm	int r;
1962231200Smm
1963231200Smm	cab = (struct cab *)(a->format->data);
1964231200Smm
1965231200Smm	if (cab->end_of_archive)
1966231200Smm		return (ARCHIVE_EOF);
1967231200Smm
1968238856Smm	if (!cab->read_data_invoked) {
1969238856Smm		cab->bytes_skipped += cab->entry_bytes_remaining;
1970238856Smm		cab->entry_bytes_remaining = 0;
1971238856Smm		/* This entry is finished and done. */
1972238856Smm		cab->end_of_entry_cleanup = cab->end_of_entry = 1;
1973238856Smm		return (ARCHIVE_OK);
1974238856Smm	}
1975238856Smm
1976231200Smm	if (cab->entry_unconsumed) {
1977231200Smm		/* Consume as much as the compressor actually used. */
1978238856Smm		r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
1979231200Smm		cab->entry_unconsumed = 0;
1980231200Smm		if (r < 0)
1981231200Smm			return (r);
1982231200Smm	} else if (cab->entry_cfdata == NULL) {
1983231200Smm		r = cab_next_cfdata(a);
1984231200Smm		if (r < 0)
1985231200Smm			return (r);
1986231200Smm	}
1987231200Smm
1988231200Smm	/* if we've already read to end of data, we're done. */
1989231200Smm	if (cab->end_of_entry_cleanup)
1990231200Smm		return (ARCHIVE_OK);
1991231200Smm
1992231200Smm	/*
1993231200Smm	 * If the length is at the beginning, we can skip the
1994231200Smm	 * compressed data much more quickly.
1995231200Smm	 */
1996231200Smm	bytes_skipped = cab_consume_cfdata(a, cab->entry_bytes_remaining);
1997231200Smm	if (bytes_skipped < 0)
1998231200Smm		return (ARCHIVE_FATAL);
1999231200Smm
2000238856Smm	/* If the compression type is none(uncompressed), we've already
2001238856Smm	 * consumed data as much as the current entry size. */
2002248616Smm	if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
2003248616Smm	    cab->entry_cfdata != NULL)
2004238856Smm		cab->entry_cfdata->unconsumed = 0;
2005238856Smm
2006231200Smm	/* This entry is finished and done. */
2007231200Smm	cab->end_of_entry_cleanup = cab->end_of_entry = 1;
2008231200Smm	return (ARCHIVE_OK);
2009231200Smm}
2010231200Smm
2011231200Smmstatic int
2012231200Smmarchive_read_format_cab_cleanup(struct archive_read *a)
2013231200Smm{
2014231200Smm	struct cab *cab = (struct cab *)(a->format->data);
2015231200Smm	struct cfheader *hd = &cab->cfheader;
2016231200Smm	int i;
2017231200Smm
2018231200Smm	if (hd->folder_array != NULL) {
2019231200Smm		for (i = 0; i < hd->folder_count; i++)
2020231200Smm			free(hd->folder_array[i].cfdata.memimage);
2021231200Smm		free(hd->folder_array);
2022231200Smm	}
2023231200Smm	if (hd->file_array != NULL) {
2024231200Smm		for (i = 0; i < cab->cfheader.file_count; i++)
2025231200Smm			archive_string_free(&(hd->file_array[i].pathname));
2026231200Smm		free(hd->file_array);
2027231200Smm	}
2028231200Smm#ifdef HAVE_ZLIB_H
2029231200Smm	if (cab->stream_valid)
2030231200Smm		inflateEnd(&cab->stream);
2031231200Smm#endif
2032231200Smm	lzx_decode_free(&cab->xstrm);
2033231200Smm	archive_wstring_free(&cab->ws);
2034231200Smm	free(cab->uncompressed_buffer);
2035231200Smm	free(cab);
2036231200Smm	(a->format->data) = NULL;
2037231200Smm	return (ARCHIVE_OK);
2038231200Smm}
2039231200Smm
2040231200Smm/* Convert an MSDOS-style date/time into Unix-style time. */
2041231200Smmstatic time_t
2042231200Smmcab_dos_time(const unsigned char *p)
2043231200Smm{
2044231200Smm	int msTime, msDate;
2045231200Smm	struct tm ts;
2046231200Smm
2047231200Smm	msDate = archive_le16dec(p);
2048231200Smm	msTime = archive_le16dec(p+2);
2049231200Smm
2050231200Smm	memset(&ts, 0, sizeof(ts));
2051231200Smm	ts.tm_year = ((msDate >> 9) & 0x7f) + 80;   /* Years since 1900. */
2052231200Smm	ts.tm_mon = ((msDate >> 5) & 0x0f) - 1;     /* Month number.     */
2053231200Smm	ts.tm_mday = msDate & 0x1f;		    /* Day of month.     */
2054231200Smm	ts.tm_hour = (msTime >> 11) & 0x1f;
2055231200Smm	ts.tm_min = (msTime >> 5) & 0x3f;
2056231200Smm	ts.tm_sec = (msTime << 1) & 0x3e;
2057231200Smm	ts.tm_isdst = -1;
2058231200Smm	return (mktime(&ts));
2059231200Smm}
2060231200Smm
2061231200Smm/*****************************************************************
2062231200Smm *
2063231200Smm * LZX decompression code.
2064231200Smm *
2065231200Smm *****************************************************************/
2066231200Smm
2067231200Smm/*
2068231200Smm * Initialize LZX decoder.
2069231200Smm *
2070231200Smm * Returns ARCHIVE_OK if initialization was successful.
2071231200Smm * Returns ARCHIVE_FAILED if w_bits has unsupported value.
2072231200Smm * Returns ARCHIVE_FATAL if initialization failed; memory allocation
2073231200Smm * error occurred.
2074231200Smm */
2075231200Smmstatic int
2076231200Smmlzx_decode_init(struct lzx_stream *strm, int w_bits)
2077231200Smm{
2078231200Smm	struct lzx_dec *ds;
2079231200Smm	int slot, w_size, w_slot;
2080231200Smm	int base, footer;
2081232153Smm	int base_inc[18];
2082231200Smm
2083231200Smm	if (strm->ds == NULL) {
2084231200Smm		strm->ds = calloc(1, sizeof(*strm->ds));
2085231200Smm		if (strm->ds == NULL)
2086231200Smm			return (ARCHIVE_FATAL);
2087231200Smm	}
2088231200Smm	ds = strm->ds;
2089231200Smm	ds->error = ARCHIVE_FAILED;
2090231200Smm
2091231200Smm	/* Allow bits from 15(32KBi) up to 21(2MBi) */
2092231200Smm	if (w_bits < SLOT_BASE || w_bits > SLOT_MAX)
2093231200Smm		return (ARCHIVE_FAILED);
2094231200Smm
2095231200Smm	ds->error = ARCHIVE_FATAL;
2096231200Smm
2097231200Smm	/*
2098231200Smm	 * Alloc window
2099231200Smm	 */
2100231200Smm	w_size = ds->w_size;
2101231200Smm	w_slot = slots[w_bits - SLOT_BASE];
2102231200Smm	ds->w_size = 1U << w_bits;
2103231200Smm	ds->w_mask = ds->w_size -1;
2104231200Smm	if (ds->w_buff == NULL || w_size != ds->w_size) {
2105231200Smm		free(ds->w_buff);
2106231200Smm		ds->w_buff = malloc(ds->w_size);
2107231200Smm		if (ds->w_buff == NULL)
2108231200Smm			return (ARCHIVE_FATAL);
2109231200Smm		free(ds->pos_tbl);
2110231200Smm		ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot);
2111231200Smm		if (ds->pos_tbl == NULL)
2112231200Smm			return (ARCHIVE_FATAL);
2113231200Smm		lzx_huffman_free(&(ds->mt));
2114231200Smm	}
2115231200Smm
2116232153Smm	for (footer = 0; footer < 18; footer++)
2117232153Smm		base_inc[footer] = 1 << footer;
2118231200Smm	base = footer = 0;
2119231200Smm	for (slot = 0; slot < w_slot; slot++) {
2120231200Smm		int n;
2121231200Smm		if (footer == 0)
2122231200Smm			base = slot;
2123231200Smm		else
2124232153Smm			base += base_inc[footer];
2125231200Smm		if (footer < 17) {
2126231200Smm			footer = -2;
2127231200Smm			for (n = base; n; n >>= 1)
2128231200Smm				footer++;
2129231200Smm			if (footer <= 0)
2130231200Smm				footer = 0;
2131231200Smm		}
2132231200Smm		ds->pos_tbl[slot].base = base;
2133231200Smm		ds->pos_tbl[slot].footer_bits = footer;
2134231200Smm	}
2135231200Smm
2136231200Smm	ds->w_pos = 0;
2137231200Smm	ds->state = 0;
2138231200Smm	ds->br.cache_buffer = 0;
2139231200Smm	ds->br.cache_avail = 0;
2140231200Smm	ds->r0 = ds->r1 = ds->r2 = 1;
2141231200Smm
2142231200Smm	/* Initialize aligned offset tree. */
2143231200Smm	if (lzx_huffman_init(&(ds->at), 8, 8) != ARCHIVE_OK)
2144231200Smm		return (ARCHIVE_FATAL);
2145231200Smm
2146231200Smm	/* Initialize pre-tree. */
2147231200Smm	if (lzx_huffman_init(&(ds->pt), 20, 10) != ARCHIVE_OK)
2148231200Smm		return (ARCHIVE_FATAL);
2149231200Smm
2150231200Smm	/* Initialize Main tree. */
2151231200Smm	if (lzx_huffman_init(&(ds->mt), 256+(w_slot<<3), 16)
2152231200Smm	    != ARCHIVE_OK)
2153231200Smm		return (ARCHIVE_FATAL);
2154231200Smm
2155231200Smm	/* Initialize Length tree. */
2156231200Smm	if (lzx_huffman_init(&(ds->lt), 249, 16) != ARCHIVE_OK)
2157231200Smm		return (ARCHIVE_FATAL);
2158231200Smm
2159231200Smm	ds->error = 0;
2160231200Smm
2161231200Smm	return (ARCHIVE_OK);
2162231200Smm}
2163231200Smm
2164231200Smm/*
2165231200Smm * Release LZX decoder.
2166231200Smm */
2167231200Smmstatic void
2168231200Smmlzx_decode_free(struct lzx_stream *strm)
2169231200Smm{
2170231200Smm
2171231200Smm	if (strm->ds == NULL)
2172231200Smm		return;
2173231200Smm	free(strm->ds->w_buff);
2174231200Smm	free(strm->ds->pos_tbl);
2175231200Smm	lzx_huffman_free(&(strm->ds->at));
2176231200Smm	lzx_huffman_free(&(strm->ds->pt));
2177231200Smm	lzx_huffman_free(&(strm->ds->mt));
2178231200Smm	lzx_huffman_free(&(strm->ds->lt));
2179231200Smm	free(strm->ds);
2180231200Smm	strm->ds = NULL;
2181231200Smm}
2182231200Smm
2183231200Smm/*
2184231200Smm * E8 Call Translation reversal.
2185231200Smm */
2186231200Smmstatic void
2187231200Smmlzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
2188231200Smm{
2189231200Smm	struct lzx_dec *ds = strm->ds;
2190231200Smm	unsigned char *b, *end;
2191231200Smm
2192231200Smm	if (!ds->translation || size <= 10)
2193231200Smm		return;
2194231200Smm	b = p;
2195231200Smm	end = b + size - 10;
2196231200Smm	while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) {
2197231200Smm		size_t i = b - (unsigned char *)p;
2198232153Smm		int32_t cp, displacement, value;
2199231200Smm
2200248616Smm		cp = (int32_t)(offset + (uint32_t)i);
2201231200Smm		value = archive_le32dec(&b[1]);
2202232153Smm		if (value >= -cp && value < (int32_t)ds->translation_size) {
2203231200Smm			if (value >= 0)
2204231200Smm				displacement = value - cp;
2205231200Smm			else
2206231200Smm				displacement = value + ds->translation_size;
2207231200Smm			archive_le32enc(&b[1], (uint32_t)displacement);
2208231200Smm		}
2209231200Smm		b += 5;
2210231200Smm	}
2211231200Smm}
2212231200Smm
2213231200Smm/*
2214231200Smm * Bit stream reader.
2215231200Smm */
2216231200Smm/* Check that the cache buffer has enough bits. */
2217231200Smm#define lzx_br_has(br, n)	((br)->cache_avail >= n)
2218231200Smm/* Get compressed data by bit. */
2219231200Smm#define lzx_br_bits(br, n)				\
2220231200Smm	(((uint32_t)((br)->cache_buffer >>		\
2221231200Smm		((br)->cache_avail - (n)))) & cache_masks[n])
2222231200Smm#define lzx_br_bits_forced(br, n)			\
2223231200Smm	(((uint32_t)((br)->cache_buffer <<		\
2224231200Smm		((n) - (br)->cache_avail))) & cache_masks[n])
2225231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we
2226231200Smm * will use.
2227231200Smm *  True  : completed, there is enough data in the cache buffer.
2228231200Smm *  False : we met that strm->next_in is empty, we have to get following
2229231200Smm *          bytes. */
2230231200Smm#define lzx_br_read_ahead_0(strm, br, n)	\
2231231200Smm	(lzx_br_has((br), (n)) || lzx_br_fillup(strm, br))
2232231200Smm/*  True  : the cache buffer has some bits as much as we need.
2233231200Smm *  False : there are no enough bits in the cache buffer to be used,
2234231200Smm *          we have to get following bytes if we could. */
2235231200Smm#define lzx_br_read_ahead(strm, br, n)	\
2236231200Smm	(lzx_br_read_ahead_0((strm), (br), (n)) || lzx_br_has((br), (n)))
2237231200Smm
2238231200Smm/* Notify how many bits we consumed. */
2239231200Smm#define lzx_br_consume(br, n)	((br)->cache_avail -= (n))
2240238856Smm#define lzx_br_consume_unaligned_bits(br) ((br)->cache_avail &= ~0x0f)
2241231200Smm
2242238856Smm#define lzx_br_is_unaligned(br)	((br)->cache_avail & 0x0f)
2243238856Smm
2244231200Smmstatic const uint32_t cache_masks[] = {
2245231200Smm	0x00000000, 0x00000001, 0x00000003, 0x00000007,
2246231200Smm	0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
2247231200Smm	0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
2248231200Smm	0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
2249231200Smm	0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
2250231200Smm	0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
2251231200Smm	0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
2252231200Smm	0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
2253231200Smm	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
2254231200Smm};
2255231200Smm
2256231200Smm/*
2257231200Smm * Shift away used bits in the cache data and fill it up with following bits.
2258231200Smm * Call this when cache buffer does not have enough bits you need.
2259231200Smm *
2260231200Smm * Returns 1 if the cache buffer is full.
2261231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty.
2262231200Smm */
2263231200Smmstatic int
2264231200Smmlzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
2265231200Smm{
2266231200Smm/*
2267311042Smm * x86 processor family can read misaligned data without an access error.
2268231200Smm */
2269231200Smm	int n = CACHE_BITS - br->cache_avail;
2270231200Smm
2271231200Smm	for (;;) {
2272231200Smm		switch (n >> 4) {
2273231200Smm		case 4:
2274231200Smm			if (strm->avail_in >= 8) {
2275231200Smm				br->cache_buffer =
2276231200Smm				    ((uint64_t)strm->next_in[1]) << 56 |
2277231200Smm				    ((uint64_t)strm->next_in[0]) << 48 |
2278231200Smm				    ((uint64_t)strm->next_in[3]) << 40 |
2279231200Smm				    ((uint64_t)strm->next_in[2]) << 32 |
2280231200Smm				    ((uint32_t)strm->next_in[5]) << 24 |
2281231200Smm				    ((uint32_t)strm->next_in[4]) << 16 |
2282231200Smm				    ((uint32_t)strm->next_in[7]) << 8 |
2283231200Smm				     (uint32_t)strm->next_in[6];
2284231200Smm				strm->next_in += 8;
2285231200Smm				strm->avail_in -= 8;
2286231200Smm				br->cache_avail += 8 * 8;
2287231200Smm				return (1);
2288231200Smm			}
2289231200Smm			break;
2290231200Smm		case 3:
2291231200Smm			if (strm->avail_in >= 6) {
2292231200Smm				br->cache_buffer =
2293231200Smm		 		   (br->cache_buffer << 48) |
2294231200Smm				    ((uint64_t)strm->next_in[1]) << 40 |
2295231200Smm				    ((uint64_t)strm->next_in[0]) << 32 |
2296231200Smm				    ((uint32_t)strm->next_in[3]) << 24 |
2297231200Smm				    ((uint32_t)strm->next_in[2]) << 16 |
2298231200Smm				    ((uint32_t)strm->next_in[5]) << 8 |
2299231200Smm				     (uint32_t)strm->next_in[4];
2300231200Smm				strm->next_in += 6;
2301231200Smm				strm->avail_in -= 6;
2302231200Smm				br->cache_avail += 6 * 8;
2303231200Smm				return (1);
2304231200Smm			}
2305231200Smm			break;
2306231200Smm		case 0:
2307231200Smm			/* We have enough compressed data in
2308231200Smm			 * the cache buffer.*/
2309231200Smm			return (1);
2310231200Smm		default:
2311231200Smm			break;
2312231200Smm		}
2313231200Smm		if (strm->avail_in < 2) {
2314231200Smm			/* There is not enough compressed data to
2315231200Smm			 * fill up the cache buffer. */
2316231200Smm			if (strm->avail_in == 1) {
2317231200Smm				br->odd = *strm->next_in++;
2318231200Smm				strm->avail_in--;
2319231200Smm				br->have_odd = 1;
2320231200Smm			}
2321231200Smm			return (0);
2322231200Smm		}
2323231200Smm		br->cache_buffer =
2324231200Smm		   (br->cache_buffer << 16) |
2325231200Smm		    archive_le16dec(strm->next_in);
2326231200Smm		strm->next_in += 2;
2327231200Smm		strm->avail_in -= 2;
2328231200Smm		br->cache_avail += 16;
2329231200Smm		n -= 16;
2330231200Smm	}
2331231200Smm}
2332231200Smm
2333231200Smmstatic void
2334231200Smmlzx_br_fixup(struct lzx_stream *strm, struct lzx_br *br)
2335231200Smm{
2336231200Smm	int n = CACHE_BITS - br->cache_avail;
2337231200Smm
2338231200Smm	if (br->have_odd && n >= 16 && strm->avail_in > 0) {
2339231200Smm		br->cache_buffer =
2340231200Smm		   (br->cache_buffer << 16) |
2341231200Smm		   ((uint16_t)(*strm->next_in)) << 8 | br->odd;
2342231200Smm		strm->next_in++;
2343231200Smm		strm->avail_in--;
2344231200Smm		br->cache_avail += 16;
2345231200Smm		br->have_odd = 0;
2346231200Smm	}
2347231200Smm}
2348231200Smm
2349231200Smmstatic void
2350231200Smmlzx_cleanup_bitstream(struct lzx_stream *strm)
2351231200Smm{
2352231200Smm	strm->ds->br.cache_avail = 0;
2353231200Smm	strm->ds->br.have_odd = 0;
2354231200Smm}
2355231200Smm
2356231200Smm/*
2357231200Smm * Decode LZX.
2358231200Smm *
2359231200Smm * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
2360231200Smm *    Please set available buffer and call this function again.
2361231200Smm * 2. Returns ARCHIVE_EOF if decompression has been completed.
2362231200Smm * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
2363231200Smm *    is broken or you do not set 'last' flag properly.
2364231200Smm */
2365231200Smm#define ST_RD_TRANSLATION	0
2366231200Smm#define ST_RD_TRANSLATION_SIZE	1
2367231200Smm#define ST_RD_BLOCK_TYPE	2
2368231200Smm#define ST_RD_BLOCK_SIZE	3
2369238856Smm#define ST_RD_ALIGNMENT		4
2370238856Smm#define ST_RD_R0		5
2371238856Smm#define ST_RD_R1		6
2372238856Smm#define ST_RD_R2		7
2373238856Smm#define ST_COPY_UNCOMP1		8
2374238856Smm#define ST_COPY_UNCOMP2		9
2375238856Smm#define ST_RD_ALIGNED_OFFSET	10
2376238856Smm#define ST_RD_VERBATIM		11
2377238856Smm#define ST_RD_PRE_MAIN_TREE_256	12
2378238856Smm#define ST_MAIN_TREE_256	13
2379238856Smm#define ST_RD_PRE_MAIN_TREE_REM	14
2380238856Smm#define ST_MAIN_TREE_REM	15
2381238856Smm#define ST_RD_PRE_LENGTH_TREE	16
2382238856Smm#define ST_LENGTH_TREE		17
2383238856Smm#define ST_MAIN			18
2384238856Smm#define ST_LENGTH		19
2385238856Smm#define ST_OFFSET		20
2386238856Smm#define ST_REAL_POS		21
2387238856Smm#define ST_COPY			22
2388231200Smm
2389231200Smmstatic int
2390231200Smmlzx_decode(struct lzx_stream *strm, int last)
2391231200Smm{
2392231200Smm	struct lzx_dec *ds = strm->ds;
2393231200Smm	int64_t avail_in;
2394231200Smm	int r;
2395231200Smm
2396231200Smm	if (ds->error)
2397231200Smm		return (ds->error);
2398231200Smm
2399231200Smm	avail_in = strm->avail_in;
2400231200Smm	lzx_br_fixup(strm, &(ds->br));
2401231200Smm	do {
2402231200Smm		if (ds->state < ST_MAIN)
2403231200Smm			r = lzx_read_blocks(strm, last);
2404231200Smm		else {
2405231200Smm			int64_t bytes_written = strm->avail_out;
2406231200Smm			r = lzx_decode_blocks(strm, last);
2407231200Smm			bytes_written -= strm->avail_out;
2408231200Smm			strm->next_out += bytes_written;
2409231200Smm			strm->total_out += bytes_written;
2410231200Smm		}
2411231200Smm	} while (r == 100);
2412231200Smm	strm->total_in += avail_in - strm->avail_in;
2413231200Smm	return (r);
2414231200Smm}
2415231200Smm
2416231200Smmstatic int
2417231200Smmlzx_read_blocks(struct lzx_stream *strm, int last)
2418231200Smm{
2419231200Smm	struct lzx_dec *ds = strm->ds;
2420231200Smm	struct lzx_br *br = &(ds->br);
2421231200Smm	int i, r;
2422231200Smm
2423231200Smm	for (;;) {
2424231200Smm		switch (ds->state) {
2425231200Smm		case ST_RD_TRANSLATION:
2426231200Smm			if (!lzx_br_read_ahead(strm, br, 1)) {
2427231200Smm				ds->state = ST_RD_TRANSLATION;
2428231200Smm				if (last)
2429231200Smm					goto failed;
2430231200Smm				return (ARCHIVE_OK);
2431231200Smm			}
2432231200Smm			ds->translation = lzx_br_bits(br, 1);
2433231200Smm			lzx_br_consume(br, 1);
2434231200Smm			/* FALL THROUGH */
2435231200Smm		case ST_RD_TRANSLATION_SIZE:
2436231200Smm			if (ds->translation) {
2437231200Smm				if (!lzx_br_read_ahead(strm, br, 32)) {
2438231200Smm					ds->state = ST_RD_TRANSLATION_SIZE;
2439231200Smm					if (last)
2440231200Smm						goto failed;
2441231200Smm					return (ARCHIVE_OK);
2442231200Smm				}
2443231200Smm				ds->translation_size = lzx_br_bits(br, 16);
2444231200Smm				lzx_br_consume(br, 16);
2445231200Smm				ds->translation_size <<= 16;
2446231200Smm				ds->translation_size |= lzx_br_bits(br, 16);
2447231200Smm				lzx_br_consume(br, 16);
2448231200Smm			}
2449231200Smm			/* FALL THROUGH */
2450231200Smm		case ST_RD_BLOCK_TYPE:
2451231200Smm			if (!lzx_br_read_ahead(strm, br, 3)) {
2452231200Smm				ds->state = ST_RD_BLOCK_TYPE;
2453231200Smm				if (last)
2454231200Smm					goto failed;
2455231200Smm				return (ARCHIVE_OK);
2456231200Smm			}
2457231200Smm			ds->block_type = lzx_br_bits(br, 3);
2458231200Smm			lzx_br_consume(br, 3);
2459231200Smm			/* Check a block type. */
2460231200Smm			switch (ds->block_type) {
2461231200Smm			case VERBATIM_BLOCK:
2462231200Smm			case ALIGNED_OFFSET_BLOCK:
2463231200Smm			case UNCOMPRESSED_BLOCK:
2464231200Smm				break;
2465231200Smm			default:
2466231200Smm				goto failed;/* Invalid */
2467231200Smm			}
2468231200Smm			/* FALL THROUGH */
2469231200Smm		case ST_RD_BLOCK_SIZE:
2470231200Smm			if (!lzx_br_read_ahead(strm, br, 24)) {
2471231200Smm				ds->state = ST_RD_BLOCK_SIZE;
2472231200Smm				if (last)
2473231200Smm					goto failed;
2474231200Smm				return (ARCHIVE_OK);
2475231200Smm			}
2476231200Smm			ds->block_size = lzx_br_bits(br, 8);
2477231200Smm			lzx_br_consume(br, 8);
2478231200Smm			ds->block_size <<= 16;
2479231200Smm			ds->block_size |= lzx_br_bits(br, 16);
2480231200Smm			lzx_br_consume(br, 16);
2481231200Smm			if (ds->block_size == 0)
2482231200Smm				goto failed;
2483231200Smm			ds->block_bytes_avail = ds->block_size;
2484231200Smm			if (ds->block_type != UNCOMPRESSED_BLOCK) {
2485231200Smm				if (ds->block_type == VERBATIM_BLOCK)
2486231200Smm					ds->state = ST_RD_VERBATIM;
2487231200Smm				else
2488231200Smm					ds->state = ST_RD_ALIGNED_OFFSET;
2489231200Smm				break;
2490231200Smm			}
2491238856Smm			/* FALL THROUGH */
2492238856Smm		case ST_RD_ALIGNMENT:
2493231200Smm			/*
2494231200Smm			 * Handle an Uncompressed Block.
2495231200Smm			 */
2496231200Smm			/* Skip padding to align following field on
2497231200Smm			 * 16-bit boundary. */
2498238856Smm			if (lzx_br_is_unaligned(br))
2499238856Smm				lzx_br_consume_unaligned_bits(br);
2500238856Smm			else {
2501238856Smm				if (lzx_br_read_ahead(strm, br, 16))
2502238856Smm					lzx_br_consume(br, 16);
2503238856Smm				else {
2504238856Smm					ds->state = ST_RD_ALIGNMENT;
2505238856Smm					if (last)
2506238856Smm						goto failed;
2507238856Smm					return (ARCHIVE_OK);
2508238856Smm				}
2509238856Smm			}
2510231200Smm			/* Preparation to read repeated offsets R0,R1 and R2. */
2511231200Smm			ds->rbytes_avail = 0;
2512231200Smm			ds->state = ST_RD_R0;
2513231200Smm			/* FALL THROUGH */
2514231200Smm		case ST_RD_R0:
2515231200Smm		case ST_RD_R1:
2516231200Smm		case ST_RD_R2:
2517231200Smm			do {
2518231200Smm				uint16_t u16;
2519231200Smm				/* Drain bits in the cache buffer of
2520231200Smm				 * bit-stream. */
2521231200Smm				if (lzx_br_has(br, 32)) {
2522231200Smm					u16 = lzx_br_bits(br, 16);
2523231200Smm					lzx_br_consume(br, 16);
2524231200Smm					archive_le16enc(ds->rbytes, u16);
2525231200Smm					u16 = lzx_br_bits(br, 16);
2526231200Smm					lzx_br_consume(br, 16);
2527231200Smm					archive_le16enc(ds->rbytes+2, u16);
2528231200Smm					ds->rbytes_avail = 4;
2529231200Smm				} else if (lzx_br_has(br, 16)) {
2530231200Smm					u16 = lzx_br_bits(br, 16);
2531231200Smm					lzx_br_consume(br, 16);
2532231200Smm					archive_le16enc(ds->rbytes, u16);
2533231200Smm					ds->rbytes_avail = 2;
2534238856Smm				}
2535231200Smm				if (ds->rbytes_avail < 4 && ds->br.have_odd) {
2536231200Smm					ds->rbytes[ds->rbytes_avail++] =
2537231200Smm					    ds->br.odd;
2538231200Smm					ds->br.have_odd = 0;
2539231200Smm				}
2540231200Smm				while (ds->rbytes_avail < 4) {
2541231200Smm					if (strm->avail_in <= 0) {
2542231200Smm						if (last)
2543231200Smm							goto failed;
2544231200Smm						return (ARCHIVE_OK);
2545231200Smm					}
2546231200Smm					ds->rbytes[ds->rbytes_avail++] =
2547231200Smm					    *strm->next_in++;
2548231200Smm					strm->avail_in--;
2549231200Smm				}
2550238856Smm				ds->rbytes_avail = 0;
2551231200Smm				if (ds->state == ST_RD_R0) {
2552231200Smm					ds->r0 = archive_le32dec(ds->rbytes);
2553231200Smm					if (ds->r0 < 0)
2554231200Smm						goto failed;
2555231200Smm					ds->state = ST_RD_R1;
2556231200Smm				} else if (ds->state == ST_RD_R1) {
2557231200Smm					ds->r1 = archive_le32dec(ds->rbytes);
2558231200Smm					if (ds->r1 < 0)
2559231200Smm						goto failed;
2560231200Smm					ds->state = ST_RD_R2;
2561231200Smm				} else if (ds->state == ST_RD_R2) {
2562231200Smm					ds->r2 = archive_le32dec(ds->rbytes);
2563231200Smm					if (ds->r2 < 0)
2564231200Smm						goto failed;
2565231200Smm					/* We've gotten all repeated offsets. */
2566231200Smm					ds->state = ST_COPY_UNCOMP1;
2567231200Smm				}
2568231200Smm			} while (ds->state != ST_COPY_UNCOMP1);
2569231200Smm			/* FALL THROUGH */
2570231200Smm		case ST_COPY_UNCOMP1:
2571231200Smm			/*
2572231200Smm			 * Copy bytes form next_in to next_out directly.
2573231200Smm			 */
2574231200Smm			while (ds->block_bytes_avail) {
2575238856Smm				int l;
2576231200Smm
2577231200Smm				if (strm->avail_out <= 0)
2578231200Smm					/* Output buffer is empty. */
2579231200Smm					return (ARCHIVE_OK);
2580231200Smm				if (strm->avail_in <= 0) {
2581231200Smm					/* Input buffer is empty. */
2582231200Smm					if (last)
2583231200Smm						goto failed;
2584231200Smm					return (ARCHIVE_OK);
2585231200Smm				}
2586248616Smm				l = (int)ds->block_bytes_avail;
2587231200Smm				if (l > ds->w_size - ds->w_pos)
2588231200Smm					l = ds->w_size - ds->w_pos;
2589231200Smm				if (l > strm->avail_out)
2590231200Smm					l = (int)strm->avail_out;
2591231200Smm				if (l > strm->avail_in)
2592231200Smm					l = (int)strm->avail_in;
2593238856Smm				memcpy(strm->next_out, strm->next_in, l);
2594238856Smm				memcpy(&(ds->w_buff[ds->w_pos]),
2595238856Smm				    strm->next_in, l);
2596238856Smm				strm->next_in += l;
2597238856Smm				strm->avail_in -= l;
2598238856Smm				strm->next_out += l;
2599238856Smm				strm->avail_out -= l;
2600238856Smm				strm->total_out += l;
2601238856Smm				ds->w_pos = (ds->w_pos + l) & ds->w_mask;
2602238856Smm				ds->block_bytes_avail -= l;
2603231200Smm			}
2604231200Smm			/* FALL THROUGH */
2605231200Smm		case ST_COPY_UNCOMP2:
2606231200Smm			/* Re-align; skip padding byte. */
2607231200Smm			if (ds->block_size & 1) {
2608231200Smm				if (strm->avail_in <= 0) {
2609231200Smm					/* Input buffer is empty. */
2610231200Smm					ds->state = ST_COPY_UNCOMP2;
2611231200Smm					if (last)
2612231200Smm						goto failed;
2613231200Smm					return (ARCHIVE_OK);
2614231200Smm				}
2615231200Smm				strm->next_in++;
2616231200Smm				strm->avail_in --;
2617231200Smm			}
2618231200Smm			/* This block ended. */
2619231200Smm			ds->state = ST_RD_BLOCK_TYPE;
2620231200Smm			return (ARCHIVE_EOF);
2621231200Smm			/********************/
2622231200Smm		case ST_RD_ALIGNED_OFFSET:
2623231200Smm			/*
2624231200Smm			 * Read Aligned offset tree.
2625231200Smm			 */
2626231200Smm			if (!lzx_br_read_ahead(strm, br, 3 * ds->at.len_size)) {
2627231200Smm				ds->state = ST_RD_ALIGNED_OFFSET;
2628231200Smm				if (last)
2629231200Smm					goto failed;
2630231200Smm				return (ARCHIVE_OK);
2631231200Smm			}
2632231200Smm			memset(ds->at.freq, 0, sizeof(ds->at.freq));
2633231200Smm			for (i = 0; i < ds->at.len_size; i++) {
2634231200Smm				ds->at.bitlen[i] = lzx_br_bits(br, 3);
2635231200Smm				ds->at.freq[ds->at.bitlen[i]]++;
2636231200Smm				lzx_br_consume(br, 3);
2637231200Smm			}
2638231200Smm			if (!lzx_make_huffman_table(&ds->at))
2639231200Smm				goto failed;
2640231200Smm			/* FALL THROUGH */
2641231200Smm		case ST_RD_VERBATIM:
2642231200Smm			ds->loop = 0;
2643231200Smm			/* FALL THROUGH */
2644231200Smm		case ST_RD_PRE_MAIN_TREE_256:
2645231200Smm			/*
2646231200Smm			 * Read Pre-tree for first 256 elements of main tree.
2647231200Smm			 */
2648231200Smm			if (!lzx_read_pre_tree(strm)) {
2649231200Smm				ds->state = ST_RD_PRE_MAIN_TREE_256;
2650231200Smm				if (last)
2651231200Smm					goto failed;
2652231200Smm				return (ARCHIVE_OK);
2653231200Smm			}
2654231200Smm			if (!lzx_make_huffman_table(&ds->pt))
2655231200Smm				goto failed;
2656231200Smm			ds->loop = 0;
2657231200Smm			/* FALL THROUGH */
2658231200Smm		case ST_MAIN_TREE_256:
2659231200Smm			/*
2660231200Smm			 * Get path lengths of first 256 elements of main tree.
2661231200Smm			 */
2662231200Smm			r = lzx_read_bitlen(strm, &ds->mt, 256);
2663231200Smm			if (r < 0)
2664231200Smm				goto failed;
2665231200Smm			else if (!r) {
2666231200Smm				ds->state = ST_MAIN_TREE_256;
2667231200Smm				if (last)
2668231200Smm					goto failed;
2669231200Smm				return (ARCHIVE_OK);
2670231200Smm			}
2671231200Smm			ds->loop = 0;
2672231200Smm			/* FALL THROUGH */
2673231200Smm		case ST_RD_PRE_MAIN_TREE_REM:
2674231200Smm			/*
2675231200Smm			 * Read Pre-tree for remaining elements of main tree.
2676231200Smm			 */
2677231200Smm			if (!lzx_read_pre_tree(strm)) {
2678231200Smm				ds->state = ST_RD_PRE_MAIN_TREE_REM;
2679231200Smm				if (last)
2680231200Smm					goto failed;
2681231200Smm				return (ARCHIVE_OK);
2682231200Smm			}
2683231200Smm			if (!lzx_make_huffman_table(&ds->pt))
2684231200Smm				goto failed;
2685231200Smm			ds->loop = 256;
2686231200Smm			/* FALL THROUGH */
2687231200Smm		case ST_MAIN_TREE_REM:
2688231200Smm			/*
2689231200Smm			 * Get path lengths of remaining elements of main tree.
2690231200Smm			 */
2691231200Smm			r = lzx_read_bitlen(strm, &ds->mt, -1);
2692231200Smm			if (r < 0)
2693231200Smm				goto failed;
2694231200Smm			else if (!r) {
2695231200Smm				ds->state = ST_MAIN_TREE_REM;
2696231200Smm				if (last)
2697231200Smm					goto failed;
2698231200Smm				return (ARCHIVE_OK);
2699231200Smm			}
2700231200Smm			if (!lzx_make_huffman_table(&ds->mt))
2701231200Smm				goto failed;
2702231200Smm			ds->loop = 0;
2703231200Smm			/* FALL THROUGH */
2704231200Smm		case ST_RD_PRE_LENGTH_TREE:
2705231200Smm			/*
2706231200Smm			 * Read Pre-tree for remaining elements of main tree.
2707231200Smm			 */
2708231200Smm			if (!lzx_read_pre_tree(strm)) {
2709231200Smm				ds->state = ST_RD_PRE_LENGTH_TREE;
2710231200Smm				if (last)
2711231200Smm					goto failed;
2712231200Smm				return (ARCHIVE_OK);
2713231200Smm			}
2714231200Smm			if (!lzx_make_huffman_table(&ds->pt))
2715231200Smm				goto failed;
2716231200Smm			ds->loop = 0;
2717231200Smm			/* FALL THROUGH */
2718231200Smm		case ST_LENGTH_TREE:
2719231200Smm			/*
2720231200Smm			 * Get path lengths of remaining elements of main tree.
2721231200Smm			 */
2722231200Smm			r = lzx_read_bitlen(strm, &ds->lt, -1);
2723231200Smm			if (r < 0)
2724231200Smm				goto failed;
2725231200Smm			else if (!r) {
2726231200Smm				ds->state = ST_LENGTH_TREE;
2727231200Smm				if (last)
2728231200Smm					goto failed;
2729231200Smm				return (ARCHIVE_OK);
2730231200Smm			}
2731231200Smm			if (!lzx_make_huffman_table(&ds->lt))
2732231200Smm				goto failed;
2733231200Smm			ds->state = ST_MAIN;
2734231200Smm			return (100);
2735231200Smm		}
2736231200Smm	}
2737231200Smmfailed:
2738231200Smm	return (ds->error = ARCHIVE_FAILED);
2739231200Smm}
2740231200Smm
2741231200Smmstatic int
2742231200Smmlzx_decode_blocks(struct lzx_stream *strm, int last)
2743231200Smm{
2744231200Smm	struct lzx_dec *ds = strm->ds;
2745231200Smm	struct lzx_br bre = ds->br;
2746231200Smm	struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt);
2747231200Smm	const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl;
2748248616Smm	unsigned char *noutp = strm->next_out;
2749248616Smm	unsigned char *endp = noutp + strm->avail_out;
2750231200Smm	unsigned char *w_buff = ds->w_buff;
2751231200Smm	unsigned char *at_bitlen = at->bitlen;
2752231200Smm	unsigned char *lt_bitlen = lt->bitlen;
2753231200Smm	unsigned char *mt_bitlen = mt->bitlen;
2754231200Smm	size_t block_bytes_avail = ds->block_bytes_avail;
2755231200Smm	int at_max_bits = at->max_bits;
2756231200Smm	int lt_max_bits = lt->max_bits;
2757231200Smm	int mt_max_bits = mt->max_bits;
2758231200Smm	int c, copy_len = ds->copy_len, copy_pos = ds->copy_pos;
2759231200Smm	int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
2760231200Smm	int length_header = ds->length_header;
2761231200Smm	int offset_bits = ds->offset_bits;
2762231200Smm	int position_slot = ds->position_slot;
2763231200Smm	int r0 = ds->r0, r1 = ds->r1, r2 = ds->r2;
2764231200Smm	int state = ds->state;
2765231200Smm	char block_type = ds->block_type;
2766231200Smm
2767231200Smm	for (;;) {
2768231200Smm		switch (state) {
2769231200Smm		case ST_MAIN:
2770231200Smm			for (;;) {
2771231200Smm				if (block_bytes_avail == 0) {
2772231200Smm					/* This block ended. */
2773231200Smm					ds->state = ST_RD_BLOCK_TYPE;
2774231200Smm					ds->br = bre;
2775231200Smm					ds->block_bytes_avail =
2776231200Smm					    block_bytes_avail;
2777231200Smm					ds->copy_len = copy_len;
2778231200Smm					ds->copy_pos = copy_pos;
2779231200Smm					ds->length_header = length_header;
2780231200Smm					ds->position_slot = position_slot;
2781231200Smm					ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
2782231200Smm					ds->w_pos = w_pos;
2783248616Smm					strm->avail_out = endp - noutp;
2784231200Smm					return (ARCHIVE_EOF);
2785231200Smm				}
2786248616Smm				if (noutp >= endp)
2787231200Smm					/* Output buffer is empty. */
2788231200Smm					goto next_data;
2789231200Smm
2790231200Smm				if (!lzx_br_read_ahead(strm, &bre,
2791231200Smm				    mt_max_bits)) {
2792231200Smm					if (!last)
2793231200Smm						goto next_data;
2794231200Smm					/* Remaining bits are less than
2795231200Smm					 * maximum bits(mt.max_bits) but maybe
2796231200Smm					 * it still remains as much as we need,
2797231200Smm					 * so we should try to use it with
2798231200Smm					 * dummy bits. */
2799231200Smm					c = lzx_decode_huffman(mt,
2800231200Smm					      lzx_br_bits_forced(
2801231200Smm				 	        &bre, mt_max_bits));
2802231200Smm					lzx_br_consume(&bre, mt_bitlen[c]);
2803231200Smm					if (!lzx_br_has(&bre, 0))
2804231200Smm						goto failed;/* Over read. */
2805231200Smm				} else {
2806231200Smm					c = lzx_decode_huffman(mt,
2807231200Smm					      lzx_br_bits(&bre, mt_max_bits));
2808231200Smm					lzx_br_consume(&bre, mt_bitlen[c]);
2809231200Smm				}
2810231200Smm				if (c > UCHAR_MAX)
2811231200Smm					break;
2812231200Smm				/*
2813231200Smm				 * 'c' is exactly literal code.
2814231200Smm				 */
2815231200Smm				/* Save a decoded code to reference it
2816231200Smm				 * afterward. */
2817231200Smm				w_buff[w_pos] = c;
2818231200Smm				w_pos = (w_pos + 1) & w_mask;
2819231200Smm				/* Store the decoded code to output buffer. */
2820248616Smm				*noutp++ = c;
2821231200Smm				block_bytes_avail--;
2822231200Smm			}
2823231200Smm			/*
2824231200Smm			 * Get a match code, its length and offset.
2825231200Smm			 */
2826231200Smm			c -= UCHAR_MAX + 1;
2827231200Smm			length_header = c & 7;
2828231200Smm			position_slot = c >> 3;
2829231200Smm			/* FALL THROUGH */
2830231200Smm		case ST_LENGTH:
2831231200Smm			/*
2832231200Smm			 * Get a length.
2833231200Smm			 */
2834231200Smm			if (length_header == 7) {
2835231200Smm				if (!lzx_br_read_ahead(strm, &bre,
2836231200Smm				    lt_max_bits)) {
2837231200Smm					if (!last) {
2838231200Smm						state = ST_LENGTH;
2839231200Smm						goto next_data;
2840231200Smm					}
2841231200Smm					c = lzx_decode_huffman(lt,
2842231200Smm					      lzx_br_bits_forced(
2843231200Smm					        &bre, lt_max_bits));
2844231200Smm					lzx_br_consume(&bre, lt_bitlen[c]);
2845231200Smm					if (!lzx_br_has(&bre, 0))
2846231200Smm						goto failed;/* Over read. */
2847231200Smm				} else {
2848231200Smm					c = lzx_decode_huffman(lt,
2849231200Smm					    lzx_br_bits(&bre, lt_max_bits));
2850231200Smm					lzx_br_consume(&bre, lt_bitlen[c]);
2851231200Smm				}
2852231200Smm				copy_len = c + 7 + 2;
2853231200Smm			} else
2854231200Smm				copy_len = length_header + 2;
2855231200Smm			if ((size_t)copy_len > block_bytes_avail)
2856231200Smm				goto failed;
2857231200Smm			/*
2858231200Smm			 * Get an offset.
2859231200Smm			 */
2860231200Smm			switch (position_slot) {
2861231200Smm			case 0: /* Use repeated offset 0. */
2862231200Smm				copy_pos = r0;
2863231200Smm				state = ST_REAL_POS;
2864231200Smm				continue;
2865231200Smm			case 1: /* Use repeated offset 1. */
2866231200Smm				copy_pos = r1;
2867231200Smm				/* Swap repeated offset. */
2868231200Smm				r1 = r0;
2869231200Smm				r0 = copy_pos;
2870231200Smm				state = ST_REAL_POS;
2871231200Smm				continue;
2872231200Smm			case 2: /* Use repeated offset 2. */
2873231200Smm				copy_pos = r2;
2874231200Smm				/* Swap repeated offset. */
2875231200Smm				r2 = r0;
2876231200Smm				r0 = copy_pos;
2877231200Smm				state = ST_REAL_POS;
2878231200Smm				continue;
2879231200Smm			default:
2880231200Smm				offset_bits =
2881231200Smm				    pos_tbl[position_slot].footer_bits;
2882231200Smm				break;
2883231200Smm			}
2884231200Smm			/* FALL THROUGH */
2885231200Smm		case ST_OFFSET:
2886231200Smm			/*
2887231200Smm			 * Get the offset, which is a distance from
2888231200Smm			 * current window position.
2889231200Smm			 */
2890231200Smm			if (block_type == ALIGNED_OFFSET_BLOCK &&
2891231200Smm			    offset_bits >= 3) {
2892231200Smm				int offbits = offset_bits - 3;
2893231200Smm
2894231200Smm				if (!lzx_br_read_ahead(strm, &bre, offbits)) {
2895231200Smm					state = ST_OFFSET;
2896231200Smm					if (last)
2897231200Smm						goto failed;
2898231200Smm					goto next_data;
2899231200Smm				}
2900231200Smm				copy_pos = lzx_br_bits(&bre, offbits) << 3;
2901231200Smm
2902231200Smm				/* Get an aligned number. */
2903231200Smm				if (!lzx_br_read_ahead(strm, &bre,
2904231200Smm				    offbits + at_max_bits)) {
2905231200Smm					if (!last) {
2906231200Smm						state = ST_OFFSET;
2907231200Smm						goto next_data;
2908231200Smm					}
2909231200Smm					lzx_br_consume(&bre, offbits);
2910231200Smm					c = lzx_decode_huffman(at,
2911231200Smm					      lzx_br_bits_forced(&bre,
2912231200Smm					        at_max_bits));
2913231200Smm					lzx_br_consume(&bre, at_bitlen[c]);
2914231200Smm					if (!lzx_br_has(&bre, 0))
2915231200Smm						goto failed;/* Over read. */
2916231200Smm				} else {
2917231200Smm					lzx_br_consume(&bre, offbits);
2918231200Smm					c = lzx_decode_huffman(at,
2919231200Smm					      lzx_br_bits(&bre, at_max_bits));
2920231200Smm					lzx_br_consume(&bre, at_bitlen[c]);
2921231200Smm				}
2922231200Smm				/* Add an aligned number. */
2923231200Smm				copy_pos += c;
2924231200Smm			} else {
2925231200Smm				if (!lzx_br_read_ahead(strm, &bre,
2926231200Smm				    offset_bits)) {
2927231200Smm					state = ST_OFFSET;
2928231200Smm					if (last)
2929231200Smm						goto failed;
2930231200Smm					goto next_data;
2931231200Smm				}
2932231200Smm				copy_pos = lzx_br_bits(&bre, offset_bits);
2933231200Smm				lzx_br_consume(&bre, offset_bits);
2934231200Smm			}
2935231200Smm			copy_pos += pos_tbl[position_slot].base -2;
2936231200Smm
2937231200Smm			/* Update repeated offset LRU queue. */
2938231200Smm			r2 = r1;
2939231200Smm			r1 = r0;
2940231200Smm			r0 = copy_pos;
2941231200Smm			/* FALL THROUGH */
2942231200Smm		case ST_REAL_POS:
2943231200Smm			/*
2944231200Smm			 * Compute a real position in window.
2945231200Smm			 */
2946231200Smm			copy_pos = (w_pos - copy_pos) & w_mask;
2947231200Smm			/* FALL THROUGH */
2948231200Smm		case ST_COPY:
2949231200Smm			/*
2950231200Smm			 * Copy several bytes as extracted data from the window
2951231200Smm			 * into the output buffer.
2952231200Smm			 */
2953231200Smm			for (;;) {
2954231200Smm				const unsigned char *s;
2955231200Smm				int l;
2956231200Smm
2957231200Smm				l = copy_len;
2958231200Smm				if (copy_pos > w_pos) {
2959231200Smm					if (l > w_size - copy_pos)
2960231200Smm						l = w_size - copy_pos;
2961231200Smm				} else {
2962231200Smm					if (l > w_size - w_pos)
2963231200Smm						l = w_size - w_pos;
2964231200Smm				}
2965248616Smm				if (noutp + l >= endp)
2966248616Smm					l = (int)(endp - noutp);
2967231200Smm				s = w_buff + copy_pos;
2968231200Smm				if (l >= 8 && ((copy_pos + l < w_pos)
2969231200Smm				  || (w_pos + l < copy_pos))) {
2970231200Smm					memcpy(w_buff + w_pos, s, l);
2971248616Smm					memcpy(noutp, s, l);
2972231200Smm				} else {
2973231200Smm					unsigned char *d;
2974231200Smm					int li;
2975231200Smm
2976231200Smm					d = w_buff + w_pos;
2977231200Smm					for (li = 0; li < l; li++)
2978248616Smm						noutp[li] = d[li] = s[li];
2979231200Smm				}
2980248616Smm				noutp += l;
2981231200Smm				copy_pos = (copy_pos + l) & w_mask;
2982231200Smm				w_pos = (w_pos + l) & w_mask;
2983231200Smm				block_bytes_avail -= l;
2984231200Smm				if (copy_len <= l)
2985231200Smm					/* A copy of current pattern ended. */
2986231200Smm					break;
2987231200Smm				copy_len -= l;
2988248616Smm				if (noutp >= endp) {
2989231200Smm					/* Output buffer is empty. */
2990231200Smm					state = ST_COPY;
2991231200Smm					goto next_data;
2992231200Smm				}
2993231200Smm			}
2994231200Smm			state = ST_MAIN;
2995231200Smm			break;
2996231200Smm		}
2997231200Smm	}
2998231200Smmfailed:
2999231200Smm	return (ds->error = ARCHIVE_FAILED);
3000231200Smmnext_data:
3001231200Smm	ds->br = bre;
3002231200Smm	ds->block_bytes_avail = block_bytes_avail;
3003231200Smm	ds->copy_len = copy_len;
3004231200Smm	ds->copy_pos = copy_pos;
3005231200Smm	ds->length_header = length_header;
3006231200Smm	ds->offset_bits = offset_bits;
3007231200Smm	ds->position_slot = position_slot;
3008231200Smm	ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
3009231200Smm	ds->state = state;
3010231200Smm	ds->w_pos = w_pos;
3011248616Smm	strm->avail_out = endp - noutp;
3012231200Smm	return (ARCHIVE_OK);
3013231200Smm}
3014231200Smm
3015231200Smmstatic int
3016231200Smmlzx_read_pre_tree(struct lzx_stream *strm)
3017231200Smm{
3018231200Smm	struct lzx_dec *ds = strm->ds;
3019231200Smm	struct lzx_br *br = &(ds->br);
3020231200Smm	int i;
3021231200Smm
3022231200Smm	if (ds->loop == 0)
3023231200Smm		memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
3024231200Smm	for (i = ds->loop; i < ds->pt.len_size; i++) {
3025231200Smm		if (!lzx_br_read_ahead(strm, br, 4)) {
3026231200Smm			ds->loop = i;
3027231200Smm			return (0);
3028231200Smm		}
3029231200Smm		ds->pt.bitlen[i] = lzx_br_bits(br, 4);
3030231200Smm		ds->pt.freq[ds->pt.bitlen[i]]++;
3031231200Smm		lzx_br_consume(br, 4);
3032231200Smm	}
3033231200Smm	ds->loop = i;
3034231200Smm	return (1);
3035231200Smm}
3036231200Smm
3037231200Smm/*
3038231200Smm * Read a bunch of bit-lengths from pre-tree.
3039231200Smm */
3040231200Smmstatic int
3041231200Smmlzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end)
3042231200Smm{
3043231200Smm	struct lzx_dec *ds = strm->ds;
3044231200Smm	struct lzx_br *br = &(ds->br);
3045231200Smm	int c, i, j, ret, same;
3046231200Smm	unsigned rbits;
3047231200Smm
3048231200Smm	i = ds->loop;
3049231200Smm	if (i == 0)
3050231200Smm		memset(d->freq, 0, sizeof(d->freq));
3051231200Smm	ret = 0;
3052231200Smm	if (end < 0)
3053231200Smm		end = d->len_size;
3054231200Smm	while (i < end) {
3055231200Smm		ds->loop = i;
3056231200Smm		if (!lzx_br_read_ahead(strm, br, ds->pt.max_bits))
3057231200Smm			goto getdata;
3058231200Smm		rbits = lzx_br_bits(br, ds->pt.max_bits);
3059231200Smm		c = lzx_decode_huffman(&(ds->pt), rbits);
3060231200Smm		switch (c) {
3061231200Smm		case 17:/* several zero lengths, from 4 to 19. */
3062231200Smm			if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+4))
3063231200Smm				goto getdata;
3064231200Smm			lzx_br_consume(br, ds->pt.bitlen[c]);
3065231200Smm			same = lzx_br_bits(br, 4) + 4;
3066231200Smm			if (i + same > end)
3067231200Smm				return (-1);/* Invalid */
3068231200Smm			lzx_br_consume(br, 4);
3069231200Smm			for (j = 0; j < same; j++)
3070231200Smm				d->bitlen[i++] = 0;
3071231200Smm			break;
3072231200Smm		case 18:/* many zero lengths, from 20 to 51. */
3073231200Smm			if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+5))
3074231200Smm				goto getdata;
3075231200Smm			lzx_br_consume(br, ds->pt.bitlen[c]);
3076231200Smm			same = lzx_br_bits(br, 5) + 20;
3077231200Smm			if (i + same > end)
3078231200Smm				return (-1);/* Invalid */
3079231200Smm			lzx_br_consume(br, 5);
3080231200Smm			memset(d->bitlen + i, 0, same);
3081231200Smm			i += same;
3082231200Smm			break;
3083231200Smm		case 19:/* a few same lengths. */
3084231200Smm			if (!lzx_br_read_ahead(strm, br,
3085231200Smm			    ds->pt.bitlen[c]+1+ds->pt.max_bits))
3086231200Smm				goto getdata;
3087231200Smm			lzx_br_consume(br, ds->pt.bitlen[c]);
3088231200Smm			same = lzx_br_bits(br, 1) + 4;
3089231200Smm			if (i + same > end)
3090231200Smm				return (-1);
3091231200Smm			lzx_br_consume(br, 1);
3092231200Smm			rbits = lzx_br_bits(br, ds->pt.max_bits);
3093231200Smm			c = lzx_decode_huffman(&(ds->pt), rbits);
3094231200Smm			lzx_br_consume(br, ds->pt.bitlen[c]);
3095231200Smm			c = (d->bitlen[i] - c + 17) % 17;
3096231200Smm			if (c < 0)
3097231200Smm				return (-1);/* Invalid */
3098231200Smm			for (j = 0; j < same; j++)
3099231200Smm				d->bitlen[i++] = c;
3100231200Smm			d->freq[c] += same;
3101231200Smm			break;
3102231200Smm		default:
3103231200Smm			lzx_br_consume(br, ds->pt.bitlen[c]);
3104231200Smm			c = (d->bitlen[i] - c + 17) % 17;
3105231200Smm			if (c < 0)
3106231200Smm				return (-1);/* Invalid */
3107231200Smm			d->freq[c]++;
3108231200Smm			d->bitlen[i++] = c;
3109231200Smm			break;
3110231200Smm		}
3111231200Smm	}
3112231200Smm	ret = 1;
3113231200Smmgetdata:
3114231200Smm	ds->loop = i;
3115231200Smm	return (ret);
3116231200Smm}
3117231200Smm
3118231200Smmstatic int
3119231200Smmlzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
3120231200Smm{
3121231200Smm
3122231200Smm	if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
3123231200Smm		free(hf->bitlen);
3124231200Smm		hf->bitlen = calloc(len_size,  sizeof(hf->bitlen[0]));
3125231200Smm		if (hf->bitlen == NULL)
3126231200Smm			return (ARCHIVE_FATAL);
3127248616Smm		hf->len_size = (int)len_size;
3128231200Smm	} else
3129231200Smm		memset(hf->bitlen, 0, len_size *  sizeof(hf->bitlen[0]));
3130231200Smm	if (hf->tbl == NULL) {
3131318483Smm		hf->tbl = malloc(((size_t)1 << tbl_bits) * sizeof(hf->tbl[0]));
3132231200Smm		if (hf->tbl == NULL)
3133231200Smm			return (ARCHIVE_FATAL);
3134231200Smm		hf->tbl_bits = tbl_bits;
3135231200Smm	}
3136231200Smm	return (ARCHIVE_OK);
3137231200Smm}
3138231200Smm
3139231200Smmstatic void
3140231200Smmlzx_huffman_free(struct huffman *hf)
3141231200Smm{
3142231200Smm	free(hf->bitlen);
3143231200Smm	free(hf->tbl);
3144231200Smm}
3145231200Smm
3146231200Smm/*
3147231200Smm * Make a huffman coding table.
3148231200Smm */
3149231200Smmstatic int
3150231200Smmlzx_make_huffman_table(struct huffman *hf)
3151231200Smm{
3152231200Smm	uint16_t *tbl;
3153231200Smm	const unsigned char *bitlen;
3154231200Smm	int bitptn[17], weight[17];
3155231200Smm	int i, maxbits = 0, ptn, tbl_size, w;
3156318483Smm	int len_avail;
3157231200Smm
3158231200Smm	/*
3159231200Smm	 * Initialize bit patterns.
3160231200Smm	 */
3161231200Smm	ptn = 0;
3162231200Smm	for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
3163231200Smm		bitptn[i] = ptn;
3164231200Smm		weight[i] = w;
3165231200Smm		if (hf->freq[i]) {
3166231200Smm			ptn += hf->freq[i] * w;
3167231200Smm			maxbits = i;
3168231200Smm		}
3169231200Smm	}
3170231200Smm	if ((ptn & 0xffff) != 0 || maxbits > hf->tbl_bits)
3171231200Smm		return (0);/* Invalid */
3172231200Smm
3173231200Smm	hf->max_bits = maxbits;
3174231200Smm
3175231200Smm	/*
3176231200Smm	 * Cut out extra bits which we won't house in the table.
3177231200Smm	 * This preparation reduces the same calculation in the for-loop
3178231200Smm	 * making the table.
3179231200Smm	 */
3180231200Smm	if (maxbits < 16) {
3181231200Smm		int ebits = 16 - maxbits;
3182231200Smm		for (i = 1; i <= maxbits; i++) {
3183231200Smm			bitptn[i] >>= ebits;
3184231200Smm			weight[i] >>= ebits;
3185231200Smm		}
3186231200Smm	}
3187231200Smm
3188231200Smm	/*
3189231200Smm	 * Make the table.
3190231200Smm	 */
3191318483Smm	tbl_size = 1 << hf->tbl_bits;
3192231200Smm	tbl = hf->tbl;
3193231200Smm	bitlen = hf->bitlen;
3194231200Smm	len_avail = hf->len_size;
3195231200Smm	hf->tree_used = 0;
3196231200Smm	for (i = 0; i < len_avail; i++) {
3197231200Smm		uint16_t *p;
3198231200Smm		int len, cnt;
3199231200Smm
3200231200Smm		if (bitlen[i] == 0)
3201231200Smm			continue;
3202231200Smm		/* Get a bit pattern */
3203231200Smm		len = bitlen[i];
3204318483Smm		if (len > tbl_size)
3205318483Smm			return (0);
3206231200Smm		ptn = bitptn[len];
3207231200Smm		cnt = weight[len];
3208318483Smm		/* Calculate next bit pattern */
3209318483Smm		if ((bitptn[len] = ptn + cnt) > tbl_size)
3210318483Smm			return (0);/* Invalid */
3211318483Smm		/* Update the table */
3212318483Smm		p = &(tbl[ptn]);
3213318483Smm		while (--cnt >= 0)
3214318483Smm			p[cnt] = (uint16_t)i;
3215231200Smm	}
3216231200Smm	return (1);
3217231200Smm}
3218231200Smm
3219231200Smmstatic inline int
3220231200Smmlzx_decode_huffman(struct huffman *hf, unsigned rbits)
3221231200Smm{
3222231200Smm	int c;
3223318483Smm	c = hf->tbl[rbits];
3224231200Smm	if (c < hf->len_size)
3225231200Smm		return (c);
3226318483Smm	return (0);
3227231200Smm}
3228