1231200Smm/*-
2302001Smm * Copyright (c) 2008-2014 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
41231200Smm#include "archive.h"
42231200Smm#include "archive_entry.h"
43231200Smm#include "archive_entry_locale.h"
44231200Smm#include "archive_private.h"
45231200Smm#include "archive_read_private.h"
46231200Smm#include "archive_endian.h"
47231200Smm
48231200Smm
49231200Smm#define MAXMATCH		256	/* Maximum match length. */
50231200Smm#define MINMATCH		3	/* Minimum match length. */
51231200Smm/*
52231200Smm * Literal table format:
53231200Smm * +0              +256                      +510
54231200Smm * +---------------+-------------------------+
55231200Smm * | literal code  |       match length      |
56231200Smm * |   0 ... 255   |  MINMATCH ... MAXMATCH  |
57231200Smm * +---------------+-------------------------+
58231200Smm *  <---          LT_BITLEN_SIZE         --->
59231200Smm */
60231200Smm/* Literal table size. */
61231200Smm#define LT_BITLEN_SIZE		(UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1)
62231200Smm/* Position table size.
63231200Smm * Note: this used for both position table and pre literal table.*/
64231200Smm#define PT_BITLEN_SIZE		(3 + 16)
65231200Smm
66231200Smmstruct lzh_dec {
67231200Smm	/* Decoding status. */
68231200Smm	int     		 state;
69231200Smm
70231200Smm	/*
71231200Smm	 * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded
72231200Smm	 * data.
73231200Smm	 */
74231200Smm	int			 w_size;
75231200Smm	int			 w_mask;
76231200Smm	/* Window buffer, which is a loop buffer. */
77231200Smm	unsigned char		*w_buff;
78231200Smm	/* The insert position to the window. */
79231200Smm	int			 w_pos;
80231200Smm	/* The position where we can copy decoded code from the window. */
81231200Smm	int     		 copy_pos;
82231200Smm	/* The length how many bytes we can copy decoded code from
83231200Smm	 * the window. */
84231200Smm	int     		 copy_len;
85231200Smm
86231200Smm	/*
87231200Smm	 * Bit stream reader.
88231200Smm	 */
89231200Smm	struct lzh_br {
90231200Smm#define CACHE_TYPE		uint64_t
91231200Smm#define CACHE_BITS		(8 * sizeof(CACHE_TYPE))
92231200Smm	 	/* Cache buffer. */
93231200Smm		CACHE_TYPE	 cache_buffer;
94231200Smm		/* Indicates how many bits avail in cache_buffer. */
95231200Smm		int		 cache_avail;
96231200Smm	} br;
97231200Smm
98231200Smm	/*
99231200Smm	 * Huffman coding.
100231200Smm	 */
101231200Smm	struct huffman {
102231200Smm		int		 len_size;
103231200Smm		int		 len_avail;
104231200Smm		int		 len_bits;
105231200Smm		int		 freq[17];
106231200Smm		unsigned char	*bitlen;
107231200Smm
108231200Smm		/*
109231200Smm		 * Use a index table. It's faster than searching a huffman
110231200Smm		 * coding tree, which is a binary tree. But a use of a large
111231200Smm		 * index table causes L1 cache read miss many times.
112231200Smm		 */
113231200Smm#define HTBL_BITS	10
114231200Smm		int		 max_bits;
115231200Smm		int		 shift_bits;
116231200Smm		int		 tbl_bits;
117231200Smm		int		 tree_used;
118231200Smm		int		 tree_avail;
119231200Smm		/* Direct access table. */
120231200Smm		uint16_t	*tbl;
121231200Smm		/* Binary tree table for extra bits over the direct access. */
122231200Smm		struct htree_t {
123231200Smm			uint16_t left;
124231200Smm			uint16_t right;
125231200Smm		}		*tree;
126231200Smm	}			 lt, pt;
127231200Smm
128231200Smm	int			 blocks_avail;
129231200Smm	int			 pos_pt_len_size;
130231200Smm	int			 pos_pt_len_bits;
131231200Smm	int			 literal_pt_len_size;
132231200Smm	int			 literal_pt_len_bits;
133231200Smm	int			 reading_position;
134231200Smm	int			 loop;
135231200Smm	int			 error;
136231200Smm};
137231200Smm
138231200Smmstruct lzh_stream {
139231200Smm	const unsigned char	*next_in;
140302001Smm	int			 avail_in;
141231200Smm	int64_t			 total_in;
142302001Smm	const unsigned char	*ref_ptr;
143302001Smm	int			 avail_out;
144231200Smm	int64_t			 total_out;
145231200Smm	struct lzh_dec		*ds;
146231200Smm};
147231200Smm
148231200Smmstruct lha {
149231200Smm	/* entry_bytes_remaining is the number of bytes we expect.	    */
150231200Smm	int64_t                  entry_offset;
151231200Smm	int64_t                  entry_bytes_remaining;
152231200Smm	int64_t			 entry_unconsumed;
153231200Smm	uint16_t		 entry_crc_calculated;
154231200Smm
155231200Smm	size_t			 header_size;	/* header size		    */
156231200Smm	unsigned char		 level;		/* header level		    */
157231200Smm	char			 method[3];	/* compress type	    */
158231200Smm	int64_t			 compsize;	/* compressed data size	    */
159231200Smm	int64_t			 origsize;	/* original file size	    */
160231200Smm	int			 setflag;
161231200Smm#define BIRTHTIME_IS_SET	1
162231200Smm#define ATIME_IS_SET		2
163231200Smm#define UNIX_MODE_IS_SET	4
164231200Smm#define CRC_IS_SET		8
165231200Smm	time_t			 birthtime;
166231200Smm	long			 birthtime_tv_nsec;
167231200Smm	time_t			 mtime;
168231200Smm	long			 mtime_tv_nsec;
169231200Smm	time_t			 atime;
170231200Smm	long			 atime_tv_nsec;
171231200Smm	mode_t			 mode;
172231200Smm	int64_t			 uid;
173231200Smm	int64_t			 gid;
174231200Smm	struct archive_string 	 uname;
175231200Smm	struct archive_string 	 gname;
176231200Smm	uint16_t		 header_crc;
177231200Smm	uint16_t		 crc;
178358090Smm	/* dirname and filename could be in different codepages */
179358090Smm	struct archive_string_conv *sconv_dir;
180358090Smm	struct archive_string_conv *sconv_fname;
181231200Smm	struct archive_string_conv *opt_sconv;
182231200Smm
183231200Smm	struct archive_string 	 dirname;
184231200Smm	struct archive_string 	 filename;
185231200Smm	struct archive_wstring	 ws;
186231200Smm
187231200Smm	unsigned char		 dos_attr;
188231200Smm
189231200Smm	/* Flag to mark progress that an archive was read their first header.*/
190231200Smm	char			 found_first_header;
191231200Smm	/* Flag to mark that indicates an empty directory. */
192231200Smm	char			 directory;
193231200Smm
194231200Smm	/* Flags to mark progress of decompression. */
195231200Smm	char			 decompress_init;
196231200Smm	char			 end_of_entry;
197231200Smm	char			 end_of_entry_cleanup;
198231200Smm	char			 entry_is_compressed;
199231200Smm
200231200Smm	char			 format_name[64];
201231200Smm
202231200Smm	struct lzh_stream	 strm;
203231200Smm};
204231200Smm
205231200Smm/*
206231200Smm * LHA header common member offset.
207231200Smm */
208231200Smm#define H_METHOD_OFFSET	2	/* Compress type. */
209231200Smm#define H_ATTR_OFFSET	19	/* DOS attribute. */
210231200Smm#define H_LEVEL_OFFSET	20	/* Header Level.  */
211231200Smm#define H_SIZE		22	/* Minimum header size. */
212231200Smm
213231200Smmstatic int      archive_read_format_lha_bid(struct archive_read *, int);
214231200Smmstatic int      archive_read_format_lha_options(struct archive_read *,
215231200Smm		    const char *, const char *);
216231200Smmstatic int	archive_read_format_lha_read_header(struct archive_read *,
217231200Smm		    struct archive_entry *);
218231200Smmstatic int	archive_read_format_lha_read_data(struct archive_read *,
219231200Smm		    const void **, size_t *, int64_t *);
220231200Smmstatic int	archive_read_format_lha_read_data_skip(struct archive_read *);
221231200Smmstatic int	archive_read_format_lha_cleanup(struct archive_read *);
222231200Smm
223231200Smmstatic void	lha_replace_path_separator(struct lha *,
224231200Smm		    struct archive_entry *);
225231200Smmstatic int	lha_read_file_header_0(struct archive_read *, struct lha *);
226231200Smmstatic int	lha_read_file_header_1(struct archive_read *, struct lha *);
227231200Smmstatic int	lha_read_file_header_2(struct archive_read *, struct lha *);
228231200Smmstatic int	lha_read_file_header_3(struct archive_read *, struct lha *);
229231200Smmstatic int	lha_read_file_extended_header(struct archive_read *,
230231200Smm		    struct lha *, uint16_t *, int, size_t, size_t *);
231231200Smmstatic size_t	lha_check_header_format(const void *);
232231200Smmstatic int	lha_skip_sfx(struct archive_read *);
233231200Smmstatic time_t	lha_dos_time(const unsigned char *);
234231200Smmstatic time_t	lha_win_time(uint64_t, long *);
235231200Smmstatic unsigned char	lha_calcsum(unsigned char, const void *,
236248616Smm		    int, size_t);
237358090Smmstatic int	lha_parse_linkname(struct archive_wstring *,
238358090Smm		    struct archive_wstring *);
239231200Smmstatic int	lha_read_data_none(struct archive_read *, const void **,
240231200Smm		    size_t *, int64_t *);
241231200Smmstatic int	lha_read_data_lzh(struct archive_read *, const void **,
242231200Smm		    size_t *, int64_t *);
243302001Smmstatic void	lha_crc16_init(void);
244231200Smmstatic uint16_t lha_crc16(uint16_t, const void *, size_t);
245231200Smmstatic int	lzh_decode_init(struct lzh_stream *, const char *);
246231200Smmstatic void	lzh_decode_free(struct lzh_stream *);
247231200Smmstatic int	lzh_decode(struct lzh_stream *, int);
248231200Smmstatic int	lzh_br_fillup(struct lzh_stream *, struct lzh_br *);
249231200Smmstatic int	lzh_huffman_init(struct huffman *, size_t, int);
250231200Smmstatic void	lzh_huffman_free(struct huffman *);
251231200Smmstatic int	lzh_read_pt_bitlen(struct lzh_stream *, int start, int end);
252231200Smmstatic int	lzh_make_fake_table(struct huffman *, uint16_t);
253231200Smmstatic int	lzh_make_huffman_table(struct huffman *);
254232153Smmstatic inline int lzh_decode_huffman(struct huffman *, unsigned);
255231200Smmstatic int	lzh_decode_huffman_tree(struct huffman *, unsigned, int);
256231200Smm
257231200Smm
258231200Smmint
259231200Smmarchive_read_support_format_lha(struct archive *_a)
260231200Smm{
261231200Smm	struct archive_read *a = (struct archive_read *)_a;
262231200Smm	struct lha *lha;
263231200Smm	int r;
264231200Smm
265231200Smm	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
266231200Smm	    ARCHIVE_STATE_NEW, "archive_read_support_format_lha");
267231200Smm
268231200Smm	lha = (struct lha *)calloc(1, sizeof(*lha));
269231200Smm	if (lha == NULL) {
270231200Smm		archive_set_error(&a->archive, ENOMEM,
271231200Smm		    "Can't allocate lha data");
272231200Smm		return (ARCHIVE_FATAL);
273231200Smm	}
274231200Smm	archive_string_init(&lha->ws);
275231200Smm
276231200Smm	r = __archive_read_register_format(a,
277231200Smm	    lha,
278231200Smm	    "lha",
279231200Smm	    archive_read_format_lha_bid,
280231200Smm	    archive_read_format_lha_options,
281231200Smm	    archive_read_format_lha_read_header,
282231200Smm	    archive_read_format_lha_read_data,
283231200Smm	    archive_read_format_lha_read_data_skip,
284248616Smm	    NULL,
285302001Smm	    archive_read_format_lha_cleanup,
286302001Smm	    NULL,
287302001Smm	    NULL);
288231200Smm
289231200Smm	if (r != ARCHIVE_OK)
290231200Smm		free(lha);
291231200Smm	return (ARCHIVE_OK);
292231200Smm}
293231200Smm
294231200Smmstatic size_t
295231200Smmlha_check_header_format(const void *h)
296231200Smm{
297231200Smm	const unsigned char *p = h;
298231200Smm	size_t next_skip_bytes;
299231200Smm
300231200Smm	switch (p[H_METHOD_OFFSET+3]) {
301231200Smm	/*
302231200Smm	 * "-lh0-" ... "-lh7-" "-lhd-"
303231200Smm	 * "-lzs-" "-lz5-"
304231200Smm	 */
305231200Smm	case '0': case '1': case '2': case '3':
306231200Smm	case '4': case '5': case '6': case '7':
307231200Smm	case 'd':
308231200Smm	case 's':
309231200Smm		next_skip_bytes = 4;
310231200Smm
311231200Smm		/* b0 == 0 means the end of an LHa archive file.	*/
312231200Smm		if (p[0] == 0)
313231200Smm			break;
314231200Smm		if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l'
315231200Smm		    ||  p[H_METHOD_OFFSET+4] != '-')
316231200Smm			break;
317231200Smm
318231200Smm		if (p[H_METHOD_OFFSET+2] == 'h') {
319231200Smm			/* "-lh?-" */
320231200Smm			if (p[H_METHOD_OFFSET+3] == 's')
321231200Smm				break;
322231200Smm			if (p[H_LEVEL_OFFSET] == 0)
323231200Smm				return (0);
324231200Smm			if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20)
325231200Smm				return (0);
326231200Smm		}
327231200Smm		if (p[H_METHOD_OFFSET+2] == 'z') {
328231200Smm			/* LArc extensions: -lzs-,-lz4- and -lz5- */
329231200Smm			if (p[H_LEVEL_OFFSET] != 0)
330231200Smm				break;
331231200Smm			if (p[H_METHOD_OFFSET+3] == 's'
332231200Smm			    || p[H_METHOD_OFFSET+3] == '4'
333231200Smm			    || p[H_METHOD_OFFSET+3] == '5')
334231200Smm				return (0);
335231200Smm		}
336231200Smm		break;
337231200Smm	case 'h': next_skip_bytes = 1; break;
338231200Smm	case 'z': next_skip_bytes = 1; break;
339231200Smm	case 'l': next_skip_bytes = 2; break;
340231200Smm	case '-': next_skip_bytes = 3; break;
341231200Smm	default : next_skip_bytes = 4; break;
342231200Smm	}
343231200Smm
344231200Smm	return (next_skip_bytes);
345231200Smm}
346231200Smm
347231200Smmstatic int
348231200Smmarchive_read_format_lha_bid(struct archive_read *a, int best_bid)
349231200Smm{
350231200Smm	const char *p;
351231200Smm	const void *buff;
352231200Smm	ssize_t bytes_avail, offset, window;
353231200Smm	size_t next;
354231200Smm
355231200Smm	/* If there's already a better bid than we can ever
356231200Smm	   make, don't bother testing. */
357231200Smm	if (best_bid > 30)
358231200Smm		return (-1);
359231200Smm
360231200Smm	if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL)
361231200Smm		return (-1);
362231200Smm
363231200Smm	if (lha_check_header_format(p) == 0)
364231200Smm		return (30);
365231200Smm
366231200Smm	if (p[0] == 'M' && p[1] == 'Z') {
367231200Smm		/* PE file */
368231200Smm		offset = 0;
369231200Smm		window = 4096;
370231200Smm		while (offset < (1024 * 20)) {
371231200Smm			buff = __archive_read_ahead(a, offset + window,
372231200Smm			    &bytes_avail);
373231200Smm			if (buff == NULL) {
374231200Smm				/* Remaining bytes are less than window. */
375231200Smm				window >>= 1;
376231200Smm				if (window < (H_SIZE + 3))
377231200Smm					return (0);
378231200Smm				continue;
379231200Smm			}
380231200Smm			p = (const char *)buff + offset;
381231200Smm			while (p + H_SIZE < (const char *)buff + bytes_avail) {
382231200Smm				if ((next = lha_check_header_format(p)) == 0)
383231200Smm					return (30);
384231200Smm				p += next;
385231200Smm			}
386231200Smm			offset = p - (const char *)buff;
387231200Smm		}
388231200Smm	}
389231200Smm	return (0);
390231200Smm}
391231200Smm
392231200Smmstatic int
393231200Smmarchive_read_format_lha_options(struct archive_read *a,
394231200Smm    const char *key, const char *val)
395231200Smm{
396231200Smm	struct lha *lha;
397231200Smm	int ret = ARCHIVE_FAILED;
398231200Smm
399231200Smm	lha = (struct lha *)(a->format->data);
400231200Smm	if (strcmp(key, "hdrcharset")  == 0) {
401231200Smm		if (val == NULL || val[0] == 0)
402231200Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
403231200Smm			    "lha: hdrcharset option needs a character-set name");
404231200Smm		else {
405231200Smm			lha->opt_sconv =
406231200Smm			    archive_string_conversion_from_charset(
407231200Smm				&a->archive, val, 0);
408231200Smm			if (lha->opt_sconv != NULL)
409231200Smm				ret = ARCHIVE_OK;
410231200Smm			else
411231200Smm				ret = ARCHIVE_FATAL;
412231200Smm		}
413232153Smm		return (ret);
414232153Smm	}
415231200Smm
416232153Smm	/* Note: The "warn" return is just to inform the options
417232153Smm	 * supervisor that we didn't handle it.  It will generate
418232153Smm	 * a suitable error if no one used this option. */
419232153Smm	return (ARCHIVE_WARN);
420231200Smm}
421231200Smm
422231200Smmstatic int
423231200Smmlha_skip_sfx(struct archive_read *a)
424231200Smm{
425231200Smm	const void *h;
426231200Smm	const char *p, *q;
427231200Smm	size_t next, skip;
428231200Smm	ssize_t bytes, window;
429231200Smm
430231200Smm	window = 4096;
431231200Smm	for (;;) {
432231200Smm		h = __archive_read_ahead(a, window, &bytes);
433231200Smm		if (h == NULL) {
434231200Smm			/* Remaining bytes are less than window. */
435231200Smm			window >>= 1;
436231200Smm			if (window < (H_SIZE + 3))
437231200Smm				goto fatal;
438231200Smm			continue;
439231200Smm		}
440231200Smm		if (bytes < H_SIZE)
441231200Smm			goto fatal;
442231200Smm		p = h;
443231200Smm		q = p + bytes;
444231200Smm
445231200Smm		/*
446231200Smm		 * Scan ahead until we find something that looks
447231200Smm		 * like the lha header.
448231200Smm		 */
449231200Smm		while (p + H_SIZE < q) {
450231200Smm			if ((next = lha_check_header_format(p)) == 0) {
451231200Smm				skip = p - (const char *)h;
452231200Smm				__archive_read_consume(a, skip);
453231200Smm				return (ARCHIVE_OK);
454231200Smm			}
455231200Smm			p += next;
456231200Smm		}
457231200Smm		skip = p - (const char *)h;
458231200Smm		__archive_read_consume(a, skip);
459231200Smm	}
460231200Smmfatal:
461231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
462231200Smm	    "Couldn't find out LHa header");
463231200Smm	return (ARCHIVE_FATAL);
464231200Smm}
465231200Smm
466231200Smmstatic int
467231200Smmtruncated_error(struct archive_read *a)
468231200Smm{
469231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
470231200Smm	    "Truncated LHa header");
471231200Smm	return (ARCHIVE_FATAL);
472231200Smm}
473231200Smm
474231200Smmstatic int
475231200Smmarchive_read_format_lha_read_header(struct archive_read *a,
476231200Smm    struct archive_entry *entry)
477231200Smm{
478358090Smm	struct archive_wstring linkname;
479358090Smm	struct archive_wstring pathname;
480231200Smm	struct lha *lha;
481231200Smm	const unsigned char *p;
482231200Smm	const char *signature;
483231200Smm	int err;
484358090Smm	struct archive_mstring conv_buffer;
485358090Smm	const wchar_t *conv_buffer_p;
486358090Smm
487302001Smm	lha_crc16_init();
488302001Smm
489231200Smm	a->archive.archive_format = ARCHIVE_FORMAT_LHA;
490231200Smm	if (a->archive.archive_format_name == NULL)
491231200Smm		a->archive.archive_format_name = "lha";
492231200Smm
493231200Smm	lha = (struct lha *)(a->format->data);
494231200Smm	lha->decompress_init = 0;
495231200Smm	lha->end_of_entry = 0;
496231200Smm	lha->end_of_entry_cleanup = 0;
497231200Smm	lha->entry_unconsumed = 0;
498231200Smm
499231200Smm	if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) {
500231200Smm		/*
501231200Smm		 * LHa archiver added 0 to the tail of its archive file as
502231200Smm		 * the mark of the end of the archive.
503231200Smm		 */
504231200Smm		signature = __archive_read_ahead(a, sizeof(signature[0]), NULL);
505231200Smm		if (signature == NULL || signature[0] == 0)
506231200Smm			return (ARCHIVE_EOF);
507231200Smm		return (truncated_error(a));
508231200Smm	}
509231200Smm
510231200Smm	signature = (const char *)p;
511231200Smm	if (lha->found_first_header == 0 &&
512231200Smm	    signature[0] == 'M' && signature[1] == 'Z') {
513231200Smm                /* This is an executable?  Must be self-extracting... 	*/
514231200Smm		err = lha_skip_sfx(a);
515231200Smm		if (err < ARCHIVE_WARN)
516231200Smm			return (err);
517231200Smm
518231200Smm		if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
519231200Smm			return (truncated_error(a));
520231200Smm		signature = (const char *)p;
521231200Smm	}
522231200Smm	/* signature[0] == 0 means the end of an LHa archive file. */
523231200Smm	if (signature[0] == 0)
524231200Smm		return (ARCHIVE_EOF);
525231200Smm
526231200Smm	/*
527231200Smm	 * Check the header format and method type.
528231200Smm	 */
529231200Smm	if (lha_check_header_format(p) != 0) {
530231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
531231200Smm		    "Bad LHa file");
532231200Smm		return (ARCHIVE_FATAL);
533231200Smm	}
534231200Smm
535231200Smm	/* We've found the first header. */
536231200Smm	lha->found_first_header = 1;
537231200Smm	/* Set a default value and common data */
538231200Smm	lha->header_size = 0;
539231200Smm	lha->level = p[H_LEVEL_OFFSET];
540231200Smm	lha->method[0] = p[H_METHOD_OFFSET+1];
541231200Smm	lha->method[1] = p[H_METHOD_OFFSET+2];
542231200Smm	lha->method[2] = p[H_METHOD_OFFSET+3];
543231200Smm	if (memcmp(lha->method, "lhd", 3) == 0)
544231200Smm		lha->directory = 1;
545231200Smm	else
546231200Smm		lha->directory = 0;
547231200Smm	if (memcmp(lha->method, "lh0", 3) == 0 ||
548231200Smm	    memcmp(lha->method, "lz4", 3) == 0)
549231200Smm		lha->entry_is_compressed = 0;
550231200Smm	else
551231200Smm		lha->entry_is_compressed = 1;
552231200Smm
553231200Smm	lha->compsize = 0;
554231200Smm	lha->origsize = 0;
555231200Smm	lha->setflag = 0;
556231200Smm	lha->birthtime = 0;
557231200Smm	lha->birthtime_tv_nsec = 0;
558231200Smm	lha->mtime = 0;
559231200Smm	lha->mtime_tv_nsec = 0;
560231200Smm	lha->atime = 0;
561231200Smm	lha->atime_tv_nsec = 0;
562231200Smm	lha->mode = (lha->directory)? 0777 : 0666;
563231200Smm	lha->uid = 0;
564231200Smm	lha->gid = 0;
565231200Smm	archive_string_empty(&lha->dirname);
566231200Smm	archive_string_empty(&lha->filename);
567231200Smm	lha->dos_attr = 0;
568358090Smm	if (lha->opt_sconv != NULL) {
569358090Smm		lha->sconv_dir = lha->opt_sconv;
570358090Smm		lha->sconv_fname = lha->opt_sconv;
571358090Smm	} else {
572358090Smm		lha->sconv_dir = NULL;
573358090Smm		lha->sconv_fname = NULL;
574358090Smm	}
575231200Smm
576231200Smm	switch (p[H_LEVEL_OFFSET]) {
577231200Smm	case 0:
578231200Smm		err = lha_read_file_header_0(a, lha);
579231200Smm		break;
580231200Smm	case 1:
581231200Smm		err = lha_read_file_header_1(a, lha);
582231200Smm		break;
583231200Smm	case 2:
584231200Smm		err = lha_read_file_header_2(a, lha);
585231200Smm		break;
586231200Smm	case 3:
587231200Smm		err = lha_read_file_header_3(a, lha);
588231200Smm		break;
589231200Smm	default:
590231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
591231200Smm		    "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]);
592231200Smm		err = ARCHIVE_FATAL;
593231200Smm		break;
594231200Smm	}
595231200Smm	if (err < ARCHIVE_WARN)
596231200Smm		return (err);
597231200Smm
598231200Smm
599231200Smm	if (!lha->directory && archive_strlen(&lha->filename) == 0)
600231200Smm		/* The filename has not been set */
601231200Smm		return (truncated_error(a));
602231200Smm
603231200Smm	/*
604358090Smm	 * Make a pathname from a dirname and a filename, after converting to Unicode.
605358090Smm	 * This is because codepages might differ between dirname and filename.
606358090Smm	*/
607231200Smm	archive_string_init(&pathname);
608231200Smm	archive_string_init(&linkname);
609358090Smm	archive_string_init(&conv_buffer.aes_mbs);
610358090Smm	archive_string_init(&conv_buffer.aes_mbs_in_locale);
611358090Smm	archive_string_init(&conv_buffer.aes_utf8);
612358090Smm	archive_string_init(&conv_buffer.aes_wcs);
613358090Smm	if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
614358090Smm		archive_set_error(&a->archive,
615358090Smm			ARCHIVE_ERRNO_FILE_FORMAT,
616358090Smm			"Pathname cannot be converted "
617358090Smm			"from %s to Unicode.",
618358090Smm			archive_string_conversion_charset_name(lha->sconv_dir));
619358090Smm		err = ARCHIVE_FATAL;
620358090Smm	} else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
621358090Smm		err = ARCHIVE_FATAL;
622358090Smm	if (err == ARCHIVE_FATAL) {
623358090Smm		archive_mstring_clean(&conv_buffer);
624358090Smm		archive_wstring_free(&pathname);
625358090Smm		archive_wstring_free(&linkname);
626358090Smm		return (err);
627358090Smm	}
628358090Smm	archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
629231200Smm
630358090Smm	archive_string_empty(&conv_buffer.aes_mbs);
631358090Smm	archive_string_empty(&conv_buffer.aes_mbs_in_locale);
632358090Smm	archive_string_empty(&conv_buffer.aes_utf8);
633358090Smm	archive_wstring_empty(&conv_buffer.aes_wcs);
634358090Smm	if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
635358090Smm		archive_set_error(&a->archive,
636358090Smm			ARCHIVE_ERRNO_FILE_FORMAT,
637358090Smm			"Pathname cannot be converted "
638358090Smm			"from %s to Unicode.",
639358090Smm			archive_string_conversion_charset_name(lha->sconv_fname));
640358090Smm		err = ARCHIVE_FATAL;
641358090Smm	}
642358090Smm	else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
643358090Smm		err = ARCHIVE_FATAL;
644358090Smm	if (err == ARCHIVE_FATAL) {
645358090Smm		archive_mstring_clean(&conv_buffer);
646358090Smm		archive_wstring_free(&pathname);
647358090Smm		archive_wstring_free(&linkname);
648358090Smm		return (err);
649358090Smm	}
650358090Smm	archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
651358090Smm	archive_mstring_clean(&conv_buffer);
652358090Smm
653231200Smm	if ((lha->mode & AE_IFMT) == AE_IFLNK) {
654231200Smm		/*
655231200Smm	 	 * Extract the symlink-name if it's included in the pathname.
656231200Smm	 	 */
657231200Smm		if (!lha_parse_linkname(&linkname, &pathname)) {
658231200Smm			/* We couldn't get the symlink-name. */
659231200Smm			archive_set_error(&a->archive,
660231200Smm		    	    ARCHIVE_ERRNO_FILE_FORMAT,
661231200Smm			    "Unknown symlink-name");
662358090Smm			archive_wstring_free(&pathname);
663358090Smm			archive_wstring_free(&linkname);
664231200Smm			return (ARCHIVE_FAILED);
665231200Smm		}
666231200Smm	} else {
667231200Smm		/*
668231200Smm		 * Make sure a file-type is set.
669231200Smm		 * The mode has been overridden if it is in the extended data.
670231200Smm		 */
671231200Smm		lha->mode = (lha->mode & ~AE_IFMT) |
672231200Smm		    ((lha->directory)? AE_IFDIR: AE_IFREG);
673231200Smm	}
674231200Smm	if ((lha->setflag & UNIX_MODE_IS_SET) == 0 &&
675231200Smm	    (lha->dos_attr & 1) != 0)
676231200Smm		lha->mode &= ~(0222);/* read only. */
677231200Smm
678231200Smm	/*
679231200Smm	 * Set basic file parameters.
680231200Smm	 */
681358090Smm	archive_entry_copy_pathname_w(entry, pathname.s);
682358090Smm	archive_wstring_free(&pathname);
683231200Smm	if (archive_strlen(&linkname) > 0) {
684358090Smm		archive_entry_copy_symlink_w(entry, linkname.s);
685231200Smm	} else
686231200Smm		archive_entry_set_symlink(entry, NULL);
687358090Smm	archive_wstring_free(&linkname);
688231200Smm	/*
689231200Smm	 * When a header level is 0, there is a possibility that
690231200Smm	 * a pathname and a symlink has '\' character, a directory
691231200Smm	 * separator in DOS/Windows. So we should convert it to '/'.
692231200Smm	 */
693231200Smm	if (p[H_LEVEL_OFFSET] == 0)
694231200Smm		lha_replace_path_separator(lha, entry);
695231200Smm
696231200Smm	archive_entry_set_mode(entry, lha->mode);
697231200Smm	archive_entry_set_uid(entry, lha->uid);
698231200Smm	archive_entry_set_gid(entry, lha->gid);
699231200Smm	if (archive_strlen(&lha->uname) > 0)
700231200Smm		archive_entry_set_uname(entry, lha->uname.s);
701231200Smm	if (archive_strlen(&lha->gname) > 0)
702231200Smm		archive_entry_set_gname(entry, lha->gname.s);
703231200Smm	if (lha->setflag & BIRTHTIME_IS_SET) {
704231200Smm		archive_entry_set_birthtime(entry, lha->birthtime,
705231200Smm		    lha->birthtime_tv_nsec);
706231200Smm		archive_entry_set_ctime(entry, lha->birthtime,
707231200Smm		    lha->birthtime_tv_nsec);
708231200Smm	} else {
709231200Smm		archive_entry_unset_birthtime(entry);
710231200Smm		archive_entry_unset_ctime(entry);
711231200Smm	}
712231200Smm	archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec);
713231200Smm	if (lha->setflag & ATIME_IS_SET)
714231200Smm		archive_entry_set_atime(entry, lha->atime,
715231200Smm		    lha->atime_tv_nsec);
716231200Smm	else
717231200Smm		archive_entry_unset_atime(entry);
718231200Smm	if (lha->directory || archive_entry_symlink(entry) != NULL)
719231200Smm		archive_entry_unset_size(entry);
720231200Smm	else
721231200Smm		archive_entry_set_size(entry, lha->origsize);
722231200Smm
723231200Smm	/*
724231200Smm	 * Prepare variables used to read a file content.
725231200Smm	 */
726231200Smm	lha->entry_bytes_remaining = lha->compsize;
727337352Smm	if (lha->entry_bytes_remaining < 0) {
728337352Smm		archive_set_error(&a->archive,
729337352Smm		    ARCHIVE_ERRNO_FILE_FORMAT,
730337352Smm		    "Invalid LHa entry size");
731337352Smm		return (ARCHIVE_FATAL);
732337352Smm	}
733231200Smm	lha->entry_offset = 0;
734231200Smm	lha->entry_crc_calculated = 0;
735231200Smm
736231200Smm	/*
737231200Smm	 * This file does not have a content.
738231200Smm	 */
739231200Smm	if (lha->directory || lha->compsize == 0)
740231200Smm		lha->end_of_entry = 1;
741231200Smm
742231200Smm	sprintf(lha->format_name, "lha -%c%c%c-",
743231200Smm	    lha->method[0], lha->method[1], lha->method[2]);
744231200Smm	a->archive.archive_format_name = lha->format_name;
745231200Smm
746231200Smm	return (err);
747231200Smm}
748231200Smm
749231200Smm/*
750231200Smm * Replace a DOS path separator '\' by a character '/'.
751231200Smm * Some multi-byte character set have  a character '\' in its second byte.
752231200Smm */
753231200Smmstatic void
754231200Smmlha_replace_path_separator(struct lha *lha, struct archive_entry *entry)
755231200Smm{
756231200Smm	const wchar_t *wp;
757231200Smm	size_t i;
758231200Smm
759231200Smm	if ((wp = archive_entry_pathname_w(entry)) != NULL) {
760231200Smm		archive_wstrcpy(&(lha->ws), wp);
761231200Smm		for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
762231200Smm			if (lha->ws.s[i] == L'\\')
763231200Smm				lha->ws.s[i] = L'/';
764231200Smm		}
765231200Smm		archive_entry_copy_pathname_w(entry, lha->ws.s);
766231200Smm	}
767231200Smm
768231200Smm	if ((wp = archive_entry_symlink_w(entry)) != NULL) {
769231200Smm		archive_wstrcpy(&(lha->ws), wp);
770231200Smm		for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
771231200Smm			if (lha->ws.s[i] == L'\\')
772231200Smm				lha->ws.s[i] = L'/';
773231200Smm		}
774231200Smm		archive_entry_copy_symlink_w(entry, lha->ws.s);
775231200Smm	}
776231200Smm}
777231200Smm
778231200Smm/*
779231200Smm * Header 0 format
780231200Smm *
781231200Smm * +0              +1         +2               +7                  +11
782231200Smm * +---------------+----------+----------------+-------------------+
783231200Smm * |header size(*1)|header sum|compression type|compressed size(*2)|
784231200Smm * +---------------+----------+----------------+-------------------+
785231200Smm *                             <---------------------(*1)----------*
786231200Smm *
787231200Smm * +11               +15       +17       +19            +20              +21
788231200Smm * +-----------------+---------+---------+--------------+----------------+
789231200Smm * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)|
790231200Smm * +-----------------+---------+---------+--------------+----------------+
791231200Smm * *--------------------------------(*1)---------------------------------*
792231200Smm *
793231200Smm * +21             +22       +22+(*3)   +22+(*3)+2       +22+(*3)+2+(*4)
794231200Smm * +---------------+---------+----------+----------------+------------------+
795231200Smm * |name length(*3)|file name|file CRC16|extra header(*4)|  compressed data |
796231200Smm * +---------------+---------+----------+----------------+------------------+
797231200Smm *                  <--(*3)->                             <------(*2)------>
798231200Smm * *----------------------(*1)-------------------------->
799231200Smm *
800231200Smm */
801231200Smm#define H0_HEADER_SIZE_OFFSET	0
802231200Smm#define H0_HEADER_SUM_OFFSET	1
803231200Smm#define H0_COMP_SIZE_OFFSET	7
804231200Smm#define H0_ORIG_SIZE_OFFSET	11
805231200Smm#define H0_DOS_TIME_OFFSET	15
806231200Smm#define H0_NAME_LEN_OFFSET	21
807231200Smm#define H0_FILE_NAME_OFFSET	22
808231200Smm#define H0_FIXED_SIZE		24
809231200Smmstatic int
810231200Smmlha_read_file_header_0(struct archive_read *a, struct lha *lha)
811231200Smm{
812231200Smm	const unsigned char *p;
813231200Smm	int extdsize, namelen;
814231200Smm	unsigned char headersum, sum_calculated;
815231200Smm
816231200Smm	if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL)
817231200Smm		return (truncated_error(a));
818231200Smm	lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2;
819231200Smm	headersum = p[H0_HEADER_SUM_OFFSET];
820231200Smm	lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET);
821231200Smm	lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET);
822231200Smm	lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET);
823231200Smm	namelen = p[H0_NAME_LEN_OFFSET];
824231200Smm	extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen;
825231200Smm	if ((namelen > 221 || extdsize < 0) && extdsize != -2) {
826231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
827231200Smm		    "Invalid LHa header");
828231200Smm		return (ARCHIVE_FATAL);
829231200Smm	}
830231200Smm	if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
831231200Smm		return (truncated_error(a));
832231200Smm
833231200Smm	archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
834231200Smm	/* When extdsize == -2, A CRC16 value is not present in the header. */
835231200Smm	if (extdsize >= 0) {
836231200Smm		lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
837231200Smm		lha->setflag |= CRC_IS_SET;
838231200Smm	}
839231200Smm	sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
840231200Smm
841231200Smm	/* Read an extended header */
842231200Smm	if (extdsize > 0) {
843231200Smm		/* This extended data is set by 'LHa for UNIX' only.
844231200Smm		 * Maybe fixed size.
845231200Smm		 */
846231200Smm		p += H0_FILE_NAME_OFFSET + namelen + 2;
847231200Smm		if (p[0] == 'U' && extdsize == 12) {
848231200Smm			/* p[1] is a minor version. */
849231200Smm			lha->mtime = archive_le32dec(&p[2]);
850231200Smm			lha->mode = archive_le16dec(&p[6]);
851231200Smm			lha->uid = archive_le16dec(&p[8]);
852231200Smm			lha->gid = archive_le16dec(&p[10]);
853231200Smm			lha->setflag |= UNIX_MODE_IS_SET;
854231200Smm		}
855231200Smm	}
856231200Smm	__archive_read_consume(a, lha->header_size);
857231200Smm
858231200Smm	if (sum_calculated != headersum) {
859231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
860231200Smm		    "LHa header sum error");
861231200Smm		return (ARCHIVE_FATAL);
862231200Smm	}
863231200Smm
864231200Smm	return (ARCHIVE_OK);
865231200Smm}
866231200Smm
867231200Smm/*
868231200Smm * Header 1 format
869231200Smm *
870231200Smm * +0              +1         +2               +7            +11
871231200Smm * +---------------+----------+----------------+-------------+
872231200Smm * |header size(*1)|header sum|compression type|skip size(*2)|
873231200Smm * +---------------+----------+----------------+-------------+
874231200Smm *                             <---------------(*1)----------*
875231200Smm *
876231200Smm * +11               +15       +17       +19            +20              +21
877231200Smm * +-----------------+---------+---------+--------------+----------------+
878231200Smm * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)|
879231200Smm * +-----------------+---------+---------+--------------+----------------+
880231200Smm * *-------------------------------(*1)----------------------------------*
881231200Smm *
882231200Smm * +21             +22       +22+(*3)   +22+(*3)+2  +22+(*3)+3  +22+(*3)+3+(*4)
883231200Smm * +---------------+---------+----------+-----------+-----------+
884231200Smm * |name length(*3)|file name|file CRC16|  creator  |padding(*4)|
885231200Smm * +---------------+---------+----------+-----------+-----------+
886231200Smm *                  <--(*3)->
887231200Smm * *----------------------------(*1)----------------------------*
888231200Smm *
889231200Smm * +22+(*3)+3+(*4)  +22+(*3)+3+(*4)+2     +22+(*3)+3+(*4)+2+(*5)
890231200Smm * +----------------+---------------------+------------------------+
891231200Smm * |next header size| extended header(*5) |     compressed data    |
892231200Smm * +----------------+---------------------+------------------------+
893231200Smm * *------(*1)-----> <--------------------(*2)-------------------->
894231200Smm */
895231200Smm#define H1_HEADER_SIZE_OFFSET	0
896231200Smm#define H1_HEADER_SUM_OFFSET	1
897231200Smm#define H1_COMP_SIZE_OFFSET	7
898231200Smm#define H1_ORIG_SIZE_OFFSET	11
899231200Smm#define H1_DOS_TIME_OFFSET	15
900231200Smm#define H1_NAME_LEN_OFFSET	21
901231200Smm#define H1_FILE_NAME_OFFSET	22
902231200Smm#define H1_FIXED_SIZE		27
903231200Smmstatic int
904231200Smmlha_read_file_header_1(struct archive_read *a, struct lha *lha)
905231200Smm{
906231200Smm	const unsigned char *p;
907231200Smm	size_t extdsize;
908231200Smm	int i, err, err2;
909231200Smm	int namelen, padding;
910231200Smm	unsigned char headersum, sum_calculated;
911231200Smm
912231200Smm	err = ARCHIVE_OK;
913231200Smm
914231200Smm	if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL)
915231200Smm		return (truncated_error(a));
916231200Smm
917231200Smm	lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2;
918231200Smm	headersum = p[H1_HEADER_SUM_OFFSET];
919231200Smm	/* Note: An extended header size is included in a compsize. */
920231200Smm	lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET);
921231200Smm	lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET);
922231200Smm	lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET);
923231200Smm	namelen = p[H1_NAME_LEN_OFFSET];
924231200Smm	/* Calculate a padding size. The result will be normally 0 only(?) */
925231200Smm	padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen;
926231200Smm
927231200Smm	if (namelen > 230 || padding < 0)
928231200Smm		goto invalid;
929231200Smm
930231200Smm	if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
931231200Smm		return (truncated_error(a));
932231200Smm
933231200Smm	for (i = 0; i < namelen; i++) {
934231200Smm		if (p[i + H1_FILE_NAME_OFFSET] == 0xff)
935231200Smm			goto invalid;/* Invalid filename. */
936231200Smm	}
937231200Smm	archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen);
938231200Smm	lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen);
939231200Smm	lha->setflag |= CRC_IS_SET;
940231200Smm
941231200Smm	sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
942231200Smm	/* Consume used bytes but not include `next header size' data
943231200Smm	 * since it will be consumed in lha_read_file_extended_header(). */
944231200Smm	__archive_read_consume(a, lha->header_size - 2);
945231200Smm
946231200Smm	/* Read extended headers */
947231200Smm	err2 = lha_read_file_extended_header(a, lha, NULL, 2,
948238856Smm	    (size_t)(lha->compsize + 2), &extdsize);
949231200Smm	if (err2 < ARCHIVE_WARN)
950231200Smm		return (err2);
951231200Smm	if (err2 < err)
952231200Smm		err = err2;
953231200Smm	/* Get a real compressed file size. */
954231200Smm	lha->compsize -= extdsize - 2;
955231200Smm
956313571Smm	if (lha->compsize < 0)
957313571Smm		goto invalid;	/* Invalid compressed file size */
958313571Smm
959231200Smm	if (sum_calculated != headersum) {
960231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
961231200Smm		    "LHa header sum error");
962231200Smm		return (ARCHIVE_FATAL);
963231200Smm	}
964231200Smm	return (err);
965231200Smminvalid:
966231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
967231200Smm	    "Invalid LHa header");
968231200Smm	return (ARCHIVE_FATAL);
969231200Smm}
970231200Smm
971231200Smm/*
972231200Smm * Header 2 format
973231200Smm *
974231200Smm * +0              +2               +7                  +11               +15
975231200Smm * +---------------+----------------+-------------------+-----------------+
976231200Smm * |header size(*1)|compression type|compressed size(*2)|uncompressed size|
977231200Smm * +---------------+----------------+-------------------+-----------------+
978231200Smm *  <--------------------------------(*1)---------------------------------*
979231200Smm *
980231200Smm * +15               +19          +20              +21        +23         +24
981231200Smm * +-----------------+------------+----------------+----------+-----------+
982231200Smm * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16|  creator  |
983231200Smm * +-----------------+------------+----------------+----------+-----------+
984231200Smm * *---------------------------------(*1)---------------------------------*
985231200Smm *
986231200Smm * +24              +26                 +26+(*3)      +26+(*3)+(*4)
987231200Smm * +----------------+-------------------+-------------+-------------------+
988231200Smm * |next header size|extended header(*3)| padding(*4) |  compressed data  |
989231200Smm * +----------------+-------------------+-------------+-------------------+
990231200Smm * *--------------------------(*1)-------------------> <------(*2)------->
991231200Smm *
992231200Smm */
993231200Smm#define H2_HEADER_SIZE_OFFSET	0
994231200Smm#define H2_COMP_SIZE_OFFSET	7
995231200Smm#define H2_ORIG_SIZE_OFFSET	11
996231200Smm#define H2_TIME_OFFSET		15
997231200Smm#define H2_CRC_OFFSET		21
998231200Smm#define H2_FIXED_SIZE		24
999231200Smmstatic int
1000231200Smmlha_read_file_header_2(struct archive_read *a, struct lha *lha)
1001231200Smm{
1002231200Smm	const unsigned char *p;
1003231200Smm	size_t extdsize;
1004231200Smm	int err, padding;
1005231200Smm	uint16_t header_crc;
1006231200Smm
1007231200Smm	if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL)
1008231200Smm		return (truncated_error(a));
1009231200Smm
1010231200Smm	lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET);
1011231200Smm	lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET);
1012231200Smm	lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET);
1013231200Smm	lha->mtime = archive_le32dec(p + H2_TIME_OFFSET);
1014231200Smm	lha->crc = archive_le16dec(p + H2_CRC_OFFSET);
1015231200Smm	lha->setflag |= CRC_IS_SET;
1016231200Smm
1017231200Smm	if (lha->header_size < H2_FIXED_SIZE) {
1018231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1019231200Smm		    "Invalid LHa header size");
1020231200Smm		return (ARCHIVE_FATAL);
1021231200Smm	}
1022231200Smm
1023231200Smm	header_crc = lha_crc16(0, p, H2_FIXED_SIZE);
1024231200Smm	__archive_read_consume(a, H2_FIXED_SIZE);
1025231200Smm
1026231200Smm	/* Read extended headers */
1027231200Smm	err = lha_read_file_extended_header(a, lha, &header_crc, 2,
1028231200Smm		  lha->header_size - H2_FIXED_SIZE, &extdsize);
1029231200Smm	if (err < ARCHIVE_WARN)
1030231200Smm		return (err);
1031231200Smm
1032231200Smm	/* Calculate a padding size. The result will be normally 0 or 1. */
1033231200Smm	padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize);
1034231200Smm	if (padding > 0) {
1035231200Smm		if ((p = __archive_read_ahead(a, padding, NULL)) == NULL)
1036231200Smm			return (truncated_error(a));
1037231200Smm		header_crc = lha_crc16(header_crc, p, padding);
1038231200Smm		__archive_read_consume(a, padding);
1039231200Smm	}
1040231200Smm
1041231200Smm	if (header_crc != lha->header_crc) {
1042231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1043231200Smm		    "LHa header CRC error");
1044231200Smm		return (ARCHIVE_FATAL);
1045231200Smm	}
1046231200Smm	return (err);
1047231200Smm}
1048231200Smm
1049231200Smm/*
1050231200Smm * Header 3 format
1051231200Smm *
1052231200Smm * +0           +2               +7                  +11               +15
1053231200Smm * +------------+----------------+-------------------+-----------------+
1054231200Smm * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size|
1055231200Smm * +------------+----------------+-------------------+-----------------+
1056231200Smm *  <-------------------------------(*1)-------------------------------*
1057231200Smm *
1058231200Smm * +15               +19          +20              +21        +23         +24
1059231200Smm * +-----------------+------------+----------------+----------+-----------+
1060231200Smm * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16|  creator  |
1061231200Smm * +-----------------+------------+----------------+----------+-----------+
1062231200Smm * *--------------------------------(*1)----------------------------------*
1063231200Smm *
1064231200Smm * +24             +28              +32                 +32+(*3)
1065231200Smm * +---------------+----------------+-------------------+-----------------+
1066231200Smm * |header size(*1)|next header size|extended header(*3)| compressed data |
1067231200Smm * +---------------+----------------+-------------------+-----------------+
1068231200Smm * *------------------------(*1)-----------------------> <------(*2)----->
1069231200Smm *
1070231200Smm */
1071231200Smm#define H3_FIELD_LEN_OFFSET	0
1072231200Smm#define H3_COMP_SIZE_OFFSET	7
1073231200Smm#define H3_ORIG_SIZE_OFFSET	11
1074231200Smm#define H3_TIME_OFFSET		15
1075231200Smm#define H3_CRC_OFFSET		21
1076231200Smm#define H3_HEADER_SIZE_OFFSET	24
1077231200Smm#define H3_FIXED_SIZE		28
1078231200Smmstatic int
1079231200Smmlha_read_file_header_3(struct archive_read *a, struct lha *lha)
1080231200Smm{
1081231200Smm	const unsigned char *p;
1082231200Smm	size_t extdsize;
1083231200Smm	int err;
1084231200Smm	uint16_t header_crc;
1085231200Smm
1086231200Smm	if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL)
1087231200Smm		return (truncated_error(a));
1088231200Smm
1089231200Smm	if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4)
1090231200Smm		goto invalid;
1091231200Smm	lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET);
1092231200Smm	lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET);
1093231200Smm	lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET);
1094231200Smm	lha->mtime = archive_le32dec(p + H3_TIME_OFFSET);
1095231200Smm	lha->crc = archive_le16dec(p + H3_CRC_OFFSET);
1096231200Smm	lha->setflag |= CRC_IS_SET;
1097231200Smm
1098231200Smm	if (lha->header_size < H3_FIXED_SIZE + 4)
1099231200Smm		goto invalid;
1100231200Smm	header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
1101231200Smm	__archive_read_consume(a, H3_FIXED_SIZE);
1102231200Smm
1103231200Smm	/* Read extended headers */
1104231200Smm	err = lha_read_file_extended_header(a, lha, &header_crc, 4,
1105231200Smm		  lha->header_size - H3_FIXED_SIZE, &extdsize);
1106231200Smm	if (err < ARCHIVE_WARN)
1107231200Smm		return (err);
1108231200Smm
1109231200Smm	if (header_crc != lha->header_crc) {
1110231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1111231200Smm		    "LHa header CRC error");
1112231200Smm		return (ARCHIVE_FATAL);
1113231200Smm	}
1114231200Smm	return (err);
1115231200Smminvalid:
1116231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1117231200Smm	    "Invalid LHa header");
1118231200Smm	return (ARCHIVE_FATAL);
1119231200Smm}
1120231200Smm
1121231200Smm/*
1122231200Smm * Extended header format
1123231200Smm *
1124231200Smm * +0             +2        +3  -- used in header 1 and 2
1125231200Smm * +0             +4        +5  -- used in header 3
1126231200Smm * +--------------+---------+-------------------+--------------+--
1127231200Smm * |ex-header size|header id|        data       |ex-header size| .......
1128231200Smm * +--------------+---------+-------------------+--------------+--
1129231200Smm *  <-------------( ex-header size)------------> <-- next extended header --*
1130231200Smm *
1131231200Smm * If the ex-header size is zero, it is the make of the end of extended
1132231200Smm * headers.
1133231200Smm *
1134231200Smm */
1135231200Smmstatic int
1136231200Smmlha_read_file_extended_header(struct archive_read *a, struct lha *lha,
1137231200Smm    uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
1138231200Smm{
1139231200Smm	const void *h;
1140231200Smm	const unsigned char *extdheader;
1141231200Smm	size_t	extdsize;
1142231200Smm	size_t	datasize;
1143231200Smm	unsigned int i;
1144231200Smm	unsigned char extdtype;
1145231200Smm
1146231200Smm#define EXT_HEADER_CRC		0x00		/* Header CRC and information*/
1147231200Smm#define EXT_FILENAME		0x01		/* Filename 		    */
1148231200Smm#define EXT_DIRECTORY		0x02		/* Directory name	    */
1149231200Smm#define EXT_DOS_ATTR		0x40		/* MS-DOS attribute	    */
1150231200Smm#define EXT_TIMESTAMP		0x41		/* Windows time stamp	    */
1151231200Smm#define EXT_FILESIZE		0x42		/* Large file size	    */
1152231200Smm#define EXT_TIMEZONE		0x43		/* Time zone		    */
1153231200Smm#define EXT_UTF16_FILENAME	0x44		/* UTF-16 filename 	    */
1154231200Smm#define EXT_UTF16_DIRECTORY	0x45		/* UTF-16 directory name    */
1155231200Smm#define EXT_CODEPAGE		0x46		/* Codepage		    */
1156231200Smm#define EXT_UNIX_MODE		0x50		/* File permission	    */
1157231200Smm#define EXT_UNIX_GID_UID	0x51		/* gid,uid		    */
1158231200Smm#define EXT_UNIX_GNAME		0x52		/* Group name		    */
1159231200Smm#define EXT_UNIX_UNAME		0x53		/* User name		    */
1160231200Smm#define EXT_UNIX_MTIME		0x54		/* Modified time	    */
1161231200Smm#define EXT_OS2_NEW_ATTR	0x7f		/* new attribute(OS/2 only) */
1162231200Smm#define EXT_NEW_ATTR		0xff		/* new attribute	    */
1163231200Smm
1164231200Smm	*total_size = sizefield_length;
1165231200Smm
1166231200Smm	for (;;) {
1167231200Smm		/* Read an extended header size. */
1168231200Smm		if ((h =
1169231200Smm		    __archive_read_ahead(a, sizefield_length, NULL)) == NULL)
1170231200Smm			return (truncated_error(a));
1171231200Smm		/* Check if the size is the zero indicates the end of the
1172231200Smm		 * extended header. */
1173231200Smm		if (sizefield_length == sizeof(uint16_t))
1174231200Smm			extdsize = archive_le16dec(h);
1175231200Smm		else
1176231200Smm			extdsize = archive_le32dec(h);
1177231200Smm		if (extdsize == 0) {
1178231200Smm			/* End of extended header */
1179231200Smm			if (crc != NULL)
1180231200Smm				*crc = lha_crc16(*crc, h, sizefield_length);
1181231200Smm			__archive_read_consume(a, sizefield_length);
1182231200Smm			return (ARCHIVE_OK);
1183231200Smm		}
1184231200Smm
1185231200Smm		/* Sanity check to the extended header size. */
1186231200Smm		if (((uint64_t)*total_size + extdsize) >
1187231200Smm				    (uint64_t)limitsize ||
1188231200Smm		    extdsize <= (size_t)sizefield_length)
1189231200Smm			goto invalid;
1190231200Smm
1191231200Smm		/* Read the extended header. */
1192231200Smm		if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL)
1193231200Smm			return (truncated_error(a));
1194231200Smm		*total_size += extdsize;
1195231200Smm
1196231200Smm		extdheader = (const unsigned char *)h;
1197231200Smm		/* Get the extended header type. */
1198231200Smm		extdtype = extdheader[sizefield_length];
1199231200Smm		/* Calculate an extended data size. */
1200231200Smm		datasize = extdsize - (1 + sizefield_length);
1201231200Smm		/* Skip an extended header size field and type field. */
1202231200Smm		extdheader += sizefield_length + 1;
1203231200Smm
1204231200Smm		if (crc != NULL && extdtype != EXT_HEADER_CRC)
1205231200Smm			*crc = lha_crc16(*crc, h, extdsize);
1206231200Smm		switch (extdtype) {
1207231200Smm		case EXT_HEADER_CRC:
1208231200Smm			/* We only use a header CRC. Following data will not
1209231200Smm			 * be used. */
1210231200Smm			if (datasize >= 2) {
1211231200Smm				lha->header_crc = archive_le16dec(extdheader);
1212231200Smm				if (crc != NULL) {
1213231200Smm					static const char zeros[2] = {0, 0};
1214231200Smm					*crc = lha_crc16(*crc, h,
1215231200Smm					    extdsize - datasize);
1216231200Smm					/* CRC value itself as zero */
1217231200Smm					*crc = lha_crc16(*crc, zeros, 2);
1218231200Smm					*crc = lha_crc16(*crc,
1219231200Smm					    extdheader+2, datasize - 2);
1220231200Smm				}
1221231200Smm			}
1222231200Smm			break;
1223231200Smm		case EXT_FILENAME:
1224231200Smm			if (datasize == 0) {
1225231200Smm				/* maybe directory header */
1226231200Smm				archive_string_empty(&lha->filename);
1227231200Smm				break;
1228231200Smm			}
1229302001Smm			if (extdheader[0] == '\0')
1230302001Smm				goto invalid;
1231231200Smm			archive_strncpy(&lha->filename,
1232231200Smm			    (const char *)extdheader, datasize);
1233231200Smm			break;
1234358090Smm		case EXT_UTF16_FILENAME:
1235358090Smm			if (datasize == 0) {
1236358090Smm				/* maybe directory header */
1237358090Smm				archive_string_empty(&lha->filename);
1238358090Smm				break;
1239358090Smm			} else if (datasize & 1) {
1240358090Smm				/* UTF-16 characters take always 2 or 4 bytes */
1241358090Smm				goto invalid;
1242358090Smm			}
1243358090Smm			if (extdheader[0] == '\0')
1244358090Smm				goto invalid;
1245358090Smm			archive_string_empty(&lha->filename);
1246358090Smm			archive_array_append(&lha->filename,
1247358090Smm				(const char *)extdheader, datasize);
1248358090Smm			/* Setup a string conversion for a filename. */
1249358090Smm			lha->sconv_fname =
1250358090Smm			    archive_string_conversion_from_charset(&a->archive,
1251358090Smm			        "UTF-16LE", 1);
1252358090Smm			if (lha->sconv_fname == NULL)
1253358090Smm				return (ARCHIVE_FATAL);
1254358090Smm			break;
1255231200Smm		case EXT_DIRECTORY:
1256302001Smm			if (datasize == 0 || extdheader[0] == '\0')
1257231200Smm				/* no directory name data. exit this case. */
1258302001Smm				goto invalid;
1259231200Smm
1260231200Smm			archive_strncpy(&lha->dirname,
1261231200Smm		  	    (const char *)extdheader, datasize);
1262231200Smm			/*
1263231200Smm			 * Convert directory delimiter from 0xFF
1264231200Smm			 * to '/' for local system.
1265231200Smm	 		 */
1266231200Smm			for (i = 0; i < lha->dirname.length; i++) {
1267231200Smm				if ((unsigned char)lha->dirname.s[i] == 0xFF)
1268231200Smm					lha->dirname.s[i] = '/';
1269231200Smm			}
1270231200Smm			/* Is last character directory separator? */
1271231200Smm			if (lha->dirname.s[lha->dirname.length-1] != '/')
1272231200Smm				/* invalid directory data */
1273231200Smm				goto invalid;
1274231200Smm			break;
1275358090Smm		case EXT_UTF16_DIRECTORY:
1276358090Smm			/* UTF-16 characters take always 2 or 4 bytes */
1277358090Smm			if (datasize == 0 || (datasize & 1) ||
1278358090Smm			    extdheader[0] == '\0') {
1279358090Smm				/* no directory name data. exit this case. */
1280358090Smm				goto invalid;
1281358090Smm			}
1282358090Smm
1283358090Smm			archive_string_empty(&lha->dirname);
1284358090Smm			archive_array_append(&lha->dirname,
1285358090Smm				(const char *)extdheader, datasize);
1286358090Smm			lha->sconv_dir =
1287358090Smm			    archive_string_conversion_from_charset(&a->archive,
1288358090Smm			        "UTF-16LE", 1);
1289358090Smm			if (lha->sconv_dir == NULL)
1290358090Smm				return (ARCHIVE_FATAL);
1291358090Smm			else {
1292358090Smm				/*
1293358090Smm				 * Convert directory delimiter from 0xFFFF
1294358090Smm				 * to '/' for local system.
1295358090Smm				 */
1296358090Smm				uint16_t dirSep;
1297358090Smm				uint16_t d = 1;
1298358090Smm				if (archive_be16dec(&d) == 1)
1299358090Smm					dirSep = 0x2F00;
1300358090Smm				else
1301358090Smm					dirSep = 0x002F;
1302358090Smm
1303358090Smm				/* UTF-16LE character */
1304358090Smm				uint16_t *utf16name =
1305358090Smm				    (uint16_t *)lha->dirname.s;
1306358090Smm				for (i = 0; i < lha->dirname.length / 2; i++) {
1307358090Smm					if (utf16name[i] == 0xFFFF) {
1308358090Smm						utf16name[i] = dirSep;
1309358090Smm					}
1310358090Smm				}
1311358090Smm				/* Is last character directory separator? */
1312358090Smm				if (utf16name[lha->dirname.length / 2 - 1] !=
1313358090Smm				    dirSep) {
1314358090Smm					/* invalid directory data */
1315358090Smm					goto invalid;
1316358090Smm				}
1317358090Smm			}
1318358090Smm			break;
1319231200Smm		case EXT_DOS_ATTR:
1320231200Smm			if (datasize == 2)
1321231200Smm				lha->dos_attr = (unsigned char)
1322231200Smm				    (archive_le16dec(extdheader) & 0xff);
1323231200Smm			break;
1324231200Smm		case EXT_TIMESTAMP:
1325231200Smm			if (datasize == (sizeof(uint64_t) * 3)) {
1326231200Smm				lha->birthtime = lha_win_time(
1327231200Smm				    archive_le64dec(extdheader),
1328231200Smm				    &lha->birthtime_tv_nsec);
1329231200Smm				extdheader += sizeof(uint64_t);
1330231200Smm				lha->mtime = lha_win_time(
1331231200Smm				    archive_le64dec(extdheader),
1332231200Smm				    &lha->mtime_tv_nsec);
1333231200Smm				extdheader += sizeof(uint64_t);
1334231200Smm				lha->atime = lha_win_time(
1335231200Smm				    archive_le64dec(extdheader),
1336231200Smm				    &lha->atime_tv_nsec);
1337231200Smm				lha->setflag |= BIRTHTIME_IS_SET |
1338231200Smm				    ATIME_IS_SET;
1339231200Smm			}
1340231200Smm			break;
1341231200Smm		case EXT_FILESIZE:
1342231200Smm			if (datasize == sizeof(uint64_t) * 2) {
1343231200Smm				lha->compsize = archive_le64dec(extdheader);
1344231200Smm				extdheader += sizeof(uint64_t);
1345231200Smm				lha->origsize = archive_le64dec(extdheader);
1346231200Smm			}
1347231200Smm			break;
1348231200Smm		case EXT_CODEPAGE:
1349231200Smm			/* Get an archived filename charset from codepage.
1350231200Smm			 * This overwrites the charset specified by
1351231200Smm			 * hdrcharset option. */
1352231200Smm			if (datasize == sizeof(uint32_t)) {
1353231200Smm				struct archive_string cp;
1354231200Smm				const char *charset;
1355231200Smm
1356231200Smm				archive_string_init(&cp);
1357231200Smm				switch (archive_le32dec(extdheader)) {
1358231200Smm				case 65001: /* UTF-8 */
1359231200Smm					charset = "UTF-8";
1360231200Smm					break;
1361231200Smm				default:
1362231200Smm					archive_string_sprintf(&cp, "CP%d",
1363231200Smm					    (int)archive_le32dec(extdheader));
1364231200Smm					charset = cp.s;
1365231200Smm					break;
1366231200Smm				}
1367358090Smm				lha->sconv_dir =
1368231200Smm				    archive_string_conversion_from_charset(
1369231200Smm					&(a->archive), charset, 1);
1370358090Smm				lha->sconv_fname =
1371358090Smm				    archive_string_conversion_from_charset(
1372358090Smm					&(a->archive), charset, 1);
1373231200Smm				archive_string_free(&cp);
1374358090Smm				if (lha->sconv_dir == NULL)
1375231200Smm					return (ARCHIVE_FATAL);
1376358090Smm				if (lha->sconv_fname == NULL)
1377358090Smm					return (ARCHIVE_FATAL);
1378231200Smm			}
1379231200Smm			break;
1380231200Smm		case EXT_UNIX_MODE:
1381231200Smm			if (datasize == sizeof(uint16_t)) {
1382231200Smm				lha->mode = archive_le16dec(extdheader);
1383231200Smm				lha->setflag |= UNIX_MODE_IS_SET;
1384231200Smm			}
1385231200Smm			break;
1386231200Smm		case EXT_UNIX_GID_UID:
1387231200Smm			if (datasize == (sizeof(uint16_t) * 2)) {
1388231200Smm				lha->gid = archive_le16dec(extdheader);
1389231200Smm				lha->uid = archive_le16dec(extdheader+2);
1390231200Smm			}
1391231200Smm			break;
1392231200Smm		case EXT_UNIX_GNAME:
1393231200Smm			if (datasize > 0)
1394231200Smm				archive_strncpy(&lha->gname,
1395231200Smm				    (const char *)extdheader, datasize);
1396231200Smm			break;
1397231200Smm		case EXT_UNIX_UNAME:
1398231200Smm			if (datasize > 0)
1399231200Smm				archive_strncpy(&lha->uname,
1400231200Smm				    (const char *)extdheader, datasize);
1401231200Smm			break;
1402231200Smm		case EXT_UNIX_MTIME:
1403231200Smm			if (datasize == sizeof(uint32_t))
1404231200Smm				lha->mtime = archive_le32dec(extdheader);
1405231200Smm			break;
1406231200Smm		case EXT_OS2_NEW_ATTR:
1407231200Smm			/* This extended header is OS/2 depend. */
1408231200Smm			if (datasize == 16) {
1409231200Smm				lha->dos_attr = (unsigned char)
1410231200Smm				    (archive_le16dec(extdheader) & 0xff);
1411231200Smm				lha->mode = archive_le16dec(extdheader+2);
1412231200Smm				lha->gid = archive_le16dec(extdheader+4);
1413231200Smm				lha->uid = archive_le16dec(extdheader+6);
1414231200Smm				lha->birthtime = archive_le32dec(extdheader+8);
1415231200Smm				lha->atime = archive_le32dec(extdheader+12);
1416231200Smm				lha->setflag |= UNIX_MODE_IS_SET
1417231200Smm				    | BIRTHTIME_IS_SET | ATIME_IS_SET;
1418231200Smm			}
1419231200Smm			break;
1420231200Smm		case EXT_NEW_ATTR:
1421231200Smm			if (datasize == 20) {
1422231200Smm				lha->mode = (mode_t)archive_le32dec(extdheader);
1423231200Smm				lha->gid = archive_le32dec(extdheader+4);
1424231200Smm				lha->uid = archive_le32dec(extdheader+8);
1425231200Smm				lha->birthtime = archive_le32dec(extdheader+12);
1426231200Smm				lha->atime = archive_le32dec(extdheader+16);
1427231200Smm				lha->setflag |= UNIX_MODE_IS_SET
1428231200Smm				    | BIRTHTIME_IS_SET | ATIME_IS_SET;
1429231200Smm			}
1430231200Smm			break;
1431231200Smm		case EXT_TIMEZONE:		/* Not supported */
1432358090Smm			break;
1433231200Smm		default:
1434231200Smm			break;
1435231200Smm		}
1436231200Smm
1437231200Smm		__archive_read_consume(a, extdsize);
1438231200Smm	}
1439231200Smminvalid:
1440231200Smm	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1441231200Smm	    "Invalid extended LHa header");
1442231200Smm	return (ARCHIVE_FATAL);
1443231200Smm}
1444231200Smm
1445231200Smmstatic int
1446302001Smmlha_end_of_entry(struct archive_read *a)
1447302001Smm{
1448302001Smm	struct lha *lha = (struct lha *)(a->format->data);
1449302001Smm	int r = ARCHIVE_EOF;
1450302001Smm
1451302001Smm	if (!lha->end_of_entry_cleanup) {
1452302001Smm		if ((lha->setflag & CRC_IS_SET) &&
1453302001Smm		    lha->crc != lha->entry_crc_calculated) {
1454302001Smm			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1455302001Smm			    "LHa data CRC error");
1456302001Smm			r = ARCHIVE_WARN;
1457302001Smm		}
1458302001Smm
1459302001Smm		/* End-of-entry cleanup done. */
1460302001Smm		lha->end_of_entry_cleanup = 1;
1461302001Smm	}
1462302001Smm	return (r);
1463302001Smm}
1464302001Smm
1465302001Smmstatic int
1466231200Smmarchive_read_format_lha_read_data(struct archive_read *a,
1467231200Smm    const void **buff, size_t *size, int64_t *offset)
1468231200Smm{
1469231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1470231200Smm	int r;
1471231200Smm
1472231200Smm	if (lha->entry_unconsumed) {
1473231200Smm		/* Consume as much as the decompressor actually used. */
1474231200Smm		__archive_read_consume(a, lha->entry_unconsumed);
1475231200Smm		lha->entry_unconsumed = 0;
1476231200Smm	}
1477231200Smm	if (lha->end_of_entry) {
1478231200Smm		*offset = lha->entry_offset;
1479231200Smm		*size = 0;
1480231200Smm		*buff = NULL;
1481302001Smm		return (lha_end_of_entry(a));
1482231200Smm	}
1483231200Smm
1484231200Smm	if (lha->entry_is_compressed)
1485231200Smm		r =  lha_read_data_lzh(a, buff, size, offset);
1486231200Smm	else
1487231200Smm		/* No compression. */
1488231200Smm		r =  lha_read_data_none(a, buff, size, offset);
1489231200Smm	return (r);
1490231200Smm}
1491231200Smm
1492231200Smm/*
1493231200Smm * Read a file content in no compression.
1494231200Smm *
1495231200Smm * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
1496231200Smm * lha->end_of_entry if it consumes all of the data.
1497231200Smm */
1498231200Smmstatic int
1499231200Smmlha_read_data_none(struct archive_read *a, const void **buff,
1500231200Smm    size_t *size, int64_t *offset)
1501231200Smm{
1502231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1503231200Smm	ssize_t bytes_avail;
1504231200Smm
1505231200Smm	if (lha->entry_bytes_remaining == 0) {
1506231200Smm		*buff = NULL;
1507231200Smm		*size = 0;
1508231200Smm		*offset = lha->entry_offset;
1509231200Smm		lha->end_of_entry = 1;
1510231200Smm		return (ARCHIVE_OK);
1511231200Smm	}
1512231200Smm	/*
1513231200Smm	 * Note: '1' here is a performance optimization.
1514231200Smm	 * Recall that the decompression layer returns a count of
1515231200Smm	 * available bytes; asking for more than that forces the
1516231200Smm	 * decompressor to combine reads by copying data.
1517231200Smm	 */
1518231200Smm	*buff = __archive_read_ahead(a, 1, &bytes_avail);
1519231200Smm	if (bytes_avail <= 0) {
1520231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1521231200Smm		    "Truncated LHa file data");
1522231200Smm		return (ARCHIVE_FATAL);
1523231200Smm	}
1524231200Smm	if (bytes_avail > lha->entry_bytes_remaining)
1525238856Smm		bytes_avail = (ssize_t)lha->entry_bytes_remaining;
1526231200Smm	lha->entry_crc_calculated =
1527231200Smm	    lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
1528231200Smm	*size = bytes_avail;
1529231200Smm	*offset = lha->entry_offset;
1530231200Smm	lha->entry_offset += bytes_avail;
1531231200Smm	lha->entry_bytes_remaining -= bytes_avail;
1532231200Smm	if (lha->entry_bytes_remaining == 0)
1533231200Smm		lha->end_of_entry = 1;
1534231200Smm	lha->entry_unconsumed = bytes_avail;
1535231200Smm	return (ARCHIVE_OK);
1536231200Smm}
1537231200Smm
1538231200Smm/*
1539231200Smm * Read a file content in LZHUFF encoding.
1540231200Smm *
1541231200Smm * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is
1542231200Smm * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes
1543231200Smm * all of the data.
1544231200Smm */
1545231200Smmstatic int
1546231200Smmlha_read_data_lzh(struct archive_read *a, const void **buff,
1547231200Smm    size_t *size, int64_t *offset)
1548231200Smm{
1549231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1550231200Smm	ssize_t bytes_avail;
1551231200Smm	int r;
1552231200Smm
1553231200Smm	/* If we haven't yet read any data, initialize the decompressor. */
1554231200Smm	if (!lha->decompress_init) {
1555231200Smm		r = lzh_decode_init(&(lha->strm), lha->method);
1556231200Smm		switch (r) {
1557231200Smm		case ARCHIVE_OK:
1558231200Smm			break;
1559231200Smm		case ARCHIVE_FAILED:
1560231200Smm        		/* Unsupported compression. */
1561231200Smm			*buff = NULL;
1562231200Smm			*size = 0;
1563231200Smm			*offset = 0;
1564231200Smm			archive_set_error(&a->archive,
1565231200Smm			    ARCHIVE_ERRNO_FILE_FORMAT,
1566231200Smm			    "Unsupported lzh compression method -%c%c%c-",
1567231200Smm			    lha->method[0], lha->method[1], lha->method[2]);
1568231200Smm			/* We know compressed size; just skip it. */
1569231200Smm			archive_read_format_lha_read_data_skip(a);
1570231200Smm			return (ARCHIVE_WARN);
1571231200Smm		default:
1572231200Smm			archive_set_error(&a->archive, ENOMEM,
1573231200Smm			    "Couldn't allocate memory "
1574231200Smm			    "for lzh decompression");
1575231200Smm			return (ARCHIVE_FATAL);
1576231200Smm		}
1577231200Smm		/* We've initialized decompression for this stream. */
1578231200Smm		lha->decompress_init = 1;
1579231200Smm		lha->strm.avail_out = 0;
1580231200Smm		lha->strm.total_out = 0;
1581231200Smm	}
1582231200Smm
1583231200Smm	/*
1584231200Smm	 * Note: '1' here is a performance optimization.
1585231200Smm	 * Recall that the decompression layer returns a count of
1586231200Smm	 * available bytes; asking for more than that forces the
1587231200Smm	 * decompressor to combine reads by copying data.
1588231200Smm	 */
1589231200Smm	lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail);
1590231200Smm	if (bytes_avail <= 0) {
1591231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1592231200Smm		    "Truncated LHa file body");
1593231200Smm		return (ARCHIVE_FATAL);
1594231200Smm	}
1595231200Smm	if (bytes_avail > lha->entry_bytes_remaining)
1596238856Smm		bytes_avail = (ssize_t)lha->entry_bytes_remaining;
1597231200Smm
1598302001Smm	lha->strm.avail_in = (int)bytes_avail;
1599231200Smm	lha->strm.total_in = 0;
1600302001Smm	lha->strm.avail_out = 0;
1601231200Smm
1602231200Smm	r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
1603231200Smm	switch (r) {
1604231200Smm	case ARCHIVE_OK:
1605231200Smm		break;
1606231200Smm	case ARCHIVE_EOF:
1607231200Smm		lha->end_of_entry = 1;
1608231200Smm		break;
1609231200Smm	default:
1610231200Smm		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1611231200Smm		    "Bad lzh data");
1612231200Smm		return (ARCHIVE_FAILED);
1613231200Smm	}
1614231200Smm	lha->entry_unconsumed = lha->strm.total_in;
1615231200Smm	lha->entry_bytes_remaining -= lha->strm.total_in;
1616231200Smm
1617302001Smm	if (lha->strm.avail_out) {
1618231200Smm		*offset = lha->entry_offset;
1619302001Smm		*size = lha->strm.avail_out;
1620302001Smm		*buff = lha->strm.ref_ptr;
1621231200Smm		lha->entry_crc_calculated =
1622231200Smm		    lha_crc16(lha->entry_crc_calculated, *buff, *size);
1623231200Smm		lha->entry_offset += *size;
1624231200Smm	} else {
1625231200Smm		*offset = lha->entry_offset;
1626231200Smm		*size = 0;
1627231200Smm		*buff = NULL;
1628302001Smm		if (lha->end_of_entry)
1629302001Smm			return (lha_end_of_entry(a));
1630231200Smm	}
1631231200Smm	return (ARCHIVE_OK);
1632231200Smm}
1633231200Smm
1634231200Smm/*
1635231200Smm * Skip a file content.
1636231200Smm */
1637231200Smmstatic int
1638231200Smmarchive_read_format_lha_read_data_skip(struct archive_read *a)
1639231200Smm{
1640231200Smm	struct lha *lha;
1641238856Smm	int64_t bytes_skipped;
1642231200Smm
1643231200Smm	lha = (struct lha *)(a->format->data);
1644231200Smm
1645231200Smm	if (lha->entry_unconsumed) {
1646231200Smm		/* Consume as much as the decompressor actually used. */
1647231200Smm		__archive_read_consume(a, lha->entry_unconsumed);
1648231200Smm		lha->entry_unconsumed = 0;
1649231200Smm	}
1650231200Smm
1651231200Smm	/* if we've already read to end of data, we're done. */
1652231200Smm	if (lha->end_of_entry_cleanup)
1653231200Smm		return (ARCHIVE_OK);
1654231200Smm
1655231200Smm	/*
1656231200Smm	 * If the length is at the beginning, we can skip the
1657231200Smm	 * compressed data much more quickly.
1658231200Smm	 */
1659231200Smm	bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining);
1660231200Smm	if (bytes_skipped < 0)
1661231200Smm		return (ARCHIVE_FATAL);
1662231200Smm
1663231200Smm	/* This entry is finished and done. */
1664231200Smm	lha->end_of_entry_cleanup = lha->end_of_entry = 1;
1665231200Smm	return (ARCHIVE_OK);
1666231200Smm}
1667231200Smm
1668231200Smmstatic int
1669231200Smmarchive_read_format_lha_cleanup(struct archive_read *a)
1670231200Smm{
1671231200Smm	struct lha *lha = (struct lha *)(a->format->data);
1672231200Smm
1673231200Smm	lzh_decode_free(&(lha->strm));
1674231200Smm	archive_string_free(&(lha->dirname));
1675231200Smm	archive_string_free(&(lha->filename));
1676231200Smm	archive_string_free(&(lha->uname));
1677231200Smm	archive_string_free(&(lha->gname));
1678231200Smm	archive_wstring_free(&(lha->ws));
1679231200Smm	free(lha);
1680231200Smm	(a->format->data) = NULL;
1681231200Smm	return (ARCHIVE_OK);
1682231200Smm}
1683231200Smm
1684231200Smm/*
1685231200Smm * 'LHa for UNIX' utility has archived a symbolic-link name after
1686231200Smm * a pathname with '|' character.
1687231200Smm * This function extracts the symbolic-link name from the pathname.
1688231200Smm *
1689231200Smm * example.
1690231200Smm *   1. a symbolic-name is 'aaa/bb/cc'
1691231200Smm *   2. a filename is 'xxx/bbb'
1692231200Smm *  then a archived pathname is 'xxx/bbb|aaa/bb/cc'
1693231200Smm */
1694231200Smmstatic int
1695358090Smmlha_parse_linkname(struct archive_wstring *linkname,
1696358090Smm    struct archive_wstring *pathname)
1697231200Smm{
1698358090Smm	wchar_t *	linkptr;
1699248616Smm	size_t 	symlen;
1700231200Smm
1701358090Smm	linkptr = wcschr(pathname->s, L'|');
1702231200Smm	if (linkptr != NULL) {
1703358090Smm		symlen = wcslen(linkptr + 1);
1704358090Smm		archive_wstrncpy(linkname, linkptr+1, symlen);
1705231200Smm
1706231200Smm		*linkptr = 0;
1707358090Smm		pathname->length = wcslen(pathname->s);
1708231200Smm
1709231200Smm		return (1);
1710231200Smm	}
1711231200Smm	return (0);
1712231200Smm}
1713231200Smm
1714231200Smm/* Convert an MSDOS-style date/time into Unix-style time. */
1715231200Smmstatic time_t
1716231200Smmlha_dos_time(const unsigned char *p)
1717231200Smm{
1718231200Smm	int msTime, msDate;
1719231200Smm	struct tm ts;
1720231200Smm
1721231200Smm	msTime = archive_le16dec(p);
1722231200Smm	msDate = archive_le16dec(p+2);
1723231200Smm
1724231200Smm	memset(&ts, 0, sizeof(ts));
1725231200Smm	ts.tm_year = ((msDate >> 9) & 0x7f) + 80;   /* Years since 1900. */
1726231200Smm	ts.tm_mon = ((msDate >> 5) & 0x0f) - 1;     /* Month number.     */
1727231200Smm	ts.tm_mday = msDate & 0x1f;		    /* Day of month.     */
1728231200Smm	ts.tm_hour = (msTime >> 11) & 0x1f;
1729231200Smm	ts.tm_min = (msTime >> 5) & 0x3f;
1730231200Smm	ts.tm_sec = (msTime << 1) & 0x3e;
1731231200Smm	ts.tm_isdst = -1;
1732231200Smm	return (mktime(&ts));
1733231200Smm}
1734231200Smm
1735231200Smm/* Convert an MS-Windows-style date/time into Unix-style time. */
1736231200Smmstatic time_t
1737231200Smmlha_win_time(uint64_t wintime, long *ns)
1738231200Smm{
1739231200Smm#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1740231200Smm
1741231200Smm	if (wintime >= EPOC_TIME) {
1742231200Smm		wintime -= EPOC_TIME;	/* 1970-01-01 00:00:00 (UTC) */
1743231200Smm		if (ns != NULL)
1744231200Smm			*ns = (long)(wintime % 10000000) * 100;
1745231200Smm		return (wintime / 10000000);
1746231200Smm	} else {
1747231200Smm		if (ns != NULL)
1748231200Smm			*ns = 0;
1749231200Smm		return (0);
1750231200Smm	}
1751231200Smm}
1752231200Smm
1753231200Smmstatic unsigned char
1754248616Smmlha_calcsum(unsigned char sum, const void *pp, int offset, size_t size)
1755231200Smm{
1756231200Smm	unsigned char const *p = (unsigned char const *)pp;
1757231200Smm
1758231200Smm	p += offset;
1759248616Smm	for (;size > 0; --size)
1760231200Smm		sum += *p++;
1761231200Smm	return (sum);
1762231200Smm}
1763231200Smm
1764302001Smmstatic uint16_t crc16tbl[2][256];
1765302001Smmstatic void
1766302001Smmlha_crc16_init(void)
1767302001Smm{
1768302001Smm	unsigned int i;
1769302001Smm	static int crc16init = 0;
1770231200Smm
1771302001Smm	if (crc16init)
1772302001Smm		return;
1773302001Smm	crc16init = 1;
1774302001Smm
1775302001Smm	for (i = 0; i < 256; i++) {
1776302001Smm		unsigned int j;
1777302001Smm		uint16_t crc = (uint16_t)i;
1778302001Smm		for (j = 8; j; j--)
1779302001Smm			crc = (crc >> 1) ^ ((crc & 1) * 0xA001);
1780302001Smm		crc16tbl[0][i] = crc;
1781302001Smm	}
1782302001Smm
1783302001Smm	for (i = 0; i < 256; i++) {
1784302001Smm		crc16tbl[1][i] = (crc16tbl[0][i] >> 8)
1785302001Smm			^ crc16tbl[0][crc16tbl[0][i] & 0xff];
1786302001Smm	}
1787302001Smm}
1788302001Smm
1789231200Smmstatic uint16_t
1790231200Smmlha_crc16(uint16_t crc, const void *pp, size_t len)
1791231200Smm{
1792302001Smm	const unsigned char *p = (const unsigned char *)pp;
1793302001Smm	const uint16_t *buff;
1794302001Smm	const union {
1795302001Smm		uint32_t i;
1796302001Smm		char c[4];
1797302001Smm	} u = { 0x01020304 };
1798231200Smm
1799302001Smm	if (len == 0)
1800302001Smm		return crc;
1801302001Smm
1802302001Smm	/* Process unaligned address. */
1803302001Smm	if (((uintptr_t)p) & (uintptr_t)0x1) {
1804302001Smm		crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
1805302001Smm		len--;
1806231200Smm	}
1807302001Smm	buff = (const uint16_t *)p;
1808302001Smm	/*
1809302001Smm	 * Modern C compiler such as GCC does not unroll automatically yet
1810302001Smm	 * without unrolling pragma, and Clang is so. So we should
1811302001Smm	 * unroll this loop for its performance.
1812302001Smm	 */
1813302001Smm	for (;len >= 8; len -= 8) {
1814302001Smm		/* This if statement expects compiler optimization will
1815313571Smm		 * remove the statement which will not be executed. */
1816302295Smm#undef bswap16
1817302001Smm#if defined(_MSC_VER) && _MSC_VER >= 1400  /* Visual Studio */
1818302001Smm#  define bswap16(x) _byteswap_ushort(x)
1819305192Smm#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ > 4)
1820305192Smm/* GCC 4.8 and later has __builtin_bswap16() */
1821302001Smm#  define bswap16(x) __builtin_bswap16(x)
1822305192Smm#elif defined(__clang__)
1823305192Smm/* All clang versions have __builtin_bswap16() */
1824305192Smm#  define bswap16(x) __builtin_bswap16(x)
1825302001Smm#else
1826302001Smm#  define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
1827302001Smm#endif
1828302001Smm#define CRC16W	do { 	\
1829302001Smm		if(u.c[0] == 1) { /* Big endian */		\
1830302001Smm			crc ^= bswap16(*buff); buff++;		\
1831302001Smm		} else						\
1832302001Smm			crc ^= *buff++;				\
1833302001Smm		crc = crc16tbl[1][crc & 0xff] ^ crc16tbl[0][crc >> 8];\
1834302001Smm} while (0)
1835302001Smm		CRC16W;
1836302001Smm		CRC16W;
1837302001Smm		CRC16W;
1838302001Smm		CRC16W;
1839302001Smm#undef CRC16W
1840302001Smm#undef bswap16
1841231200Smm	}
1842302001Smm
1843302001Smm	p = (const unsigned char *)buff;
1844302001Smm	for (;len; len--) {
1845302001Smm		crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
1846302001Smm	}
1847302001Smm	return crc;
1848231200Smm}
1849231200Smm
1850231200Smm/*
1851231200Smm * Initialize LZHUF decoder.
1852231200Smm *
1853231200Smm * Returns ARCHIVE_OK if initialization was successful.
1854231200Smm * Returns ARCHIVE_FAILED if method is unsupported.
1855231200Smm * Returns ARCHIVE_FATAL if initialization failed; memory allocation
1856231200Smm * error occurred.
1857231200Smm */
1858231200Smmstatic int
1859231200Smmlzh_decode_init(struct lzh_stream *strm, const char *method)
1860231200Smm{
1861231200Smm	struct lzh_dec *ds;
1862231200Smm	int w_bits, w_size;
1863231200Smm
1864231200Smm	if (strm->ds == NULL) {
1865231200Smm		strm->ds = calloc(1, sizeof(*strm->ds));
1866231200Smm		if (strm->ds == NULL)
1867231200Smm			return (ARCHIVE_FATAL);
1868231200Smm	}
1869231200Smm	ds = strm->ds;
1870231200Smm	ds->error = ARCHIVE_FAILED;
1871231200Smm	if (method == NULL || method[0] != 'l' || method[1] != 'h')
1872231200Smm		return (ARCHIVE_FAILED);
1873231200Smm	switch (method[2]) {
1874231200Smm	case '5':
1875231200Smm		w_bits = 13;/* 8KiB for window */
1876231200Smm		break;
1877231200Smm	case '6':
1878231200Smm		w_bits = 15;/* 32KiB for window */
1879231200Smm		break;
1880231200Smm	case '7':
1881231200Smm		w_bits = 16;/* 64KiB for window */
1882231200Smm		break;
1883231200Smm	default:
1884231200Smm		return (ARCHIVE_FAILED);/* Not supported. */
1885231200Smm	}
1886231200Smm	ds->error = ARCHIVE_FATAL;
1887302001Smm	/* Expand a window size up to 128 KiB for decompressing process
1888302001Smm	 * performance whatever its original window size is. */
1889302001Smm	ds->w_size = 1U << 17;
1890231200Smm	ds->w_mask = ds->w_size -1;
1891302001Smm	if (ds->w_buff == NULL) {
1892231200Smm		ds->w_buff = malloc(ds->w_size);
1893231200Smm		if (ds->w_buff == NULL)
1894231200Smm			return (ARCHIVE_FATAL);
1895231200Smm	}
1896302001Smm	w_size = 1U << w_bits;
1897302001Smm	memset(ds->w_buff + ds->w_size - w_size, 0x20, w_size);
1898231200Smm	ds->w_pos = 0;
1899231200Smm	ds->state = 0;
1900231200Smm	ds->pos_pt_len_size = w_bits + 1;
1901231200Smm	ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4;
1902231200Smm	ds->literal_pt_len_size = PT_BITLEN_SIZE;
1903231200Smm	ds->literal_pt_len_bits = 5;
1904231200Smm	ds->br.cache_buffer = 0;
1905231200Smm	ds->br.cache_avail = 0;
1906231200Smm
1907231200Smm	if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16)
1908231200Smm	    != ARCHIVE_OK)
1909231200Smm		return (ARCHIVE_FATAL);
1910231200Smm	ds->lt.len_bits = 9;
1911231200Smm	if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16)
1912231200Smm	    != ARCHIVE_OK)
1913231200Smm		return (ARCHIVE_FATAL);
1914231200Smm	ds->error = 0;
1915231200Smm
1916231200Smm	return (ARCHIVE_OK);
1917231200Smm}
1918231200Smm
1919231200Smm/*
1920231200Smm * Release LZHUF decoder.
1921231200Smm */
1922231200Smmstatic void
1923231200Smmlzh_decode_free(struct lzh_stream *strm)
1924231200Smm{
1925231200Smm
1926231200Smm	if (strm->ds == NULL)
1927231200Smm		return;
1928231200Smm	free(strm->ds->w_buff);
1929231200Smm	lzh_huffman_free(&(strm->ds->lt));
1930231200Smm	lzh_huffman_free(&(strm->ds->pt));
1931231200Smm	free(strm->ds);
1932231200Smm	strm->ds = NULL;
1933231200Smm}
1934231200Smm
1935231200Smm/*
1936231200Smm * Bit stream reader.
1937231200Smm */
1938231200Smm/* Check that the cache buffer has enough bits. */
1939231200Smm#define lzh_br_has(br, n)	((br)->cache_avail >= n)
1940231200Smm/* Get compressed data by bit. */
1941231200Smm#define lzh_br_bits(br, n)				\
1942231200Smm	(((uint16_t)((br)->cache_buffer >>		\
1943231200Smm		((br)->cache_avail - (n)))) & cache_masks[n])
1944231200Smm#define lzh_br_bits_forced(br, n)			\
1945231200Smm	(((uint16_t)((br)->cache_buffer <<		\
1946231200Smm		((n) - (br)->cache_avail))) & cache_masks[n])
1947231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we
1948231200Smm * will use.
1949231200Smm *  True  : completed, there is enough data in the cache buffer.
1950231200Smm *  False : we met that strm->next_in is empty, we have to get following
1951231200Smm *          bytes. */
1952231200Smm#define lzh_br_read_ahead_0(strm, br, n)	\
1953231200Smm	(lzh_br_has(br, (n)) || lzh_br_fillup(strm, br))
1954231200Smm/*  True  : the cache buffer has some bits as much as we need.
1955231200Smm *  False : there are no enough bits in the cache buffer to be used,
1956231200Smm *          we have to get following bytes if we could. */
1957231200Smm#define lzh_br_read_ahead(strm, br, n)	\
1958231200Smm	(lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n)))
1959231200Smm
1960231200Smm/* Notify how many bits we consumed. */
1961231200Smm#define lzh_br_consume(br, n)	((br)->cache_avail -= (n))
1962231200Smm#define lzh_br_unconsume(br, n)	((br)->cache_avail += (n))
1963231200Smm
1964231200Smmstatic const uint16_t cache_masks[] = {
1965231200Smm	0x0000, 0x0001, 0x0003, 0x0007,
1966231200Smm	0x000F, 0x001F, 0x003F, 0x007F,
1967231200Smm	0x00FF, 0x01FF, 0x03FF, 0x07FF,
1968231200Smm	0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
1969231200Smm	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
1970231200Smm};
1971231200Smm
1972231200Smm/*
1973231200Smm * Shift away used bits in the cache data and fill it up with following bits.
1974231200Smm * Call this when cache buffer does not have enough bits you need.
1975231200Smm *
1976231200Smm * Returns 1 if the cache buffer is full.
1977231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty.
1978231200Smm */
1979231200Smmstatic int
1980231200Smmlzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
1981231200Smm{
1982231200Smm	int n = CACHE_BITS - br->cache_avail;
1983231200Smm
1984231200Smm	for (;;) {
1985302001Smm		const int x = n >> 3;
1986302001Smm		if (strm->avail_in >= x) {
1987302001Smm			switch (x) {
1988302001Smm			case 8:
1989231200Smm				br->cache_buffer =
1990231200Smm				    ((uint64_t)strm->next_in[0]) << 56 |
1991231200Smm				    ((uint64_t)strm->next_in[1]) << 48 |
1992231200Smm				    ((uint64_t)strm->next_in[2]) << 40 |
1993231200Smm				    ((uint64_t)strm->next_in[3]) << 32 |
1994231200Smm				    ((uint32_t)strm->next_in[4]) << 24 |
1995231200Smm				    ((uint32_t)strm->next_in[5]) << 16 |
1996231200Smm				    ((uint32_t)strm->next_in[6]) << 8 |
1997231200Smm				     (uint32_t)strm->next_in[7];
1998231200Smm				strm->next_in += 8;
1999231200Smm				strm->avail_in -= 8;
2000231200Smm				br->cache_avail += 8 * 8;
2001231200Smm				return (1);
2002302001Smm			case 7:
2003231200Smm				br->cache_buffer =
2004231200Smm		 		   (br->cache_buffer << 56) |
2005231200Smm				    ((uint64_t)strm->next_in[0]) << 48 |
2006231200Smm				    ((uint64_t)strm->next_in[1]) << 40 |
2007231200Smm				    ((uint64_t)strm->next_in[2]) << 32 |
2008231200Smm				    ((uint32_t)strm->next_in[3]) << 24 |
2009231200Smm				    ((uint32_t)strm->next_in[4]) << 16 |
2010231200Smm				    ((uint32_t)strm->next_in[5]) << 8 |
2011231200Smm				     (uint32_t)strm->next_in[6];
2012231200Smm				strm->next_in += 7;
2013231200Smm				strm->avail_in -= 7;
2014231200Smm				br->cache_avail += 7 * 8;
2015231200Smm				return (1);
2016302001Smm			case 6:
2017231200Smm				br->cache_buffer =
2018231200Smm		 		   (br->cache_buffer << 48) |
2019231200Smm				    ((uint64_t)strm->next_in[0]) << 40 |
2020231200Smm				    ((uint64_t)strm->next_in[1]) << 32 |
2021231200Smm				    ((uint32_t)strm->next_in[2]) << 24 |
2022231200Smm				    ((uint32_t)strm->next_in[3]) << 16 |
2023231200Smm				    ((uint32_t)strm->next_in[4]) << 8 |
2024231200Smm				     (uint32_t)strm->next_in[5];
2025231200Smm				strm->next_in += 6;
2026231200Smm				strm->avail_in -= 6;
2027231200Smm				br->cache_avail += 6 * 8;
2028231200Smm				return (1);
2029302001Smm			case 0:
2030302001Smm				/* We have enough compressed data in
2031302001Smm				 * the cache buffer.*/
2032302001Smm				return (1);
2033302001Smm			default:
2034302001Smm				break;
2035231200Smm			}
2036231200Smm		}
2037231200Smm		if (strm->avail_in == 0) {
2038231200Smm			/* There is not enough compressed data to fill up the
2039231200Smm			 * cache buffer. */
2040231200Smm			return (0);
2041231200Smm		}
2042231200Smm		br->cache_buffer =
2043231200Smm		   (br->cache_buffer << 8) | *strm->next_in++;
2044231200Smm		strm->avail_in--;
2045231200Smm		br->cache_avail += 8;
2046231200Smm		n -= 8;
2047231200Smm	}
2048231200Smm}
2049231200Smm
2050231200Smm/*
2051231200Smm * Decode LZHUF.
2052231200Smm *
2053231200Smm * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
2054231200Smm *    Please set available buffer and call this function again.
2055231200Smm * 2. Returns ARCHIVE_EOF if decompression has been completed.
2056231200Smm * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
2057231200Smm *    is broken or you do not set 'last' flag properly.
2058231200Smm * 4. 'last' flag is very important, you must set 1 to the flag if there
2059231200Smm *    is no input data. The lha compressed data format does not provide how
2060231200Smm *    to know the compressed data is really finished.
2061231200Smm *    Note: lha command utility check if the total size of output bytes is
2062231200Smm *    reached the uncompressed size recorded in its header. it does not mind
2063231200Smm *    that the decoding process is properly finished.
2064231200Smm *    GNU ZIP can decompress another compressed file made by SCO LZH compress.
2065231200Smm *    it handles EOF as null to fill read buffer with zero until the decoding
2066231200Smm *    process meet 2 bytes of zeros at reading a size of a next chunk, so the
2067231200Smm *    zeros are treated as the mark of the end of the data although the zeros
2068231200Smm *    is dummy, not the file data.
2069231200Smm */
2070231200Smmstatic int	lzh_read_blocks(struct lzh_stream *, int);
2071231200Smmstatic int	lzh_decode_blocks(struct lzh_stream *, int);
2072231200Smm#define ST_RD_BLOCK		0
2073231200Smm#define ST_RD_PT_1		1
2074231200Smm#define ST_RD_PT_2		2
2075231200Smm#define ST_RD_PT_3		3
2076231200Smm#define ST_RD_PT_4		4
2077231200Smm#define ST_RD_LITERAL_1		5
2078231200Smm#define ST_RD_LITERAL_2		6
2079231200Smm#define ST_RD_LITERAL_3		7
2080231200Smm#define ST_RD_POS_DATA_1	8
2081231200Smm#define ST_GET_LITERAL		9
2082231200Smm#define ST_GET_POS_1		10
2083231200Smm#define ST_GET_POS_2		11
2084231200Smm#define ST_COPY_DATA		12
2085231200Smm
2086231200Smmstatic int
2087231200Smmlzh_decode(struct lzh_stream *strm, int last)
2088231200Smm{
2089231200Smm	struct lzh_dec *ds = strm->ds;
2090302001Smm	int avail_in;
2091231200Smm	int r;
2092231200Smm
2093231200Smm	if (ds->error)
2094231200Smm		return (ds->error);
2095231200Smm
2096231200Smm	avail_in = strm->avail_in;
2097231200Smm	do {
2098231200Smm		if (ds->state < ST_GET_LITERAL)
2099231200Smm			r = lzh_read_blocks(strm, last);
2100231200Smm		else
2101231200Smm			r = lzh_decode_blocks(strm, last);
2102231200Smm	} while (r == 100);
2103231200Smm	strm->total_in += avail_in - strm->avail_in;
2104231200Smm	return (r);
2105231200Smm}
2106231200Smm
2107302001Smmstatic void
2108302001Smmlzh_emit_window(struct lzh_stream *strm, size_t s)
2109231200Smm{
2110302001Smm	strm->ref_ptr = strm->ds->w_buff;
2111302001Smm	strm->avail_out = (int)s;
2112302001Smm	strm->total_out += s;
2113231200Smm}
2114231200Smm
2115231200Smmstatic int
2116231200Smmlzh_read_blocks(struct lzh_stream *strm, int last)
2117231200Smm{
2118231200Smm	struct lzh_dec *ds = strm->ds;
2119231200Smm	struct lzh_br *br = &(ds->br);
2120231200Smm	int c = 0, i;
2121231200Smm	unsigned rbits;
2122231200Smm
2123231200Smm	for (;;) {
2124231200Smm		switch (ds->state) {
2125231200Smm		case ST_RD_BLOCK:
2126231200Smm			/*
2127231200Smm			 * Read a block number indicates how many blocks
2128231200Smm			 * we will handle. The block is composed of a
2129231200Smm			 * literal and a match, sometimes a literal only
2130231200Smm			 * in particular, there are no reference data at
2131231200Smm			 * the beginning of the decompression.
2132231200Smm			 */
2133231200Smm			if (!lzh_br_read_ahead_0(strm, br, 16)) {
2134231200Smm				if (!last)
2135231200Smm					/* We need following data. */
2136231200Smm					return (ARCHIVE_OK);
2137231200Smm				if (lzh_br_has(br, 8)) {
2138231200Smm					/*
2139231200Smm					 * It seems there are extra bits.
2140231200Smm					 *  1. Compressed data is broken.
2141231200Smm					 *  2. `last' flag does not properly
2142231200Smm					 *     set.
2143231200Smm					 */
2144231200Smm					goto failed;
2145231200Smm				}
2146231200Smm				if (ds->w_pos > 0) {
2147302001Smm					lzh_emit_window(strm, ds->w_pos);
2148302001Smm					ds->w_pos = 0;
2149302001Smm					return (ARCHIVE_OK);
2150231200Smm				}
2151231200Smm				/* End of compressed data; we have completely
2152231200Smm				 * handled all compressed data. */
2153231200Smm				return (ARCHIVE_EOF);
2154231200Smm			}
2155231200Smm			ds->blocks_avail = lzh_br_bits(br, 16);
2156231200Smm			if (ds->blocks_avail == 0)
2157231200Smm				goto failed;
2158231200Smm			lzh_br_consume(br, 16);
2159231200Smm			/*
2160231200Smm			 * Read a literal table compressed in huffman
2161231200Smm			 * coding.
2162231200Smm			 */
2163231200Smm			ds->pt.len_size = ds->literal_pt_len_size;
2164231200Smm			ds->pt.len_bits = ds->literal_pt_len_bits;
2165231200Smm			ds->reading_position = 0;
2166231200Smm			/* FALL THROUGH */
2167231200Smm		case ST_RD_PT_1:
2168231200Smm			/* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are
2169231200Smm			 * used in reading both a literal table and a
2170231200Smm			 * position table. */
2171231200Smm			if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) {
2172231200Smm				if (last)
2173231200Smm					goto failed;/* Truncated data. */
2174231200Smm				ds->state = ST_RD_PT_1;
2175231200Smm				return (ARCHIVE_OK);
2176231200Smm			}
2177231200Smm			ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits);
2178231200Smm			lzh_br_consume(br, ds->pt.len_bits);
2179231200Smm			/* FALL THROUGH */
2180231200Smm		case ST_RD_PT_2:
2181231200Smm			if (ds->pt.len_avail == 0) {
2182231200Smm				/* There is no bitlen. */
2183231200Smm				if (!lzh_br_read_ahead(strm, br,
2184231200Smm				    ds->pt.len_bits)) {
2185231200Smm					if (last)
2186231200Smm						goto failed;/* Truncated data.*/
2187231200Smm					ds->state = ST_RD_PT_2;
2188231200Smm					return (ARCHIVE_OK);
2189231200Smm				}
2190231200Smm				if (!lzh_make_fake_table(&(ds->pt),
2191231200Smm				    lzh_br_bits(br, ds->pt.len_bits)))
2192231200Smm					goto failed;/* Invalid data. */
2193231200Smm				lzh_br_consume(br, ds->pt.len_bits);
2194231200Smm				if (ds->reading_position)
2195231200Smm					ds->state = ST_GET_LITERAL;
2196231200Smm				else
2197231200Smm					ds->state = ST_RD_LITERAL_1;
2198231200Smm				break;
2199231200Smm			} else if (ds->pt.len_avail > ds->pt.len_size)
2200231200Smm				goto failed;/* Invalid data. */
2201231200Smm			ds->loop = 0;
2202231200Smm			memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
2203231200Smm			if (ds->pt.len_avail < 3 ||
2204231200Smm			    ds->pt.len_size == ds->pos_pt_len_size) {
2205231200Smm				ds->state = ST_RD_PT_4;
2206231200Smm				break;
2207231200Smm			}
2208231200Smm			/* FALL THROUGH */
2209231200Smm		case ST_RD_PT_3:
2210231200Smm			ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3);
2211231200Smm			if (ds->loop < 3) {
2212231200Smm				if (ds->loop < 0 || last)
2213231200Smm					goto failed;/* Invalid data. */
2214231200Smm				/* Not completed, get following data. */
2215231200Smm				ds->state = ST_RD_PT_3;
2216231200Smm				return (ARCHIVE_OK);
2217231200Smm			}
2218231200Smm			/* There are some null in bitlen of the literal. */
2219231200Smm			if (!lzh_br_read_ahead(strm, br, 2)) {
2220231200Smm				if (last)
2221231200Smm					goto failed;/* Truncated data. */
2222231200Smm				ds->state = ST_RD_PT_3;
2223231200Smm				return (ARCHIVE_OK);
2224231200Smm			}
2225231200Smm			c = lzh_br_bits(br, 2);
2226231200Smm			lzh_br_consume(br, 2);
2227231200Smm			if (c > ds->pt.len_avail - 3)
2228231200Smm				goto failed;/* Invalid data. */
2229231200Smm			for (i = 3; c-- > 0 ;)
2230231200Smm				ds->pt.bitlen[i++] = 0;
2231231200Smm			ds->loop = i;
2232231200Smm			/* FALL THROUGH */
2233231200Smm		case ST_RD_PT_4:
2234231200Smm			ds->loop = lzh_read_pt_bitlen(strm, ds->loop,
2235231200Smm			    ds->pt.len_avail);
2236231200Smm			if (ds->loop < ds->pt.len_avail) {
2237231200Smm				if (ds->loop < 0 || last)
2238231200Smm					goto failed;/* Invalid data. */
2239231200Smm				/* Not completed, get following data. */
2240231200Smm				ds->state = ST_RD_PT_4;
2241231200Smm				return (ARCHIVE_OK);
2242231200Smm			}
2243231200Smm			if (!lzh_make_huffman_table(&(ds->pt)))
2244231200Smm				goto failed;/* Invalid data */
2245231200Smm			if (ds->reading_position) {
2246231200Smm				ds->state = ST_GET_LITERAL;
2247231200Smm				break;
2248231200Smm			}
2249231200Smm			/* FALL THROUGH */
2250231200Smm		case ST_RD_LITERAL_1:
2251231200Smm			if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) {
2252231200Smm				if (last)
2253231200Smm					goto failed;/* Truncated data. */
2254231200Smm				ds->state = ST_RD_LITERAL_1;
2255231200Smm				return (ARCHIVE_OK);
2256231200Smm			}
2257231200Smm			ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits);
2258231200Smm			lzh_br_consume(br, ds->lt.len_bits);
2259231200Smm			/* FALL THROUGH */
2260231200Smm		case ST_RD_LITERAL_2:
2261231200Smm			if (ds->lt.len_avail == 0) {
2262231200Smm				/* There is no bitlen. */
2263231200Smm				if (!lzh_br_read_ahead(strm, br,
2264231200Smm				    ds->lt.len_bits)) {
2265231200Smm					if (last)
2266231200Smm						goto failed;/* Truncated data.*/
2267231200Smm					ds->state = ST_RD_LITERAL_2;
2268231200Smm					return (ARCHIVE_OK);
2269231200Smm				}
2270231200Smm				if (!lzh_make_fake_table(&(ds->lt),
2271231200Smm				    lzh_br_bits(br, ds->lt.len_bits)))
2272231200Smm					goto failed;/* Invalid data */
2273231200Smm				lzh_br_consume(br, ds->lt.len_bits);
2274231200Smm				ds->state = ST_RD_POS_DATA_1;
2275231200Smm				break;
2276231200Smm			} else if (ds->lt.len_avail > ds->lt.len_size)
2277231200Smm				goto failed;/* Invalid data */
2278231200Smm			ds->loop = 0;
2279231200Smm			memset(ds->lt.freq, 0, sizeof(ds->lt.freq));
2280231200Smm			/* FALL THROUGH */
2281231200Smm		case ST_RD_LITERAL_3:
2282231200Smm			i = ds->loop;
2283231200Smm			while (i < ds->lt.len_avail) {
2284231200Smm				if (!lzh_br_read_ahead(strm, br,
2285231200Smm				    ds->pt.max_bits)) {
2286231200Smm					if (last)
2287231200Smm						goto failed;/* Truncated data.*/
2288231200Smm					ds->loop = i;
2289231200Smm					ds->state = ST_RD_LITERAL_3;
2290231200Smm					return (ARCHIVE_OK);
2291231200Smm				}
2292231200Smm				rbits = lzh_br_bits(br, ds->pt.max_bits);
2293231200Smm				c = lzh_decode_huffman(&(ds->pt), rbits);
2294231200Smm				if (c > 2) {
2295231200Smm					/* Note: 'c' will never be more than
2296231200Smm					 * eighteen since it's limited by
2297231200Smm					 * PT_BITLEN_SIZE, which is being set
2298231200Smm					 * to ds->pt.len_size through
2299231200Smm					 * ds->literal_pt_len_size. */
2300231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2301231200Smm					c -= 2;
2302231200Smm					ds->lt.freq[c]++;
2303231200Smm					ds->lt.bitlen[i++] = c;
2304231200Smm				} else if (c == 0) {
2305231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2306231200Smm					ds->lt.bitlen[i++] = 0;
2307231200Smm				} else {
2308231200Smm					/* c == 1 or c == 2 */
2309231200Smm					int n = (c == 1)?4:9;
2310231200Smm					if (!lzh_br_read_ahead(strm, br,
2311231200Smm					     ds->pt.bitlen[c] + n)) {
2312231200Smm						if (last) /* Truncated data. */
2313231200Smm							goto failed;
2314231200Smm						ds->loop = i;
2315231200Smm						ds->state = ST_RD_LITERAL_3;
2316231200Smm						return (ARCHIVE_OK);
2317231200Smm					}
2318231200Smm					lzh_br_consume(br, ds->pt.bitlen[c]);
2319231200Smm					c = lzh_br_bits(br, n);
2320231200Smm					lzh_br_consume(br, n);
2321231200Smm					c += (n == 4)?3:20;
2322231200Smm					if (i + c > ds->lt.len_avail)
2323231200Smm						goto failed;/* Invalid data */
2324231200Smm					memset(&(ds->lt.bitlen[i]), 0, c);
2325231200Smm					i += c;
2326231200Smm				}
2327231200Smm			}
2328231200Smm			if (i > ds->lt.len_avail ||
2329231200Smm			    !lzh_make_huffman_table(&(ds->lt)))
2330231200Smm				goto failed;/* Invalid data */
2331231200Smm			/* FALL THROUGH */
2332231200Smm		case ST_RD_POS_DATA_1:
2333231200Smm			/*
2334231200Smm			 * Read a position table compressed in huffman
2335231200Smm			 * coding.
2336231200Smm			 */
2337231200Smm			ds->pt.len_size = ds->pos_pt_len_size;
2338231200Smm			ds->pt.len_bits = ds->pos_pt_len_bits;
2339231200Smm			ds->reading_position = 1;
2340231200Smm			ds->state = ST_RD_PT_1;
2341231200Smm			break;
2342231200Smm		case ST_GET_LITERAL:
2343231200Smm			return (100);
2344231200Smm		}
2345231200Smm	}
2346231200Smmfailed:
2347231200Smm	return (ds->error = ARCHIVE_FAILED);
2348231200Smm}
2349231200Smm
2350231200Smmstatic int
2351231200Smmlzh_decode_blocks(struct lzh_stream *strm, int last)
2352231200Smm{
2353231200Smm	struct lzh_dec *ds = strm->ds;
2354231200Smm	struct lzh_br bre = ds->br;
2355231200Smm	struct huffman *lt = &(ds->lt);
2356231200Smm	struct huffman *pt = &(ds->pt);
2357231200Smm	unsigned char *w_buff = ds->w_buff;
2358231200Smm	unsigned char *lt_bitlen = lt->bitlen;
2359231200Smm	unsigned char *pt_bitlen = pt->bitlen;
2360231200Smm	int blocks_avail = ds->blocks_avail, c = 0;
2361231200Smm	int copy_len = ds->copy_len, copy_pos = ds->copy_pos;
2362231200Smm	int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
2363231200Smm	int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits;
2364231200Smm	int state = ds->state;
2365231200Smm
2366231200Smm	for (;;) {
2367231200Smm		switch (state) {
2368231200Smm		case ST_GET_LITERAL:
2369231200Smm			for (;;) {
2370231200Smm				if (blocks_avail == 0) {
2371231200Smm					/* We have decoded all blocks.
2372231200Smm					 * Let's handle next blocks. */
2373231200Smm					ds->state = ST_RD_BLOCK;
2374231200Smm					ds->br = bre;
2375231200Smm					ds->blocks_avail = 0;
2376231200Smm					ds->w_pos = w_pos;
2377231200Smm					ds->copy_pos = 0;
2378231200Smm					return (100);
2379231200Smm				}
2380231200Smm
2381231200Smm				/* lzh_br_read_ahead() always try to fill the
2382231200Smm				 * cache buffer up. In specific situation we
2383231200Smm				 * are close to the end of the data, the cache
2384231200Smm				 * buffer will not be full and thus we have to
2385231200Smm				 * determine if the cache buffer has some bits
2386231200Smm				 * as much as we need after lzh_br_read_ahead()
2387231200Smm				 * failed. */
2388231200Smm				if (!lzh_br_read_ahead(strm, &bre,
2389231200Smm				    lt_max_bits)) {
2390231200Smm					if (!last)
2391231200Smm						goto next_data;
2392231200Smm					/* Remaining bits are less than
2393231200Smm					 * maximum bits(lt.max_bits) but maybe
2394231200Smm					 * it still remains as much as we need,
2395231200Smm					 * so we should try to use it with
2396231200Smm					 * dummy bits. */
2397231200Smm					c = lzh_decode_huffman(lt,
2398231200Smm					      lzh_br_bits_forced(&bre,
2399231200Smm					        lt_max_bits));
2400231200Smm					lzh_br_consume(&bre, lt_bitlen[c]);
2401231200Smm					if (!lzh_br_has(&bre, 0))
2402231200Smm						goto failed;/* Over read. */
2403231200Smm				} else {
2404231200Smm					c = lzh_decode_huffman(lt,
2405231200Smm					      lzh_br_bits(&bre, lt_max_bits));
2406231200Smm					lzh_br_consume(&bre, lt_bitlen[c]);
2407231200Smm				}
2408231200Smm				blocks_avail--;
2409231200Smm				if (c > UCHAR_MAX)
2410231200Smm					/* Current block is a match data. */
2411231200Smm					break;
2412231200Smm				/*
2413231200Smm				 * 'c' is exactly a literal code.
2414231200Smm				 */
2415231200Smm				/* Save a decoded code to reference it
2416231200Smm				 * afterward. */
2417231200Smm				w_buff[w_pos] = c;
2418231200Smm				if (++w_pos >= w_size) {
2419231200Smm					w_pos = 0;
2420302001Smm					lzh_emit_window(strm, w_size);
2421302001Smm					goto next_data;
2422231200Smm				}
2423231200Smm			}
2424231200Smm			/* 'c' is the length of a match pattern we have
2425231200Smm			 * already extracted, which has be stored in
2426231200Smm			 * window(ds->w_buff). */
2427231200Smm			copy_len = c - (UCHAR_MAX + 1) + MINMATCH;
2428231200Smm			/* FALL THROUGH */
2429231200Smm		case ST_GET_POS_1:
2430231200Smm			/*
2431231200Smm			 * Get a reference position.
2432231200Smm			 */
2433231200Smm			if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) {
2434231200Smm				if (!last) {
2435231200Smm					state = ST_GET_POS_1;
2436231200Smm					ds->copy_len = copy_len;
2437231200Smm					goto next_data;
2438231200Smm				}
2439231200Smm				copy_pos = lzh_decode_huffman(pt,
2440231200Smm				    lzh_br_bits_forced(&bre, pt_max_bits));
2441231200Smm				lzh_br_consume(&bre, pt_bitlen[copy_pos]);
2442231200Smm				if (!lzh_br_has(&bre, 0))
2443231200Smm					goto failed;/* Over read. */
2444231200Smm			} else {
2445231200Smm				copy_pos = lzh_decode_huffman(pt,
2446231200Smm				    lzh_br_bits(&bre, pt_max_bits));
2447231200Smm				lzh_br_consume(&bre, pt_bitlen[copy_pos]);
2448231200Smm			}
2449231200Smm			/* FALL THROUGH */
2450231200Smm		case ST_GET_POS_2:
2451231200Smm			if (copy_pos > 1) {
2452231200Smm				/* We need an additional adjustment number to
2453231200Smm				 * the position. */
2454231200Smm				int p = copy_pos - 1;
2455231200Smm				if (!lzh_br_read_ahead(strm, &bre, p)) {
2456231200Smm					if (last)
2457231200Smm						goto failed;/* Truncated data.*/
2458231200Smm					state = ST_GET_POS_2;
2459231200Smm					ds->copy_len = copy_len;
2460231200Smm					ds->copy_pos = copy_pos;
2461231200Smm					goto next_data;
2462231200Smm				}
2463231200Smm				copy_pos = (1 << p) + lzh_br_bits(&bre, p);
2464231200Smm				lzh_br_consume(&bre, p);
2465231200Smm			}
2466231200Smm			/* The position is actually a distance from the last
2467231200Smm			 * code we had extracted and thus we have to convert
2468231200Smm			 * it to a position of the window. */
2469231200Smm			copy_pos = (w_pos - copy_pos - 1) & w_mask;
2470231200Smm			/* FALL THROUGH */
2471231200Smm		case ST_COPY_DATA:
2472231200Smm			/*
2473231200Smm			 * Copy `copy_len' bytes as extracted data from
2474231200Smm			 * the window into the output buffer.
2475231200Smm			 */
2476231200Smm			for (;;) {
2477231200Smm				int l;
2478231200Smm
2479231200Smm				l = copy_len;
2480231200Smm				if (copy_pos > w_pos) {
2481231200Smm					if (l > w_size - copy_pos)
2482231200Smm						l = w_size - copy_pos;
2483231200Smm				} else {
2484231200Smm					if (l > w_size - w_pos)
2485231200Smm						l = w_size - w_pos;
2486231200Smm				}
2487231200Smm				if ((copy_pos + l < w_pos)
2488231200Smm				    || (w_pos + l < copy_pos)) {
2489231200Smm					/* No overlap. */
2490231200Smm					memcpy(w_buff + w_pos,
2491231200Smm					    w_buff + copy_pos, l);
2492231200Smm				} else {
2493231200Smm					const unsigned char *s;
2494231200Smm					unsigned char *d;
2495231200Smm					int li;
2496231200Smm
2497231200Smm					d = w_buff + w_pos;
2498231200Smm					s = w_buff + copy_pos;
2499302001Smm					for (li = 0; li < l-1;) {
2500302001Smm						d[li] = s[li];li++;
2501302001Smm						d[li] = s[li];li++;
2502302001Smm					}
2503302001Smm					if (li < l)
2504231200Smm						d[li] = s[li];
2505231200Smm				}
2506302001Smm				w_pos += l;
2507302001Smm				if (w_pos == w_size) {
2508302001Smm					w_pos = 0;
2509302001Smm					lzh_emit_window(strm, w_size);
2510302001Smm					if (copy_len <= l)
2511302001Smm						state = ST_GET_LITERAL;
2512302001Smm					else {
2513302001Smm						state = ST_COPY_DATA;
2514302001Smm						ds->copy_len = copy_len - l;
2515302001Smm						ds->copy_pos =
2516302001Smm						    (copy_pos + l) & w_mask;
2517231200Smm					}
2518302001Smm					goto next_data;
2519231200Smm				}
2520231200Smm				if (copy_len <= l)
2521231200Smm					/* A copy of current pattern ended. */
2522231200Smm					break;
2523231200Smm				copy_len -= l;
2524231200Smm				copy_pos = (copy_pos + l) & w_mask;
2525231200Smm			}
2526231200Smm			state = ST_GET_LITERAL;
2527231200Smm			break;
2528231200Smm		}
2529231200Smm	}
2530231200Smmfailed:
2531231200Smm	return (ds->error = ARCHIVE_FAILED);
2532231200Smmnext_data:
2533231200Smm	ds->br = bre;
2534231200Smm	ds->blocks_avail = blocks_avail;
2535231200Smm	ds->state = state;
2536231200Smm	ds->w_pos = w_pos;
2537231200Smm	return (ARCHIVE_OK);
2538231200Smm}
2539231200Smm
2540231200Smmstatic int
2541231200Smmlzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
2542231200Smm{
2543231200Smm	int bits;
2544231200Smm
2545231200Smm	if (hf->bitlen == NULL) {
2546231200Smm		hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0]));
2547231200Smm		if (hf->bitlen == NULL)
2548231200Smm			return (ARCHIVE_FATAL);
2549231200Smm	}
2550231200Smm	if (hf->tbl == NULL) {
2551231200Smm		if (tbl_bits < HTBL_BITS)
2552231200Smm			bits = tbl_bits;
2553231200Smm		else
2554231200Smm			bits = HTBL_BITS;
2555248616Smm		hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
2556231200Smm		if (hf->tbl == NULL)
2557231200Smm			return (ARCHIVE_FATAL);
2558231200Smm	}
2559231200Smm	if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
2560231200Smm		hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
2561231200Smm		hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
2562231200Smm		if (hf->tree == NULL)
2563231200Smm			return (ARCHIVE_FATAL);
2564231200Smm	}
2565248616Smm	hf->len_size = (int)len_size;
2566231200Smm	hf->tbl_bits = tbl_bits;
2567231200Smm	return (ARCHIVE_OK);
2568231200Smm}
2569231200Smm
2570231200Smmstatic void
2571231200Smmlzh_huffman_free(struct huffman *hf)
2572231200Smm{
2573231200Smm	free(hf->bitlen);
2574231200Smm	free(hf->tbl);
2575231200Smm	free(hf->tree);
2576231200Smm}
2577231200Smm
2578316338Smmstatic const char bitlen_tbl[0x400] = {
2579302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2580302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2581302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2582302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2583302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2584302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2585302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2586302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2587302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2588302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2589302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2590302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2591302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2592302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2593302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2594302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2595302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2596302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2597302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2598302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2599302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2600302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2601302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2602302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2603302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2604302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2605302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2606302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2607302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2608302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2609302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2610302001Smm	 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2611302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2612302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2613302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2614302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2615302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2616302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2617302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2618302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2619302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2620302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2621302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2622302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2623302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2624302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2625302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2626302001Smm	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
2627302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2628302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2629302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2630302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2631302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2632302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2633302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2634302001Smm	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
2635302001Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2636302001Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2637302001Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2638302001Smm	10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2639302001Smm	11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2640302001Smm	11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2641302001Smm	12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2642302001Smm	13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16,  0
2643302001Smm};
2644231200Smmstatic int
2645231200Smmlzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
2646231200Smm{
2647231200Smm	struct lzh_dec *ds = strm->ds;
2648302001Smm	struct lzh_br *br = &(ds->br);
2649231200Smm	int c, i;
2650231200Smm
2651302001Smm	for (i = start; i < end; ) {
2652231200Smm		/*
2653231200Smm		 *  bit pattern     the number we need
2654231200Smm		 *     000           ->  0
2655231200Smm		 *     001           ->  1
2656231200Smm		 *     010           ->  2
2657231200Smm		 *     ...
2658231200Smm		 *     110           ->  6
2659231200Smm		 *     1110          ->  7
2660231200Smm		 *     11110         ->  8
2661231200Smm		 *     ...
2662231200Smm		 *     1111111111110 ->  16
2663231200Smm		 */
2664231200Smm		if (!lzh_br_read_ahead(strm, br, 3))
2665231200Smm			return (i);
2666231200Smm		if ((c = lzh_br_bits(br, 3)) == 7) {
2667231200Smm			if (!lzh_br_read_ahead(strm, br, 13))
2668231200Smm				return (i);
2669302001Smm			c = bitlen_tbl[lzh_br_bits(br, 13) & 0x3FF];
2670302001Smm			if (c)
2671302001Smm				lzh_br_consume(br, c - 3);
2672302001Smm			else
2673231200Smm				return (-1);/* Invalid data. */
2674231200Smm		} else
2675231200Smm			lzh_br_consume(br, 3);
2676231200Smm		ds->pt.bitlen[i++] = c;
2677231200Smm		ds->pt.freq[c]++;
2678231200Smm	}
2679231200Smm	return (i);
2680231200Smm}
2681231200Smm
2682231200Smmstatic int
2683231200Smmlzh_make_fake_table(struct huffman *hf, uint16_t c)
2684231200Smm{
2685231200Smm	if (c >= hf->len_size)
2686231200Smm		return (0);
2687231200Smm	hf->tbl[0] = c;
2688231200Smm	hf->max_bits = 0;
2689231200Smm	hf->shift_bits = 0;
2690231200Smm	hf->bitlen[hf->tbl[0]] = 0;
2691231200Smm	return (1);
2692231200Smm}
2693231200Smm
2694231200Smm/*
2695231200Smm * Make a huffman coding table.
2696231200Smm */
2697231200Smmstatic int
2698231200Smmlzh_make_huffman_table(struct huffman *hf)
2699231200Smm{
2700231200Smm	uint16_t *tbl;
2701231200Smm	const unsigned char *bitlen;
2702231200Smm	int bitptn[17], weight[17];
2703231200Smm	int i, maxbits = 0, ptn, tbl_size, w;
2704231200Smm	int diffbits, len_avail;
2705231200Smm
2706231200Smm	/*
2707231200Smm	 * Initialize bit patterns.
2708231200Smm	 */
2709231200Smm	ptn = 0;
2710231200Smm	for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
2711231200Smm		bitptn[i] = ptn;
2712231200Smm		weight[i] = w;
2713231200Smm		if (hf->freq[i]) {
2714231200Smm			ptn += hf->freq[i] * w;
2715231200Smm			maxbits = i;
2716231200Smm		}
2717231200Smm	}
2718231200Smm	if (ptn != 0x10000 || maxbits > hf->tbl_bits)
2719231200Smm		return (0);/* Invalid */
2720231200Smm
2721231200Smm	hf->max_bits = maxbits;
2722231200Smm
2723231200Smm	/*
2724231200Smm	 * Cut out extra bits which we won't house in the table.
2725231200Smm	 * This preparation reduces the same calculation in the for-loop
2726231200Smm	 * making the table.
2727231200Smm	 */
2728231200Smm	if (maxbits < 16) {
2729231200Smm		int ebits = 16 - maxbits;
2730231200Smm		for (i = 1; i <= maxbits; i++) {
2731231200Smm			bitptn[i] >>= ebits;
2732231200Smm			weight[i] >>= ebits;
2733231200Smm		}
2734231200Smm	}
2735231200Smm	if (maxbits > HTBL_BITS) {
2736302001Smm		unsigned htbl_max;
2737231200Smm		uint16_t *p;
2738231200Smm
2739231200Smm		diffbits = maxbits - HTBL_BITS;
2740231200Smm		for (i = 1; i <= HTBL_BITS; i++) {
2741231200Smm			bitptn[i] >>= diffbits;
2742231200Smm			weight[i] >>= diffbits;
2743231200Smm		}
2744231200Smm		htbl_max = bitptn[HTBL_BITS] +
2745231200Smm		    weight[HTBL_BITS] * hf->freq[HTBL_BITS];
2746231200Smm		p = &(hf->tbl[htbl_max]);
2747231200Smm		while (p < &hf->tbl[1U<<HTBL_BITS])
2748231200Smm			*p++ = 0;
2749231200Smm	} else
2750231200Smm		diffbits = 0;
2751231200Smm	hf->shift_bits = diffbits;
2752231200Smm
2753231200Smm	/*
2754231200Smm	 * Make the table.
2755231200Smm	 */
2756231200Smm	tbl_size = 1 << HTBL_BITS;
2757231200Smm	tbl = hf->tbl;
2758231200Smm	bitlen = hf->bitlen;
2759231200Smm	len_avail = hf->len_avail;
2760231200Smm	hf->tree_used = 0;
2761231200Smm	for (i = 0; i < len_avail; i++) {
2762231200Smm		uint16_t *p;
2763231200Smm		int len, cnt;
2764231200Smm		uint16_t bit;
2765231200Smm		int extlen;
2766231200Smm		struct htree_t *ht;
2767231200Smm
2768231200Smm		if (bitlen[i] == 0)
2769231200Smm			continue;
2770231200Smm		/* Get a bit pattern */
2771231200Smm		len = bitlen[i];
2772231200Smm		ptn = bitptn[len];
2773231200Smm		cnt = weight[len];
2774231200Smm		if (len <= HTBL_BITS) {
2775231200Smm			/* Calculate next bit pattern */
2776231200Smm			if ((bitptn[len] = ptn + cnt) > tbl_size)
2777231200Smm				return (0);/* Invalid */
2778231200Smm			/* Update the table */
2779231200Smm			p = &(tbl[ptn]);
2780302001Smm			if (cnt > 7) {
2781302001Smm				uint16_t *pc;
2782302001Smm
2783302001Smm				cnt -= 8;
2784302001Smm				pc = &p[cnt];
2785302001Smm				pc[0] = (uint16_t)i;
2786302001Smm				pc[1] = (uint16_t)i;
2787302001Smm				pc[2] = (uint16_t)i;
2788302001Smm				pc[3] = (uint16_t)i;
2789302001Smm				pc[4] = (uint16_t)i;
2790302001Smm				pc[5] = (uint16_t)i;
2791302001Smm				pc[6] = (uint16_t)i;
2792302001Smm				pc[7] = (uint16_t)i;
2793302001Smm				if (cnt > 7) {
2794302001Smm					cnt -= 8;
2795302001Smm					memcpy(&p[cnt], pc,
2796302001Smm						8 * sizeof(uint16_t));
2797302001Smm					pc = &p[cnt];
2798302001Smm					while (cnt > 15) {
2799302001Smm						cnt -= 16;
2800302001Smm						memcpy(&p[cnt], pc,
2801302001Smm							16 * sizeof(uint16_t));
2802302001Smm					}
2803302001Smm				}
2804302001Smm				if (cnt)
2805302001Smm					memcpy(p, pc, cnt * sizeof(uint16_t));
2806302001Smm			} else {
2807302001Smm				while (cnt > 1) {
2808302001Smm					p[--cnt] = (uint16_t)i;
2809302001Smm					p[--cnt] = (uint16_t)i;
2810302001Smm				}
2811302001Smm				if (cnt)
2812302001Smm					p[--cnt] = (uint16_t)i;
2813302001Smm			}
2814231200Smm			continue;
2815231200Smm		}
2816231200Smm
2817231200Smm		/*
2818231200Smm		 * A bit length is too big to be housed to a direct table,
2819231200Smm		 * so we use a tree model for its extra bits.
2820231200Smm		 */
2821231200Smm		bitptn[len] = ptn + cnt;
2822231200Smm		bit = 1U << (diffbits -1);
2823231200Smm		extlen = len - HTBL_BITS;
2824231200Smm
2825231200Smm		p = &(tbl[ptn >> diffbits]);
2826231200Smm		if (*p == 0) {
2827231200Smm			*p = len_avail + hf->tree_used;
2828231200Smm			ht = &(hf->tree[hf->tree_used++]);
2829231200Smm			if (hf->tree_used > hf->tree_avail)
2830231200Smm				return (0);/* Invalid */
2831231200Smm			ht->left = 0;
2832231200Smm			ht->right = 0;
2833231200Smm		} else {
2834231200Smm			if (*p < len_avail ||
2835231200Smm			    *p >= (len_avail + hf->tree_used))
2836231200Smm				return (0);/* Invalid */
2837231200Smm			ht = &(hf->tree[*p - len_avail]);
2838231200Smm		}
2839231200Smm		while (--extlen > 0) {
2840231200Smm			if (ptn & bit) {
2841231200Smm				if (ht->left < len_avail) {
2842231200Smm					ht->left = len_avail + hf->tree_used;
2843231200Smm					ht = &(hf->tree[hf->tree_used++]);
2844231200Smm					if (hf->tree_used > hf->tree_avail)
2845231200Smm						return (0);/* Invalid */
2846231200Smm					ht->left = 0;
2847231200Smm					ht->right = 0;
2848231200Smm				} else {
2849231200Smm					ht = &(hf->tree[ht->left - len_avail]);
2850231200Smm				}
2851231200Smm			} else {
2852231200Smm				if (ht->right < len_avail) {
2853231200Smm					ht->right = len_avail + hf->tree_used;
2854231200Smm					ht = &(hf->tree[hf->tree_used++]);
2855231200Smm					if (hf->tree_used > hf->tree_avail)
2856231200Smm						return (0);/* Invalid */
2857231200Smm					ht->left = 0;
2858231200Smm					ht->right = 0;
2859231200Smm				} else {
2860231200Smm					ht = &(hf->tree[ht->right - len_avail]);
2861231200Smm				}
2862231200Smm			}
2863231200Smm			bit >>= 1;
2864231200Smm		}
2865231200Smm		if (ptn & bit) {
2866231200Smm			if (ht->left != 0)
2867231200Smm				return (0);/* Invalid */
2868231200Smm			ht->left = (uint16_t)i;
2869231200Smm		} else {
2870231200Smm			if (ht->right != 0)
2871231200Smm				return (0);/* Invalid */
2872231200Smm			ht->right = (uint16_t)i;
2873231200Smm		}
2874231200Smm	}
2875231200Smm	return (1);
2876231200Smm}
2877231200Smm
2878231200Smmstatic int
2879231200Smmlzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
2880231200Smm{
2881231200Smm	struct htree_t *ht;
2882231200Smm	int extlen;
2883231200Smm
2884231200Smm	ht = hf->tree;
2885231200Smm	extlen = hf->shift_bits;
2886231200Smm	while (c >= hf->len_avail) {
2887231200Smm		c -= hf->len_avail;
2888231200Smm		if (extlen-- <= 0 || c >= hf->tree_used)
2889231200Smm			return (0);
2890231200Smm		if (rbits & (1U << extlen))
2891231200Smm			c = ht[c].left;
2892231200Smm		else
2893231200Smm			c = ht[c].right;
2894231200Smm	}
2895231200Smm	return (c);
2896231200Smm}
2897231200Smm
2898231200Smmstatic inline int
2899231200Smmlzh_decode_huffman(struct huffman *hf, unsigned rbits)
2900231200Smm{
2901231200Smm	int c;
2902231200Smm	/*
2903231200Smm	 * At first search an index table for a bit pattern.
2904231200Smm	 * If it fails, search a huffman tree for.
2905231200Smm	 */
2906231200Smm	c = hf->tbl[rbits >> hf->shift_bits];
2907302001Smm	if (c < hf->len_avail || hf->len_avail == 0)
2908231200Smm		return (c);
2909231200Smm	/* This bit pattern needs to be found out at a huffman tree. */
2910231200Smm	return (lzh_decode_huffman_tree(hf, rbits, c));
2911231200Smm}
2912231200Smm
2913