xref: /freebsd/contrib/libarchive/libarchive/archive_read_support_format_7zip.c (revision 2e113ef82465598b8c26e0ca415fbe90677fbd47)
1 /*-
2  * Copyright (c) 2011 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "archive_platform.h"
27 
28 #ifdef HAVE_ERRNO_H
29 #include <errno.h>
30 #endif
31 #if HAVE_STDINT_H
32 #include <stdint.h>
33 #endif
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37 #ifdef HAVE_BZLIB_H
38 #include <bzlib.h>
39 #endif
40 #ifdef HAVE_LZMA_H
41 #include <lzma.h>
42 #endif
43 #ifdef HAVE_ZLIB_H
44 #include <zlib.h>
45 #endif
46 #ifdef HAVE_ZSTD_H
47 #include <zstd.h>
48 #endif
49 
50 #include "archive.h"
51 #include "archive_entry.h"
52 #include "archive_entry_locale.h"
53 #include "archive_ppmd7_private.h"
54 #include "archive_private.h"
55 #include "archive_read_private.h"
56 #include "archive_time_private.h"
57 #include "archive_endian.h"
58 
59 #ifndef HAVE_ZLIB_H
60 #include "archive_crc32.h"
61 #endif
62 
63 #define _7ZIP_SIGNATURE	"7z\xBC\xAF\x27\x1C"
64 #define SFX_MIN_ADDR	0x27000
65 #define SFX_MAX_ADDR	0x60000
66 #define SFX_MAX_OFFSET	(SFX_MAX_ADDR - SFX_MIN_ADDR)
67 
68 /*
69  * PE format
70  */
71 #define PE_DOS_HDR_LEN				0x40
72 #define PE_DOS_HDR_ELFANEW_OFFSET	0x3c
73 #define PE_COFF_HDR_LEN				0x18
74 #define PE_COFF_HDR_SEC_CNT_OFFSET	0x6
75 #define PE_COFF_HDR_OPT_SZ_OFFSET	0x14
76 #define PE_SEC_HDR_LEN 				0x28
77 #define PE_SEC_HDR_RAW_ADDR_OFFSET	0x14
78 #define PE_SEC_HDR_RAW_SZ_OFFSET	0x10
79 
80 /*
81  * ELF format
82  */
83 #define ELF_HDR_MIN_LEN 0x34
84 #define ELF_HDR_EI_CLASS_OFFSET 0x04
85 #define ELF_HDR_EI_DATA_OFFSET 0x05
86 
87 /*
88  * Codec ID
89  */
90 #define _7Z_COPY	0
91 #define _7Z_LZMA	0x030101
92 #define _7Z_LZMA2	0x21
93 #define _7Z_DEFLATE	0x040108
94 #define _7Z_BZ2		0x040202
95 #define _7Z_PPMD	0x030401
96 #define _7Z_DELTA	0x03
97 #define _7Z_CRYPTO_MAIN_ZIP			0x06F10101 /* Main Zip crypto algo */
98 #define _7Z_CRYPTO_RAR_29			0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */
99 #define _7Z_CRYPTO_AES_256_SHA_256	0x06F10701 /* AES-256 + SHA-256 */
100 
101 
102 #define _7Z_X86		0x03030103
103 #define _7Z_X86_BCJ2	0x0303011B
104 #define _7Z_POWERPC	0x03030205
105 #define _7Z_IA64	0x03030401
106 #define _7Z_ARM		0x03030501
107 #define _7Z_ARMTHUMB	0x03030701
108 #define _7Z_ARM64	0xa
109 #define _7Z_RISCV	0xb
110 #define _7Z_SPARC	0x03030805
111 
112 #define _7Z_ZSTD	0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
113 
114 /*
115  * 7-Zip header property IDs.
116  */
117 #define kEnd			0x00
118 #define kHeader			0x01
119 #define kArchiveProperties	0x02
120 #define kAdditionalStreamsInfo	0x03
121 #define kMainStreamsInfo	0x04
122 #define kFilesInfo		0x05
123 #define kPackInfo		0x06
124 #define kUnPackInfo		0x07
125 #define kSubStreamsInfo		0x08
126 #define kSize			0x09
127 #define kCRC			0x0A
128 #define kFolder			0x0B
129 #define kCodersUnPackSize	0x0C
130 #define kNumUnPackStream	0x0D
131 #define kEmptyStream		0x0E
132 #define kEmptyFile		0x0F
133 #define kAnti			0x10
134 #define kName			0x11
135 #define kCTime			0x12
136 #define kATime			0x13
137 #define kMTime			0x14
138 #define kAttributes		0x15
139 #define kEncodedHeader		0x17
140 #define kDummy			0x19
141 
142 // Check that some windows file attribute constants are defined.
143 // Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
144 #ifndef FILE_ATTRIBUTE_READONLY
145 #define FILE_ATTRIBUTE_READONLY 0x00000001
146 #endif
147 
148 #ifndef FILE_ATTRIBUTE_HIDDEN
149 #define FILE_ATTRIBUTE_HIDDEN 0x00000002
150 #endif
151 
152 #ifndef FILE_ATTRIBUTE_SYSTEM
153 #define FILE_ATTRIBUTE_SYSTEM 0x00000004
154 #endif
155 
156 #ifndef FILE_ATTRIBUTE_DIRECTORY
157 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010
158 #endif
159 
160 // This value is defined in 7zip with the comment "trick for Unix".
161 //
162 // 7z archives created on unix have this bit set in the high 16 bits of
163 // the attr field along with the unix permissions.
164 #define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
165 
166 struct _7z_digests {
167 	unsigned char	*defineds;
168 	uint32_t	*digests;
169 };
170 
171 struct _7z_folder {
172 	uint64_t		 numCoders;
173 	struct _7z_coder {
174 		unsigned long	 codec;
175 		uint64_t	 numInStreams;
176 		uint64_t	 numOutStreams;
177 		uint64_t	 propertiesSize;
178 		unsigned char	*properties;
179 	} *coders;
180 	uint64_t		 numBindPairs;
181 	struct {
182 		uint64_t	 inIndex;
183 		uint64_t	 outIndex;
184 	} *bindPairs;
185 	uint64_t		 numPackedStreams;
186 	uint64_t		*packedStreams;
187 	uint64_t		 numInStreams;
188 	uint64_t		 numOutStreams;
189 	uint64_t		*unPackSize;
190 	unsigned char		 digest_defined;
191 	uint32_t		 digest;
192 	uint64_t		 numUnpackStreams;
193 	uint32_t		 packIndex;
194 	/* Unoperated bytes. */
195 	uint64_t		 skipped_bytes;
196 };
197 
198 struct _7z_coders_info {
199 	uint64_t		 numFolders;
200 	struct _7z_folder	*folders;
201 	uint64_t		 dataStreamIndex;
202 };
203 
204 struct _7z_pack_info {
205 	uint64_t		 pos;
206 	uint64_t		 numPackStreams;
207 	uint64_t		*sizes;
208 	struct _7z_digests	 digest;
209 	/* Calculated from pos and numPackStreams. */
210 	uint64_t		*positions;
211 };
212 
213 struct _7z_substream_info {
214 	size_t			 unpack_streams;
215 	uint64_t		*unpackSizes;
216 	unsigned char		*digestsDefined;
217 	uint32_t		*digests;
218 };
219 
220 struct _7z_stream_info {
221 	struct _7z_pack_info	 pi;
222 	struct _7z_coders_info	 ci;
223 	struct _7z_substream_info ss;
224 };
225 
226 struct _7z_header_info {
227 	uint64_t		 dataIndex;
228 
229 	unsigned char		*emptyStreamBools;
230 	unsigned char		*emptyFileBools;
231 	unsigned char		*antiBools;
232 	unsigned char		*attrBools;
233 };
234 
235 struct _7zip_entry {
236 	size_t			 name_len;
237 	unsigned char		*utf16name;
238 #if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
239 	const wchar_t		*wname;
240 #endif
241 	uint32_t		 folderIndex;
242 	uint32_t		 ssIndex;
243 	unsigned		 flg;
244 #define MTIME_IS_SET	(1<<0)
245 #define ATIME_IS_SET	(1<<1)
246 #define CTIME_IS_SET	(1<<2)
247 #define CRC32_IS_SET	(1<<3)
248 #define HAS_STREAM	(1<<4)
249 
250 	int64_t			 mtime;
251 	int64_t			 atime;
252 	int64_t			 ctime;
253 	uint32_t		 mtime_ns;
254 	uint32_t		 atime_ns;
255 	uint32_t		 ctime_ns;
256 	__LA_MODE_T		 mode;
257 	uint32_t		 attr;
258 };
259 
260 struct _7zip {
261 	/* Structural information about the archive. */
262 	struct _7z_stream_info	 si;
263 
264 	int			 header_is_being_read;
265 	int			 header_is_encoded;
266 	uint64_t		 header_bytes_remaining;
267 	unsigned long		 header_crc32;
268 	/* Header offset to check that reading points of the file contents
269 	 * will not exceed the header. */
270 	uint64_t		 header_offset;
271 	/* Base offset of the archive file for a seek in case reading SFX. */
272 	uint64_t		 seek_base;
273 
274 	/* List of entries */
275 	size_t			 entries_remaining;
276 	uint64_t		 numFiles;
277 	struct _7zip_entry	*entries;
278 	struct _7zip_entry	*entry;
279 	unsigned char		*entry_names;
280 
281 	/* entry_bytes_remaining is the number of bytes we expect. */
282 	int64_t			 entry_offset;
283 	uint64_t		 entry_bytes_remaining;
284 
285 	/* Running CRC32 of the decompressed data */
286 	unsigned long		 entry_crc32;
287 
288 	/* Flags to mark progress of decompression. */
289 	char			 end_of_entry;
290 
291 	/* Uncompressed buffer control.  */
292 #define UBUFF_SIZE	(64 * 1024)
293 	unsigned char 		*uncompressed_buffer;
294 	unsigned char 		*uncompressed_buffer_pointer;
295 	size_t 			 uncompressed_buffer_size;
296 	size_t			 uncompressed_buffer_bytes_remaining;
297 
298 	/* Offset of the compressed data. */
299 	int64_t			 stream_offset;
300 
301 	/*
302 	 * Decompressing control data.
303 	 */
304 	unsigned		 folder_index;
305 	uint64_t		 folder_outbytes_remaining;
306 	unsigned		 pack_stream_index;
307 	unsigned		 pack_stream_remaining;
308 	uint64_t		 pack_stream_inbytes_remaining;
309 	size_t			 pack_stream_bytes_unconsumed;
310 
311 	/* The codec information of a folder. */
312 	unsigned long		 codec;
313 	unsigned long		 codec2;
314 
315 	/*
316 	 * Decompressor controllers.
317 	 */
318 	/* Decoding LZMA1 and LZMA2 data. */
319 #ifdef HAVE_LZMA_H
320 	lzma_stream		 lzstream;
321 	int			 lzstream_valid;
322 #endif
323 	/* Decoding bzip2 data. */
324 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
325 	bz_stream		 bzstream;
326 	int			 bzstream_valid;
327 #endif
328 	/* Decoding deflate data. */
329 #ifdef HAVE_ZLIB_H
330 	z_stream		 stream;
331 	int			 stream_valid;
332 #endif
333 	/* Decoding Zstandard data. */
334 #if HAVE_ZSTD_H
335 	ZSTD_DStream		 *zstd_dstream;
336 	int		         zstdstream_valid;
337 #endif
338 	/* Decoding PPMd data. */
339 	int			 ppmd7_stat;
340 	CPpmd7			 ppmd7_context;
341 	CPpmd7z_RangeDec	 range_dec;
342 	IByteIn			 bytein;
343 	struct {
344 		const unsigned char	*next_in;
345 		int64_t			 avail_in;
346 		int64_t			 total_in;
347 		int64_t			 stream_in;
348 		unsigned char		*next_out;
349 		int64_t			 avail_out;
350 		int64_t			 total_out;
351 		int			 overconsumed;
352 	} ppstream;
353 	int			 ppmd7_valid;
354 
355 	/* Decoding BCJ and BCJ2 data. */
356 	uint32_t		 bcj_state;
357 	size_t			 odd_bcj_size;
358 	unsigned char		 odd_bcj[4];
359 	/* Decoding BCJ data. */
360 	size_t			 bcj_prevPosT;
361 	uint32_t		 bcj_prevMask;
362 	uint32_t		 bcj_ip;
363 
364 	/* Decoding BCJ2 data. */
365 	size_t			 main_stream_bytes_remaining;
366 	unsigned char		*sub_stream_buff[3];
367 	size_t			 sub_stream_size[3];
368 	size_t			 sub_stream_bytes_remaining[3];
369 	unsigned char		*tmp_stream_buff;
370 	size_t			 tmp_stream_buff_size;
371 	size_t			 tmp_stream_bytes_avail;
372 	size_t			 tmp_stream_bytes_remaining;
373 #ifdef _LZMA_PROB32
374 #define CProb uint32_t
375 #else
376 #define CProb uint16_t
377 #endif
378 	CProb			 bcj2_p[256 + 2];
379 	uint8_t			 bcj2_prevByte;
380 	uint32_t		 bcj2_range;
381 	uint32_t		 bcj2_code;
382 	uint64_t		 bcj2_outPos;
383 
384 	/* Filename character-set conversion data. */
385 	struct archive_string_conv *sconv;
386 
387 	char			 format_name[64];
388 
389 	/* Custom value that is non-zero if this archive contains encrypted entries. */
390 	int			 has_encrypted_entries;
391 };
392 
393 /* Maximum entry size. This limitation prevents reading intentional
394  * corrupted 7-zip files on assuming there are not so many entries in
395  * the files. */
396 #define UMAX_ENTRY	ARCHIVE_LITERAL_ULL(100000000)
397 
398 static int	archive_read_format_7zip_has_encrypted_entries(struct archive_read *);
399 static int	archive_read_support_format_7zip_capabilities(struct archive_read *a);
400 static int	archive_read_format_7zip_bid(struct archive_read *, int);
401 static int	archive_read_format_7zip_cleanup(struct archive_read *);
402 static int	archive_read_format_7zip_read_data(struct archive_read *,
403 		    const void **, size_t *, int64_t *);
404 static int	archive_read_format_7zip_read_data_skip(struct archive_read *);
405 static int	archive_read_format_7zip_read_header(struct archive_read *,
406 		    struct archive_entry *);
407 static int	check_7zip_header_in_sfx(const char *);
408 static unsigned long decode_codec_id(const unsigned char *, size_t);
409 static int	decode_encoded_header_info(struct archive_read *,
410 		    struct _7z_stream_info *);
411 static int	decompress(struct archive_read *, struct _7zip *,
412 		    void *, size_t *, const void *, size_t *);
413 static ssize_t	extract_pack_stream(struct archive_read *, size_t);
414 static uint64_t folder_uncompressed_size(struct _7z_folder *);
415 static void	free_CodersInfo(struct _7z_coders_info *);
416 static void	free_Digest(struct _7z_digests *);
417 static void	free_Folder(struct _7z_folder *);
418 static void	free_Header(struct _7z_header_info *);
419 static void	free_PackInfo(struct _7z_pack_info *);
420 static void	free_StreamsInfo(struct _7z_stream_info *);
421 static void	free_SubStreamsInfo(struct _7z_substream_info *);
422 static int	free_decompression(struct archive_read *, struct _7zip *);
423 static ssize_t	get_uncompressed_data(struct archive_read *, const void **,
424 		    size_t, size_t);
425 static const unsigned char * header_bytes(struct archive_read *, size_t);
426 static int	init_decompression(struct archive_read *, struct _7zip *,
427 		    const struct _7z_coder *, const struct _7z_coder *);
428 static int	parse_7zip_uint64(struct archive_read *, uint64_t *);
429 static int	read_Bools(struct archive_read *, unsigned char *, size_t);
430 static int	read_CodersInfo(struct archive_read *,
431 		    struct _7z_coders_info *);
432 static int	read_Digests(struct archive_read *, struct _7z_digests *,
433 		    size_t);
434 static int	read_Folder(struct archive_read *, struct _7z_folder *);
435 static int	read_Header(struct archive_read *, struct _7z_header_info *,
436 		    int);
437 static int	read_PackInfo(struct archive_read *, struct _7z_pack_info *);
438 static int	read_StreamsInfo(struct archive_read *,
439 		    struct _7z_stream_info *);
440 static int	read_SubStreamsInfo(struct archive_read *,
441 		    struct _7z_substream_info *, struct _7z_folder *, size_t);
442 static int	read_Times(struct archive_read *, struct _7z_header_info *,
443 		    int);
444 static void	read_consume(struct archive_read *);
445 static ssize_t	read_stream(struct archive_read *, const void **, size_t,
446 		    size_t);
447 static int	seek_pack(struct archive_read *);
448 static int64_t	skip_stream(struct archive_read *, size_t);
449 static int	skip_sfx(struct archive_read *, const ssize_t);
450 static ssize_t	find_pe_overlay(struct archive_read *);
451 static ssize_t	find_elf_data_sec(struct archive_read *);
452 static int	slurp_central_directory(struct archive_read *, struct _7zip *,
453 		    struct _7z_header_info *);
454 static int	setup_decode_folder(struct archive_read *, struct _7z_folder *,
455 		    int);
456 static void	x86_Init(struct _7zip *);
457 static size_t	x86_Convert(struct _7zip *, uint8_t *, size_t);
458 static void	arm_Init(struct _7zip *);
459 static size_t	arm_Convert(struct _7zip *, uint8_t *, size_t);
460 static size_t	arm64_Convert(struct _7zip *, uint8_t *, size_t);
461 static ssize_t		Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
462 static size_t	sparc_Convert(struct _7zip *, uint8_t *, size_t);
463 static size_t	powerpc_Convert(struct _7zip *, uint8_t *, size_t);
464 
465 
466 int
archive_read_support_format_7zip(struct archive * _a)467 archive_read_support_format_7zip(struct archive *_a)
468 {
469 	struct archive_read *a = (struct archive_read *)_a;
470 	struct _7zip *zip;
471 	int r;
472 
473 	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
474 	    ARCHIVE_STATE_NEW, "archive_read_support_format_7zip");
475 
476 	zip = calloc(1, sizeof(*zip));
477 	if (zip == NULL) {
478 		archive_set_error(&a->archive, ENOMEM,
479 		    "Can't allocate 7zip data");
480 		return (ARCHIVE_FATAL);
481 	}
482 
483 	/*
484 	 * Until enough data has been read, we cannot tell about
485 	 * any encrypted entries yet.
486 	 */
487 	zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
488 
489 
490 	r = __archive_read_register_format(a,
491 	    zip,
492 	    "7zip",
493 	    archive_read_format_7zip_bid,
494 	    NULL,
495 	    archive_read_format_7zip_read_header,
496 	    archive_read_format_7zip_read_data,
497 	    archive_read_format_7zip_read_data_skip,
498 	    NULL,
499 	    archive_read_format_7zip_cleanup,
500 	    archive_read_support_format_7zip_capabilities,
501 	    archive_read_format_7zip_has_encrypted_entries);
502 
503 	if (r != ARCHIVE_OK)
504 		free(zip);
505 	return (ARCHIVE_OK);
506 }
507 
508 static int
archive_read_support_format_7zip_capabilities(struct archive_read * a)509 archive_read_support_format_7zip_capabilities(struct archive_read * a)
510 {
511 	(void)a; /* UNUSED */
512 	return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
513 			ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
514 }
515 
516 
517 static int
archive_read_format_7zip_has_encrypted_entries(struct archive_read * _a)518 archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a)
519 {
520 	if (_a && _a->format) {
521 		struct _7zip * zip = (struct _7zip *)_a->format->data;
522 		if (zip) {
523 			return zip->has_encrypted_entries;
524 		}
525 	}
526 	return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
527 }
528 
529 static int
archive_read_format_7zip_bid(struct archive_read * a,int best_bid)530 archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
531 {
532 	const char *p;
533 
534 	/* If someone has already bid more than 32, then avoid
535 	   trashing the look-ahead buffers with a seek. */
536 	if (best_bid > 32)
537 		return (-1);
538 
539 	if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
540 		return (0);
541 
542 	/* If first six bytes are the 7-Zip signature,
543 	 * return the bid right now. */
544 	if (memcmp(p, _7ZIP_SIGNATURE, 6) == 0)
545 		return (48);
546 
547 	/*
548 	 * It may a 7-Zip SFX archive file. If first two bytes are
549 	 * 'M' and 'Z' available on Windows or first four bytes are
550 	 * "\x7F\x45LF" available on posix like system, seek the 7-Zip
551 	 * signature. While find_pe_overlay can be performed without
552 	 * performing a seek, find_elf_data_sec requires one,
553 	 * thus a performance difference between the two is expected.
554 	 */
555 	if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
556 		const ssize_t min_addr = p[0] == 'M' ? find_pe_overlay(a) :
557 						       find_elf_data_sec(a);
558 		ssize_t offset = min_addr;
559 		ssize_t window = 4096;
560 		ssize_t bytes_avail;
561 		while (offset + window <= (min_addr + SFX_MAX_OFFSET)) {
562 			const char *buff = __archive_read_ahead(a,
563 					offset + window, &bytes_avail);
564 			if (buff == NULL) {
565 				/* Remaining bytes are less than window. */
566 				window >>= 1;
567 				if (window < 0x40)
568 					return (0);
569 				continue;
570 			}
571 			p = buff + offset;
572 			while (p + 32 < buff + bytes_avail) {
573 				int step = check_7zip_header_in_sfx(p);
574 				if (step == 0)
575 					return (48);
576 				p += step;
577 			}
578 			offset = p - buff;
579 		}
580 	}
581 	return (0);
582 }
583 
584 static int
check_7zip_header_in_sfx(const char * p)585 check_7zip_header_in_sfx(const char *p)
586 {
587 	switch ((unsigned char)p[5]) {
588 	case 0x1C:
589 		if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
590 			return (6);
591 		/*
592 		 * Test the CRC because its extraction code has 7-Zip
593 		 * Magic Code, so we should do this in order not to
594 		 * make a mis-detection.
595 		 */
596 		if (crc32(0, (const unsigned char *)p + 12, 20)
597 			!= archive_le32dec(p + 8))
598 			return (6);
599 		/* Hit the header! */
600 		return (0);
601 	case 0x37: return (5);
602 	case 0x7A: return (4);
603 	case 0xBC: return (3);
604 	case 0xAF: return (2);
605 	case 0x27: return (1);
606 	default: return (6);
607 	}
608 }
609 
610 static int
skip_sfx(struct archive_read * a,const ssize_t min_addr)611 skip_sfx(struct archive_read *a, const ssize_t min_addr)
612 {
613 	const void *h;
614 	const char *p, *q;
615 	size_t skip, offset;
616 	ssize_t bytes, window;
617 
618 	if (__archive_read_seek(a, min_addr, SEEK_SET) < 0)
619 		return (ARCHIVE_FATAL);
620 
621 	offset = 0;
622 	window = 1;
623 	while (offset + window <= SFX_MAX_ADDR - SFX_MIN_ADDR) {
624 		h = __archive_read_ahead(a, window, &bytes);
625 		if (h == NULL) {
626 			/* Remaining bytes are less than window. */
627 			window >>= 1;
628 			if (window < 0x40)
629 				goto fatal;
630 			continue;
631 		}
632 		if (bytes < 6) {
633 			/* This case might happen when window == 1. */
634 			window = 4096;
635 			continue;
636 		}
637 		p = (const char *)h;
638 		q = p + bytes;
639 
640 		/*
641 		 * Scan ahead until we find something that looks
642 		 * like the 7-Zip header.
643 		 */
644 		while (p + 32 < q) {
645 			int step = check_7zip_header_in_sfx(p);
646 			if (step == 0) {
647 				struct _7zip *zip =
648 				    (struct _7zip *)a->format->data;
649 				skip = p - (const char *)h;
650 				__archive_read_consume(a, skip);
651 				zip->seek_base = min_addr + offset + skip;
652 				return (ARCHIVE_OK);
653 			}
654 			p += step;
655 		}
656 		skip = p - (const char *)h;
657 		__archive_read_consume(a, skip);
658 		offset += skip;
659 		if (window == 1)
660 			window = 4096;
661 	}
662 fatal:
663 	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
664 	    "Couldn't find out 7-Zip header");
665 	return (ARCHIVE_FATAL);
666 }
667 
668 static ssize_t
find_pe_overlay(struct archive_read * a)669 find_pe_overlay(struct archive_read *a)
670 {
671 	const char *h;
672 	ssize_t bytes, max_offset, offset, sec_end;
673 	ssize_t opt_hdr_sz, sec_cnt;
674 
675 	for (;;) {
676 		/*
677 		 * Read Dos header to find e_lfanew
678 		 */
679 		h = __archive_read_ahead(a, PE_DOS_HDR_LEN, &bytes);
680 		if (h == NULL || h[0] != 'M' || h[1] != 'Z') {
681 			break;
682 		}
683 		offset = archive_le32dec(h + PE_DOS_HDR_ELFANEW_OFFSET);
684 
685 		/*
686 		 * Read COFF header to find opt header size and sec cnt
687 		 */
688 		if (bytes < offset + PE_COFF_HDR_LEN) {
689 			h = __archive_read_ahead(a, offset + PE_COFF_HDR_LEN,
690 			    &bytes);
691 			if (h == NULL || h[offset] != 'P' ||
692 			    h[offset + 1] != 'E') {
693 				break;
694 			}
695 		}
696 		sec_cnt = archive_le16dec(
697 		    h + offset + PE_COFF_HDR_SEC_CNT_OFFSET);
698 		opt_hdr_sz = archive_le16dec(
699 		    h + offset + PE_COFF_HDR_OPT_SZ_OFFSET);
700 
701 		/*
702 		 * Skip optional header
703 		 */
704 		if (opt_hdr_sz != 0) {
705 			offset += PE_COFF_HDR_LEN + opt_hdr_sz;
706 		} else {
707 			break;
708 		}
709 
710 		/*
711 		 * Traverse sec table to find max raw offset (i.e., overlay)
712 		 */
713 		if (bytes < offset + sec_cnt * PE_SEC_HDR_LEN) {
714 			h = __archive_read_ahead(a,
715 			    offset + sec_cnt * PE_SEC_HDR_LEN, NULL);
716 			if (h == NULL) {
717 				break;
718 			}
719 		}
720 		max_offset = offset;
721 		while (sec_cnt > 0) {
722 			sec_end = archive_le32dec(
723 				      h + offset + PE_SEC_HDR_RAW_SZ_OFFSET) +
724 			    archive_le32dec(
725 				h + offset + PE_SEC_HDR_RAW_ADDR_OFFSET);
726 			if (sec_end > max_offset) {
727 				max_offset = sec_end;
728 			}
729 			offset += PE_SEC_HDR_LEN;
730 			sec_cnt--;
731 		}
732 		return (max_offset);
733 	}
734 
735 	/*
736 	 * If encounter any weirdness, revert to old brute-force style search
737 	 */
738 	return (SFX_MIN_ADDR);
739 }
740 
741 static ssize_t
find_elf_data_sec(struct archive_read * a)742 find_elf_data_sec(struct archive_read *a)
743 {
744 	const char *h;
745 	char big_endian, format_64;
746 	ssize_t bytes, min_addr = SFX_MIN_ADDR;
747 	uint64_t e_shoff, strtab_offset, strtab_size;
748 	uint16_t e_shentsize, e_shnum, e_shstrndx;
749 	uint16_t (*dec16)(const void *);
750 	uint32_t (*dec32)(const void *);
751 	uint64_t (*dec64)(const void *);
752 
753 	for (;;) {
754 		/*
755 		 * Read Elf header to find bitness & endianness
756 		 */
757 		h = __archive_read_ahead(a, ELF_HDR_MIN_LEN, &bytes);
758 		if (h == NULL || memcmp(h, "\x7F\x45LF", 4) != 0) {
759 			break;
760 		}
761 		format_64 = h[ELF_HDR_EI_CLASS_OFFSET] == 0x2;
762 		big_endian = h[ELF_HDR_EI_DATA_OFFSET] == 0x2;
763 		if (big_endian) {
764 			dec16 = &archive_be16dec;
765 			dec32 = &archive_be32dec;
766 			dec64 = &archive_be64dec;
767 		} else {
768 			dec16 = &archive_le16dec;
769 			dec32 = &archive_le32dec;
770 			dec64 = &archive_le64dec;
771 		}
772 
773 		/*
774 		 * Read section header table info
775 		 */
776 		if (format_64) {
777 			e_shoff = (*dec64)(h + 0x28);
778 			e_shentsize = (*dec16)(h + 0x3A);
779 			e_shnum = (*dec16)(h + 0x3C);
780 			e_shstrndx = (*dec16)(h + 0x3E);
781 			if (e_shnum < e_shstrndx || e_shentsize < 0x28)
782 				break;
783 
784 		} else {
785 			e_shoff = (*dec32)(h + 0x20);
786 			e_shentsize = (*dec16)(h + 0x2E);
787 			e_shnum = (*dec16)(h + 0x30);
788 			e_shstrndx = (*dec16)(h + 0x32);
789 			if (e_shnum < e_shstrndx || e_shentsize < 0x18)
790 				break;
791 		}
792 
793 		/*
794 		 * Reading the section table to find strtab section
795 		 */
796 		if (__archive_read_seek(a, e_shoff, SEEK_SET) < 0) {
797 			break;
798 		}
799 		h = __archive_read_ahead(a, (size_t)e_shnum * (size_t)e_shentsize, NULL);
800 		if (h == NULL) {
801 			break;
802 		}
803 		if (format_64) {
804 			strtab_offset = (*dec64)(
805 			    h + e_shstrndx * e_shentsize + 0x18);
806 			strtab_size = (*dec64)(
807 			    h + e_shstrndx * e_shentsize + 0x20);
808 		} else {
809 			strtab_offset = (*dec32)(
810 			    h + e_shstrndx * e_shentsize + 0x10);
811 			strtab_size = (*dec32)(
812 			    h + e_shstrndx * e_shentsize + 0x14);
813 		}
814 
815 		/*
816 		 * Read the STRTAB section to find the .data offset
817 		 */
818 		if (__archive_read_seek(a, strtab_offset, SEEK_SET) < 0) {
819 			break;
820 		}
821 		h = __archive_read_ahead(a, strtab_size, NULL);
822 		if (h == NULL) {
823 			break;
824 		}
825 		ssize_t data_sym_offset = -1;
826 		for (size_t offset = 0; offset < strtab_size - 6; offset++) {
827 			if (memcmp(h + offset, ".data\00", 6) == 0) {
828 				data_sym_offset = offset;
829 				break;
830 			}
831 		}
832 		if (data_sym_offset == -1) {
833 			break;
834 		}
835 
836 		/*
837 		 * Find the section with the .data name
838 		 */
839 		if (__archive_read_seek(a, e_shoff, SEEK_SET) < 0) {
840 			break;
841 		}
842 		h = __archive_read_ahead(a, (size_t)e_shnum * (size_t)e_shentsize, NULL);
843 		if (h == NULL) {
844 			break;
845 		}
846 		ssize_t sec_tbl_offset = 0, name_offset;
847 		while (e_shnum > 0) {
848 			name_offset = (*dec32)(h + sec_tbl_offset);
849 			if (name_offset == data_sym_offset) {
850 				if (format_64) {
851 					min_addr = (*dec64)(
852 					    h + sec_tbl_offset + 0x18);
853 				} else {
854 					min_addr = (*dec32)(
855 					    h + sec_tbl_offset + 0x10);
856 				}
857 				break;
858 			}
859 			sec_tbl_offset += e_shentsize;
860 			e_shnum--;
861 		}
862 		break;
863 	}
864 
865 	__archive_read_seek(a, 0, SEEK_SET);
866 	return (min_addr);
867 }
868 
869 static int
archive_read_format_7zip_read_header(struct archive_read * a,struct archive_entry * entry)870 archive_read_format_7zip_read_header(struct archive_read *a,
871 	struct archive_entry *entry)
872 {
873 	struct _7zip *zip = (struct _7zip *)a->format->data;
874 	struct _7zip_entry *zip_entry;
875 	int r, ret = ARCHIVE_OK;
876 	struct _7z_folder *folder = 0;
877 	uint64_t fidx = 0;
878 
879 	/*
880 	 * It should be sufficient to call archive_read_next_header() for
881 	 * a reader to determine if an entry is encrypted or not. If the
882 	 * encryption of an entry is only detectable when calling
883 	 * archive_read_data(), so be it. We'll do the same check there
884 	 * as well.
885 	 */
886 	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
887 		zip->has_encrypted_entries = 0;
888 	}
889 
890 	a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
891 	if (a->archive.archive_format_name == NULL)
892 		a->archive.archive_format_name = "7-Zip";
893 
894 	if (zip->entries == NULL) {
895 		struct _7z_header_info header;
896 
897 		memset(&header, 0, sizeof(header));
898 		r = slurp_central_directory(a, zip, &header);
899 		free_Header(&header);
900 		if (r != ARCHIVE_OK)
901 			return (r);
902 		zip->entries_remaining = (size_t)zip->numFiles;
903 		zip->entry = zip->entries;
904 	} else {
905 		++zip->entry;
906 	}
907 	zip_entry = zip->entry;
908 
909 	if (zip->entries_remaining <= 0 || zip_entry == NULL)
910 		return ARCHIVE_EOF;
911 	--zip->entries_remaining;
912 
913 	zip->entry_offset = 0;
914 	zip->end_of_entry = 0;
915 	zip->entry_crc32 = crc32(0, NULL, 0);
916 
917 	/* Setup a string conversion for a filename. */
918 	if (zip->sconv == NULL) {
919 		zip->sconv = archive_string_conversion_from_charset(
920 		    &a->archive, "UTF-16LE", 1);
921 		if (zip->sconv == NULL)
922 			return (ARCHIVE_FATAL);
923 	}
924 
925 	/* Figure out if the entry is encrypted by looking at the folder
926 	   that is associated to the current 7zip entry. If the folder
927 	   has a coder with a _7Z_CRYPTO codec then the folder is encrypted.
928 	   Hence the entry must also be encrypted. */
929 	if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) {
930 		folder = &(zip->si.ci.folders[zip_entry->folderIndex]);
931 		for (fidx=0; folder && fidx<folder->numCoders; fidx++) {
932 			switch(folder->coders[fidx].codec) {
933 				case _7Z_CRYPTO_MAIN_ZIP:
934 				case _7Z_CRYPTO_RAR_29:
935 				case _7Z_CRYPTO_AES_256_SHA_256: {
936 					archive_entry_set_is_data_encrypted(entry, 1);
937 					zip->has_encrypted_entries = 1;
938 					break;
939 				}
940 			}
941 		}
942 	}
943 
944 	/* Now that we've checked for encryption, if there were still no
945 	 * encrypted entries found we can say for sure that there are none.
946 	 */
947 	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
948 		zip->has_encrypted_entries = 0;
949 	}
950 
951 	if (archive_entry_copy_pathname_l(entry,
952 	    (const char *)zip_entry->utf16name,
953 	    zip_entry->name_len, zip->sconv) != 0) {
954 		if (errno == ENOMEM) {
955 			archive_set_error(&a->archive, ENOMEM,
956 			    "Can't allocate memory for Pathname");
957 			return (ARCHIVE_FATAL);
958 		}
959 		archive_set_error(&a->archive,
960 		    ARCHIVE_ERRNO_FILE_FORMAT,
961 		    "Pathname cannot be converted "
962 		    "from %s to current locale.",
963 		    archive_string_conversion_charset_name(zip->sconv));
964 		ret = ARCHIVE_WARN;
965 	}
966 
967 	/* Populate some additional entry fields: */
968 	archive_entry_set_mode(entry, zip_entry->mode);
969 	if (zip_entry->flg & MTIME_IS_SET)
970 		archive_entry_set_mtime(entry, zip_entry->mtime,
971 			zip_entry->mtime_ns);
972 	if (zip_entry->flg & CTIME_IS_SET)
973 		archive_entry_set_ctime(entry, zip_entry->ctime,
974 		    zip_entry->ctime_ns);
975 	if (zip_entry->flg & ATIME_IS_SET)
976 		archive_entry_set_atime(entry, zip_entry->atime,
977 		    zip_entry->atime_ns);
978 	if (zip_entry->ssIndex != (uint32_t)-1) {
979 		zip->entry_bytes_remaining =
980 		    zip->si.ss.unpackSizes[zip_entry->ssIndex];
981 		archive_entry_set_size(entry, zip->entry_bytes_remaining);
982 	} else {
983 		zip->entry_bytes_remaining = 0;
984 		archive_entry_set_size(entry, 0);
985 	}
986 
987 	// These attributes are supported by the windows implementation of archive_write_disk.
988 	const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
989 
990 	if (zip_entry->attr & supported_attrs) {
991 		char *fflags_text, *ptr;
992 		/* allocate for ",rdonly,hidden,system" */
993 		fflags_text = malloc(22 * sizeof(*fflags_text));
994 		if (fflags_text != NULL) {
995 			ptr = fflags_text;
996 			if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) {
997 				strcpy(ptr, ",rdonly");
998 				ptr = ptr + 7;
999 			}
1000 			if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) {
1001 				strcpy(ptr, ",hidden");
1002 				ptr = ptr + 7;
1003 			}
1004 			if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) {
1005 				strcpy(ptr, ",system");
1006 				ptr = ptr + 7;
1007 			}
1008 			if (ptr > fflags_text) {
1009 				archive_entry_copy_fflags_text(entry,
1010 				    fflags_text + 1);
1011 			}
1012 			free(fflags_text);
1013 		}
1014 	}
1015 
1016 	/* If there's no body, force read_data() to return EOF immediately. */
1017 	if (zip->entry_bytes_remaining < 1)
1018 		zip->end_of_entry = 1;
1019 
1020 	if ((zip_entry->mode & AE_IFMT) == AE_IFLNK) {
1021 		unsigned char *symname = NULL;
1022 		size_t symsize = 0;
1023 
1024 		/*
1025 		 * Symbolic-name is recorded as its contents. We have to
1026 		 * read the contents at this time.
1027 		 */
1028 		while (zip->entry_bytes_remaining > 0) {
1029 			const void *buff;
1030 			unsigned char *mem;
1031 			size_t size;
1032 			int64_t offset;
1033 
1034 			r = archive_read_format_7zip_read_data(a, &buff,
1035 				&size, &offset);
1036 			if (r < ARCHIVE_WARN) {
1037 				free(symname);
1038 				return (r);
1039 			}
1040 			mem = realloc(symname, symsize + size + 1);
1041 			if (mem == NULL) {
1042 				free(symname);
1043 				archive_set_error(&a->archive, ENOMEM,
1044 				    "Can't allocate memory for Symname");
1045 				return (ARCHIVE_FATAL);
1046 			}
1047 			symname = mem;
1048 			memcpy(symname+symsize, buff, size);
1049 			symsize += size;
1050 		}
1051 		if (symsize == 0) {
1052 			/* If there is no symname, handle it as a regular
1053 			 * file. */
1054 			zip_entry->mode &= ~AE_IFMT;
1055 			zip_entry->mode |= AE_IFREG;
1056 			archive_entry_set_mode(entry, zip_entry->mode);
1057 		} else {
1058 			struct archive_string_conv* utf8_conv;
1059 
1060 			symname[symsize] = '\0';
1061 
1062 			/* Symbolic links are embedded as UTF-8 strings */
1063 			utf8_conv = archive_string_conversion_from_charset(&a->archive,
1064 			    "UTF-8", 1);
1065 			if (utf8_conv == NULL) {
1066 				free(symname);
1067 				return ARCHIVE_FATAL;
1068 			}
1069 
1070 			archive_entry_copy_symlink_l(entry, (const char*)symname, symsize,
1071 			    utf8_conv);
1072 		}
1073 		free(symname);
1074 		archive_entry_set_size(entry, 0);
1075 	}
1076 
1077 	/* Set up a more descriptive format name. */
1078 	snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip");
1079 	a->archive.archive_format_name = zip->format_name;
1080 
1081 	return (ret);
1082 }
1083 
1084 static int
archive_read_format_7zip_read_data(struct archive_read * a,const void ** buff,size_t * size,int64_t * offset)1085 archive_read_format_7zip_read_data(struct archive_read *a,
1086     const void **buff, size_t *size, int64_t *offset)
1087 {
1088 	struct _7zip *zip;
1089 	ssize_t bytes;
1090 	int ret = ARCHIVE_OK;
1091 
1092 	zip = (struct _7zip *)(a->format->data);
1093 
1094 	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
1095 		zip->has_encrypted_entries = 0;
1096 	}
1097 
1098 	if (zip->pack_stream_bytes_unconsumed)
1099 		read_consume(a);
1100 
1101 	*offset = zip->entry_offset;
1102 	*size = 0;
1103 	*buff = NULL;
1104 	/*
1105 	 * If we hit end-of-entry last time, clean up and return
1106 	 * ARCHIVE_EOF this time.
1107 	 */
1108 	if (zip->end_of_entry)
1109 		return (ARCHIVE_EOF);
1110 
1111 	size_t bytes_to_read = 16 * 1024 * 1024;  // Don't try to read more than 16 MB at a time
1112 	if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
1113 		bytes_to_read = (size_t)zip->entry_bytes_remaining;
1114 	}
1115 	bytes = read_stream(a, buff, bytes_to_read, 0);
1116 	if (bytes < 0)
1117 		return ((int)bytes);
1118 	if (bytes == 0) {
1119 		archive_set_error(&a->archive,
1120 		    ARCHIVE_ERRNO_FILE_FORMAT,
1121 		    "Truncated 7-Zip file body");
1122 		return (ARCHIVE_FATAL);
1123 	}
1124 	zip->entry_bytes_remaining -= bytes;
1125 	if (zip->entry_bytes_remaining == 0)
1126 		zip->end_of_entry = 1;
1127 
1128 	/* Update checksum */
1129 	if ((zip->entry->flg & CRC32_IS_SET) && bytes)
1130 		zip->entry_crc32 = crc32(zip->entry_crc32, *buff,
1131 		    (unsigned)bytes);
1132 
1133 	/* If we hit the end, swallow any end-of-data marker. */
1134 	if (zip->end_of_entry) {
1135 		/* Check computed CRC against file contents. */
1136 		if ((zip->entry->flg & CRC32_IS_SET) &&
1137 			zip->si.ss.digests[zip->entry->ssIndex] !=
1138 		    zip->entry_crc32) {
1139 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1140 			    "7-Zip bad CRC: 0x%lx should be 0x%lx",
1141 			    (unsigned long)zip->entry_crc32,
1142 			    (unsigned long)zip->si.ss.digests[
1143 			    		zip->entry->ssIndex]);
1144 			ret = ARCHIVE_WARN;
1145 		}
1146 	}
1147 
1148 	*size = bytes;
1149 	*offset = zip->entry_offset;
1150 	zip->entry_offset += bytes;
1151 
1152 	return (ret);
1153 }
1154 
1155 static int
archive_read_format_7zip_read_data_skip(struct archive_read * a)1156 archive_read_format_7zip_read_data_skip(struct archive_read *a)
1157 {
1158 	struct _7zip *zip;
1159 	int64_t bytes_skipped;
1160 
1161 	zip = (struct _7zip *)(a->format->data);
1162 
1163 	if (zip->pack_stream_bytes_unconsumed)
1164 		read_consume(a);
1165 
1166 	/* If we've already read to end of data, we're done. */
1167 	if (zip->end_of_entry)
1168 		return (ARCHIVE_OK);
1169 
1170 	/*
1171 	 * If the length is at the beginning, we can skip the
1172 	 * compressed data much more quickly.
1173 	 */
1174 	bytes_skipped = skip_stream(a, (size_t)zip->entry_bytes_remaining);
1175 	if (bytes_skipped < 0)
1176 		return (ARCHIVE_FATAL);
1177 	zip->entry_bytes_remaining = 0;
1178 
1179 	/* This entry is finished and done. */
1180 	zip->end_of_entry = 1;
1181 	return (ARCHIVE_OK);
1182 }
1183 
1184 static int
archive_read_format_7zip_cleanup(struct archive_read * a)1185 archive_read_format_7zip_cleanup(struct archive_read *a)
1186 {
1187 	struct _7zip *zip;
1188 
1189 	zip = (struct _7zip *)(a->format->data);
1190 	free_StreamsInfo(&(zip->si));
1191 	free(zip->entries);
1192 	free(zip->entry_names);
1193 	free_decompression(a, zip);
1194 	free(zip->uncompressed_buffer);
1195 	free(zip->sub_stream_buff[0]);
1196 	free(zip->sub_stream_buff[1]);
1197 	free(zip->sub_stream_buff[2]);
1198 	free(zip->tmp_stream_buff);
1199 	free(zip);
1200 	(a->format->data) = NULL;
1201 	return (ARCHIVE_OK);
1202 }
1203 
1204 static void
read_consume(struct archive_read * a)1205 read_consume(struct archive_read *a)
1206 {
1207 	struct _7zip *zip = (struct _7zip *)a->format->data;
1208 
1209 	if (zip->pack_stream_bytes_unconsumed) {
1210 		__archive_read_consume(a, zip->pack_stream_bytes_unconsumed);
1211 		zip->stream_offset += zip->pack_stream_bytes_unconsumed;
1212 		zip->pack_stream_bytes_unconsumed = 0;
1213 	}
1214 }
1215 
1216 #ifdef HAVE_LZMA_H
1217 
1218 /*
1219  * Set an error code and choose an error message for liblzma.
1220  */
1221 static void
set_error(struct archive_read * a,int ret)1222 set_error(struct archive_read *a, int ret)
1223 {
1224 
1225 	switch (ret) {
1226 	case LZMA_STREAM_END: /* Found end of stream. */
1227 	case LZMA_OK: /* Decompressor made some progress. */
1228 		break;
1229 	case LZMA_MEM_ERROR:
1230 		archive_set_error(&a->archive, ENOMEM,
1231 		    "Lzma library error: Cannot allocate memory");
1232 		break;
1233 	case LZMA_MEMLIMIT_ERROR:
1234 		archive_set_error(&a->archive, ENOMEM,
1235 		    "Lzma library error: Out of memory");
1236 		break;
1237 	case LZMA_FORMAT_ERROR:
1238 		archive_set_error(&a->archive,
1239 		    ARCHIVE_ERRNO_MISC,
1240 		    "Lzma library error: format not recognized");
1241 		break;
1242 	case LZMA_OPTIONS_ERROR:
1243 		archive_set_error(&a->archive,
1244 		    ARCHIVE_ERRNO_MISC,
1245 		    "Lzma library error: Invalid options");
1246 		break;
1247 	case LZMA_DATA_ERROR:
1248 		archive_set_error(&a->archive,
1249 		    ARCHIVE_ERRNO_MISC,
1250 		    "Lzma library error: Corrupted input data");
1251 		break;
1252 	case LZMA_BUF_ERROR:
1253 		archive_set_error(&a->archive,
1254 		    ARCHIVE_ERRNO_MISC,
1255 		    "Lzma library error:  No progress is possible");
1256 		break;
1257 	default:
1258 		/* Return an error. */
1259 		archive_set_error(&a->archive,
1260 		    ARCHIVE_ERRNO_MISC,
1261 		    "Lzma decompression failed:  Unknown error");
1262 		break;
1263 	}
1264 }
1265 
1266 #endif
1267 
1268 static unsigned long
decode_codec_id(const unsigned char * codecId,size_t id_size)1269 decode_codec_id(const unsigned char *codecId, size_t id_size)
1270 {
1271 	unsigned i;
1272 	unsigned long id = 0;
1273 
1274 	for (i = 0; i < id_size; i++) {
1275 		id <<= 8;
1276 		id += codecId[i];
1277 	}
1278 	return (id);
1279 }
1280 
1281 static Byte
ppmd_read(void * p)1282 ppmd_read(void *p)
1283 {
1284 	struct archive_read *a = ((IByteIn*)p)->a;
1285 	struct _7zip *zip = (struct _7zip *)(a->format->data);
1286 	Byte b;
1287 
1288 	if (zip->ppstream.avail_in <= 0) {
1289 		/*
1290 		 * Ppmd7_DecodeSymbol might require reading multiple bytes
1291 		 * and we are on boundary;
1292 		 * last resort to read using __archive_read_ahead.
1293 		 */
1294 		ssize_t bytes_avail = 0;
1295 		const uint8_t* data = __archive_read_ahead(a,
1296 		    (size_t)zip->ppstream.stream_in+1, &bytes_avail);
1297 		if(data == NULL || bytes_avail < zip->ppstream.stream_in+1) {
1298 			archive_set_error(&a->archive,
1299 			    ARCHIVE_ERRNO_FILE_FORMAT,
1300 			    "Truncated 7z file data");
1301 			zip->ppstream.overconsumed = 1;
1302 			return (0);
1303 		}
1304 		zip->ppstream.next_in++;
1305 		b = data[zip->ppstream.stream_in];
1306 	} else {
1307 		b = *zip->ppstream.next_in++;
1308 	}
1309 	zip->ppstream.avail_in--;
1310 	zip->ppstream.total_in++;
1311 	zip->ppstream.stream_in++;
1312 	return (b);
1313 }
1314 
1315 static int
init_decompression(struct archive_read * a,struct _7zip * zip,const struct _7z_coder * coder1,const struct _7z_coder * coder2)1316 init_decompression(struct archive_read *a, struct _7zip *zip,
1317     const struct _7z_coder *coder1, const struct _7z_coder *coder2)
1318 {
1319 	int r;
1320 
1321 	zip->codec = coder1->codec;
1322 	zip->codec2 = -1;
1323 
1324 	switch (zip->codec) {
1325 	case _7Z_COPY:
1326 	case _7Z_BZ2:
1327 	case _7Z_DEFLATE:
1328 	case _7Z_ZSTD:
1329 	case _7Z_PPMD:
1330 		if (coder2 != NULL) {
1331 			if (coder2->codec != _7Z_X86 &&
1332 			    coder2->codec != _7Z_X86_BCJ2 &&
1333 			    coder2->codec != _7Z_ARM &&
1334 			    coder2->codec != _7Z_ARM64 &&
1335 			    coder2->codec != _7Z_POWERPC &&
1336 			    coder2->codec != _7Z_SPARC) {
1337 				archive_set_error(&a->archive,
1338 				    ARCHIVE_ERRNO_MISC,
1339 				    "Unsupported filter %lx for %lx",
1340 				    coder2->codec, coder1->codec);
1341 				return (ARCHIVE_FAILED);
1342 			}
1343 			zip->codec2 = coder2->codec;
1344 			zip->bcj_state = 0;
1345 			if (coder2->codec == _7Z_X86)
1346 				x86_Init(zip);
1347 			else if (coder2->codec == _7Z_ARM)
1348 				arm_Init(zip);
1349 		}
1350 		break;
1351 	default:
1352 		break;
1353 	}
1354 
1355 	switch (zip->codec) {
1356 	case _7Z_COPY:
1357 		break;
1358 
1359 	case _7Z_LZMA: case _7Z_LZMA2:
1360 #ifdef HAVE_LZMA_H
1361 #if LZMA_VERSION_MAJOR >= 5
1362 /* Effectively disable the limiter. */
1363 #define LZMA_MEMLIMIT   UINT64_MAX
1364 #else
1365 /* NOTE: This needs to check memory size which running system has. */
1366 #define LZMA_MEMLIMIT   (1U << 30)
1367 #endif
1368 	{
1369 		lzma_options_delta delta_opt;
1370 		lzma_filter filters[LZMA_FILTERS_MAX], *ff;
1371 		int fi = 0;
1372 
1373 		if (zip->lzstream_valid) {
1374 			lzma_end(&(zip->lzstream));
1375 			zip->lzstream_valid = 0;
1376 		}
1377 
1378 		/*
1379 		 * NOTE: liblzma incompletely handle the BCJ+LZMA compressed
1380 		 * data made by 7-Zip because 7-Zip does not add End-Of-
1381 		 * Payload Marker(EOPM) at the end of LZMA compressed data,
1382 		 * and so liblzma cannot know the end of the compressed data
1383 		 * without EOPM. So consequently liblzma will not return last
1384 		 * three or four bytes of uncompressed data because
1385 		 * LZMA_FILTER_X86 filter does not handle input data if its
1386 		 * data size is less than five bytes. If liblzma detect EOPM
1387 		 * or know the uncompressed data size, liblzma will flush out
1388 		 * the remaining that three or four bytes of uncompressed
1389 		 * data. That is why we have to use our converting program
1390 		 * for BCJ+LZMA. If we were able to tell the uncompressed
1391 		 * size to liblzma when using lzma_raw_decoder() liblzma
1392 		 * could correctly deal with BCJ+LZMA. But unfortunately
1393 		 * there is no way to do that.
1394 		 * Discussion about this can be found at XZ Utils forum.
1395 		 */
1396 		if (coder2 != NULL) {
1397 			zip->codec2 = coder2->codec;
1398 
1399 			filters[fi].options = NULL;
1400 			switch (zip->codec2) {
1401 			case _7Z_X86:
1402 				if (zip->codec == _7Z_LZMA2) {
1403 					filters[fi].id = LZMA_FILTER_X86;
1404 					fi++;
1405 				} else
1406 					/* Use our filter. */
1407 					x86_Init(zip);
1408 				break;
1409 			case _7Z_X86_BCJ2:
1410 				/* Use our filter. */
1411 				zip->bcj_state = 0;
1412 				break;
1413 			case _7Z_DELTA:
1414 				if (coder2->propertiesSize != 1) {
1415 					archive_set_error(&a->archive,
1416 					    ARCHIVE_ERRNO_MISC,
1417 					    "Invalid Delta parameter");
1418 					return (ARCHIVE_FAILED);
1419 				}
1420 				filters[fi].id = LZMA_FILTER_DELTA;
1421 				memset(&delta_opt, 0, sizeof(delta_opt));
1422 				delta_opt.type = LZMA_DELTA_TYPE_BYTE;
1423 				delta_opt.dist =
1424 				    (uint32_t)coder2->properties[0] + 1;
1425 				filters[fi].options = &delta_opt;
1426 				fi++;
1427 				break;
1428 			/* Following filters have not been tested yet. */
1429 			case _7Z_POWERPC:
1430 				filters[fi].id = LZMA_FILTER_POWERPC;
1431 				fi++;
1432 				break;
1433 			case _7Z_IA64:
1434 				filters[fi].id = LZMA_FILTER_IA64;
1435 				fi++;
1436 				break;
1437 			case _7Z_ARM:
1438 				filters[fi].id = LZMA_FILTER_ARM;
1439 				fi++;
1440 				break;
1441 			case _7Z_ARMTHUMB:
1442 				filters[fi].id = LZMA_FILTER_ARMTHUMB;
1443 				fi++;
1444 				break;
1445 #ifdef LZMA_FILTER_ARM64
1446 			case _7Z_ARM64:
1447 				filters[fi].id = LZMA_FILTER_ARM64;
1448 				fi++;
1449 				break;
1450 #endif
1451 #ifdef LZMA_FILTER_RISCV
1452 			case _7Z_RISCV:
1453 				filters[fi].id = LZMA_FILTER_RISCV;
1454 				fi++;
1455 				break;
1456 #endif
1457 			case _7Z_SPARC:
1458 				filters[fi].id = LZMA_FILTER_SPARC;
1459 				fi++;
1460 				break;
1461 			default:
1462 				archive_set_error(&a->archive,
1463 				    ARCHIVE_ERRNO_MISC,
1464 				    "Unexpected codec ID: %lX", zip->codec2);
1465 				return (ARCHIVE_FAILED);
1466 			}
1467 		}
1468 
1469 		if (zip->codec == _7Z_LZMA2)
1470 			filters[fi].id = LZMA_FILTER_LZMA2;
1471 		else
1472 			filters[fi].id = LZMA_FILTER_LZMA1;
1473 		filters[fi].options = NULL;
1474 		ff = &filters[fi];
1475 		r = lzma_properties_decode(&filters[fi], NULL,
1476 		    coder1->properties, (size_t)coder1->propertiesSize);
1477 		if (r != LZMA_OK) {
1478 			set_error(a, r);
1479 			return (ARCHIVE_FAILED);
1480 		}
1481 		fi++;
1482 
1483 		filters[fi].id = LZMA_VLI_UNKNOWN;
1484 		filters[fi].options = NULL;
1485 		r = lzma_raw_decoder(&(zip->lzstream), filters);
1486 		free(ff->options);
1487 		if (r != LZMA_OK) {
1488 			set_error(a, r);
1489 			return (ARCHIVE_FAILED);
1490 		}
1491 		zip->lzstream_valid = 1;
1492 		zip->lzstream.total_in = 0;
1493 		zip->lzstream.total_out = 0;
1494 		break;
1495 	}
1496 #else
1497 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1498 		    "LZMA codec is unsupported");
1499 		return (ARCHIVE_FAILED);
1500 #endif
1501 	case _7Z_BZ2:
1502 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1503 		if (zip->bzstream_valid) {
1504 			BZ2_bzDecompressEnd(&(zip->bzstream));
1505 			zip->bzstream_valid = 0;
1506 		}
1507 		r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 0);
1508 		if (r == BZ_MEM_ERROR)
1509 			r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 1);
1510 		if (r != BZ_OK) {
1511 			int err = ARCHIVE_ERRNO_MISC;
1512 			const char *detail = NULL;
1513 			switch (r) {
1514 			case BZ_PARAM_ERROR:
1515 				detail = "invalid setup parameter";
1516 				break;
1517 			case BZ_MEM_ERROR:
1518 				err = ENOMEM;
1519 				detail = "out of memory";
1520 				break;
1521 			case BZ_CONFIG_ERROR:
1522 				detail = "mis-compiled library";
1523 				break;
1524 			}
1525 			archive_set_error(&a->archive, err,
1526 			    "Internal error initializing decompressor: %s",
1527 			    detail != NULL ? detail : "??");
1528 			zip->bzstream_valid = 0;
1529 			return (ARCHIVE_FAILED);
1530 		}
1531 		zip->bzstream_valid = 1;
1532 		zip->bzstream.total_in_lo32 = 0;
1533 		zip->bzstream.total_in_hi32 = 0;
1534 		zip->bzstream.total_out_lo32 = 0;
1535 		zip->bzstream.total_out_hi32 = 0;
1536 		break;
1537 #else
1538 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1539 		    "BZ2 codec is unsupported");
1540 		return (ARCHIVE_FAILED);
1541 #endif
1542 	case _7Z_ZSTD:
1543 	{
1544 #if defined(HAVE_ZSTD_H)
1545 		if (zip->zstdstream_valid) {
1546 			ZSTD_freeDStream(zip->zstd_dstream);
1547 			zip->zstdstream_valid = 0;
1548 		}
1549 		zip->zstd_dstream = ZSTD_createDStream();
1550 		zip->zstdstream_valid = 1;
1551 		break;
1552 #else
1553 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1554 			"ZSTD codec is unsupported");
1555 		return (ARCHIVE_FAILED);
1556 #endif
1557 	}
1558 	case _7Z_DEFLATE:
1559 #ifdef HAVE_ZLIB_H
1560 		if (zip->stream_valid)
1561 			r = inflateReset(&(zip->stream));
1562 		else
1563 			r = inflateInit2(&(zip->stream),
1564 			    -15 /* Don't check for zlib header */);
1565 		if (r != Z_OK) {
1566 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1567 			    "Couldn't initialize zlib stream.");
1568 			return (ARCHIVE_FAILED);
1569 		}
1570 		zip->stream_valid = 1;
1571 		zip->stream.total_in = 0;
1572 		zip->stream.total_out = 0;
1573 		break;
1574 #else
1575 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1576 		    "DEFLATE codec is unsupported");
1577 		return (ARCHIVE_FAILED);
1578 #endif
1579 	case _7Z_PPMD:
1580 	{
1581 		unsigned order;
1582 		uint32_t msize;
1583 
1584 		if (zip->ppmd7_valid) {
1585 			__archive_ppmd7_functions.Ppmd7_Free(
1586 			    &zip->ppmd7_context);
1587 			zip->ppmd7_valid = 0;
1588 		}
1589 
1590 		if (coder1->propertiesSize < 5) {
1591 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1592 			    "Malformed PPMd parameter");
1593 			return (ARCHIVE_FAILED);
1594 		}
1595 		order = coder1->properties[0];
1596 		msize = archive_le32dec(&(coder1->properties[1]));
1597 		if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER ||
1598 		    msize < PPMD7_MIN_MEM_SIZE || msize > PPMD7_MAX_MEM_SIZE) {
1599 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1600 			    "Malformed PPMd parameter");
1601 			return (ARCHIVE_FAILED);
1602 		}
1603 		__archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
1604 		r = __archive_ppmd7_functions.Ppmd7_Alloc(
1605 			&zip->ppmd7_context, msize);
1606 		if (r == 0) {
1607 			archive_set_error(&a->archive, ENOMEM,
1608 			    "Coludn't allocate memory for PPMd");
1609 			return (ARCHIVE_FATAL);
1610 		}
1611 		__archive_ppmd7_functions.Ppmd7_Init(
1612 			&zip->ppmd7_context, order);
1613 		__archive_ppmd7_functions.Ppmd7z_RangeDec_CreateVTable(
1614 			&zip->range_dec);
1615 		zip->ppmd7_valid = 1;
1616 		zip->ppmd7_stat = 0;
1617 		zip->ppstream.overconsumed = 0;
1618 		zip->ppstream.total_in = 0;
1619 		zip->ppstream.total_out = 0;
1620 		break;
1621 	}
1622 	case _7Z_X86:
1623 	case _7Z_X86_BCJ2:
1624 	case _7Z_POWERPC:
1625 	case _7Z_IA64:
1626 	case _7Z_ARM:
1627 	case _7Z_ARMTHUMB:
1628 	case _7Z_ARM64:
1629 	case _7Z_RISCV:
1630 	case _7Z_SPARC:
1631 	case _7Z_DELTA:
1632 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1633 		    "Unexpected codec ID: %lX", zip->codec);
1634 		return (ARCHIVE_FAILED);
1635 	case _7Z_CRYPTO_MAIN_ZIP:
1636 	case _7Z_CRYPTO_RAR_29:
1637 	case _7Z_CRYPTO_AES_256_SHA_256:
1638 		if (a->entry) {
1639 			archive_entry_set_is_metadata_encrypted(a->entry, 1);
1640 			archive_entry_set_is_data_encrypted(a->entry, 1);
1641 			zip->has_encrypted_entries = 1;
1642 		}
1643 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1644 		    "Crypto codec not supported yet (ID: 0x%lX)", zip->codec);
1645 		return (ARCHIVE_FAILED);
1646 	default:
1647 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1648 		    "Unknown codec ID: %lX", zip->codec);
1649 		return (ARCHIVE_FAILED);
1650 	}
1651 
1652 	return (ARCHIVE_OK);
1653 }
1654 
1655 static int
decompress(struct archive_read * a,struct _7zip * zip,void * buff,size_t * outbytes,const void * b,size_t * used)1656 decompress(struct archive_read *a, struct _7zip *zip,
1657     void *buff, size_t *outbytes, const void *b, size_t *used)
1658 {
1659 	const uint8_t *t_next_in;
1660 	uint8_t *t_next_out;
1661 	size_t o_avail_in, o_avail_out;
1662 	size_t t_avail_in, t_avail_out;
1663 	uint8_t *bcj2_next_out;
1664 	size_t bcj2_avail_out;
1665 	int r, ret = ARCHIVE_OK;
1666 
1667 	t_avail_in = o_avail_in = *used;
1668 	t_avail_out = o_avail_out = *outbytes;
1669 	t_next_in = b;
1670 	t_next_out = buff;
1671 
1672 	if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
1673 		int i;
1674 
1675 		/* Do not copy out the BCJ remaining bytes when the output
1676 		 * buffer size is less than five bytes. */
1677 		if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) {
1678 			*used = 0;
1679 			*outbytes = 0;
1680 			return (ret);
1681 		}
1682 		for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) {
1683 			*t_next_out++ = zip->odd_bcj[i];
1684 			t_avail_out--;
1685 			zip->odd_bcj_size--;
1686 		}
1687 		if (o_avail_in == 0 || t_avail_out == 0) {
1688 			*used = o_avail_in - t_avail_in;
1689 			*outbytes = o_avail_out - t_avail_out;
1690 			if (o_avail_in == 0)
1691 				ret = ARCHIVE_EOF;
1692 			return (ret);
1693 		}
1694 	}
1695 
1696 	bcj2_next_out = t_next_out;
1697 	bcj2_avail_out = t_avail_out;
1698 	if (zip->codec2 == _7Z_X86_BCJ2) {
1699 		/*
1700 		 * Decord a remaining decompressed main stream for BCJ2.
1701 		 */
1702 		if (zip->tmp_stream_bytes_remaining) {
1703 			ssize_t bytes;
1704 			size_t remaining = zip->tmp_stream_bytes_remaining;
1705 			bytes = Bcj2_Decode(zip, t_next_out, t_avail_out);
1706 			if (bytes < 0) {
1707 				archive_set_error(&(a->archive),
1708 				    ARCHIVE_ERRNO_MISC,
1709 				    "BCJ2 conversion Failed");
1710 				return (ARCHIVE_FAILED);
1711 			}
1712 			zip->main_stream_bytes_remaining -=
1713 			    remaining - zip->tmp_stream_bytes_remaining;
1714 			t_avail_out -= bytes;
1715 			if (o_avail_in == 0 || t_avail_out == 0) {
1716 				*used = 0;
1717 				*outbytes = o_avail_out - t_avail_out;
1718 				if (o_avail_in == 0 &&
1719 				    zip->tmp_stream_bytes_remaining)
1720 					ret = ARCHIVE_EOF;
1721 				return (ret);
1722 			}
1723 			t_next_out += bytes;
1724 			bcj2_next_out = t_next_out;
1725 			bcj2_avail_out = t_avail_out;
1726 		}
1727 		t_next_out = zip->tmp_stream_buff;
1728 		t_avail_out = zip->tmp_stream_buff_size;
1729 	}
1730 
1731 	switch (zip->codec) {
1732 	case _7Z_COPY:
1733 	{
1734 		size_t bytes =
1735 		    (t_avail_in > t_avail_out)?t_avail_out:t_avail_in;
1736 
1737 		memcpy(t_next_out, t_next_in, bytes);
1738 		t_avail_in -= bytes;
1739 		t_avail_out -= bytes;
1740 		if (o_avail_in == 0)
1741 			ret = ARCHIVE_EOF;
1742 		break;
1743 	}
1744 #ifdef HAVE_LZMA_H
1745 	case _7Z_LZMA: case _7Z_LZMA2:
1746 		zip->lzstream.next_in = t_next_in;
1747 		zip->lzstream.avail_in = t_avail_in;
1748 		zip->lzstream.next_out = t_next_out;
1749 		zip->lzstream.avail_out = t_avail_out;
1750 
1751 		r = lzma_code(&(zip->lzstream), LZMA_RUN);
1752 		switch (r) {
1753 		case LZMA_STREAM_END: /* Found end of stream. */
1754 			lzma_end(&(zip->lzstream));
1755 			zip->lzstream_valid = 0;
1756 			ret = ARCHIVE_EOF;
1757 			break;
1758 		case LZMA_OK: /* Decompressor made some progress. */
1759 			break;
1760 		default:
1761 			archive_set_error(&(a->archive),
1762 			    ARCHIVE_ERRNO_MISC,
1763 				"Decompression failed(%d)",
1764 			    r);
1765 			return (ARCHIVE_FAILED);
1766 		}
1767 		t_avail_in = zip->lzstream.avail_in;
1768 		t_avail_out = zip->lzstream.avail_out;
1769 		break;
1770 #endif
1771 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1772 	case _7Z_BZ2:
1773 		zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
1774 		zip->bzstream.avail_in = (uint32_t)t_avail_in;
1775 		zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
1776 		zip->bzstream.avail_out = (uint32_t)t_avail_out;
1777 		r = BZ2_bzDecompress(&(zip->bzstream));
1778 		switch (r) {
1779 		case BZ_STREAM_END: /* Found end of stream. */
1780 			switch (BZ2_bzDecompressEnd(&(zip->bzstream))) {
1781 			case BZ_OK:
1782 				break;
1783 			default:
1784 				archive_set_error(&(a->archive),
1785 				    ARCHIVE_ERRNO_MISC,
1786 				    "Failed to clean up decompressor");
1787 				return (ARCHIVE_FAILED);
1788 			}
1789 			zip->bzstream_valid = 0;
1790 			ret = ARCHIVE_EOF;
1791 			break;
1792 		case BZ_OK: /* Decompressor made some progress. */
1793 			break;
1794 		default:
1795 			archive_set_error(&(a->archive),
1796 			    ARCHIVE_ERRNO_MISC,
1797 			    "bzip decompression failed");
1798 			return (ARCHIVE_FAILED);
1799 		}
1800 		t_avail_in = zip->bzstream.avail_in;
1801 		t_avail_out = zip->bzstream.avail_out;
1802 		break;
1803 #endif
1804 #ifdef HAVE_ZLIB_H
1805 	case _7Z_DEFLATE:
1806 		zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in;
1807 		zip->stream.avail_in = (uInt)t_avail_in;
1808 		zip->stream.next_out = t_next_out;
1809 		zip->stream.avail_out = (uInt)t_avail_out;
1810 		r = inflate(&(zip->stream), 0);
1811 		switch (r) {
1812 		case Z_STREAM_END: /* Found end of stream. */
1813 			ret = ARCHIVE_EOF;
1814 			break;
1815 		case Z_OK: /* Decompressor made some progress.*/
1816 			break;
1817 		default:
1818 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1819 			    "File decompression failed (%d)", r);
1820 			return (ARCHIVE_FAILED);
1821 		}
1822 		t_avail_in = zip->stream.avail_in;
1823 		t_avail_out = zip->stream.avail_out;
1824 		break;
1825 #endif
1826 #ifdef HAVE_ZSTD_H
1827 	case _7Z_ZSTD:
1828 	{
1829 		ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
1830 		ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
1831 
1832 		size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
1833 		if (ZSTD_isError(zret)) {
1834 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
1835 			return ARCHIVE_FAILED;
1836 		}
1837 		t_avail_in -= input.pos;
1838 		t_avail_out -= output.pos;
1839 		break;
1840 	}
1841 #endif
1842 	case _7Z_PPMD:
1843 	{
1844 		uint64_t flush_bytes;
1845 
1846 		if (!zip->ppmd7_valid || zip->ppmd7_stat < 0 ||
1847 		    t_avail_out <= 0) {
1848 			archive_set_error(&(a->archive),
1849 			    ARCHIVE_ERRNO_MISC,
1850 			    "Decompression internal error");
1851 			return (ARCHIVE_FAILED);
1852 		}
1853 		zip->ppstream.next_in = t_next_in;
1854 		zip->ppstream.avail_in = t_avail_in;
1855 		zip->ppstream.stream_in = 0;
1856 		zip->ppstream.next_out = t_next_out;
1857 		zip->ppstream.avail_out = t_avail_out;
1858 		if (zip->ppmd7_stat == 0) {
1859 			zip->bytein.a = a;
1860 			zip->bytein.Read = &ppmd_read;
1861 			zip->range_dec.Stream = &zip->bytein;
1862 			r = __archive_ppmd7_functions.Ppmd7z_RangeDec_Init(
1863 				&(zip->range_dec));
1864 			if (r == 0) {
1865 				zip->ppmd7_stat = -1;
1866 				archive_set_error(&a->archive,
1867 				    ARCHIVE_ERRNO_MISC,
1868 				    "Failed to initialize PPMd range decoder");
1869 				return (ARCHIVE_FAILED);
1870 			}
1871 			if (zip->ppstream.overconsumed) {
1872 				zip->ppmd7_stat = -1;
1873 				return (ARCHIVE_FAILED);
1874 			}
1875 			zip->ppmd7_stat = 1;
1876 		}
1877 
1878 		if (t_avail_in == 0)
1879 			/* XXX Flush out remaining decoded data XXX */
1880 			flush_bytes = zip->folder_outbytes_remaining;
1881 		else
1882 			flush_bytes = 0;
1883 
1884 		do {
1885 			int sym;
1886 
1887 			sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1888 				&(zip->ppmd7_context), &(zip->range_dec.p));
1889 			if (sym < 0) {
1890 				zip->ppmd7_stat = -1;
1891 				archive_set_error(&a->archive,
1892 				    ARCHIVE_ERRNO_FILE_FORMAT,
1893 				    "Failed to decode PPMd");
1894 				return (ARCHIVE_FAILED);
1895 			}
1896 			if (zip->ppstream.overconsumed) {
1897 				zip->ppmd7_stat = -1;
1898 				return (ARCHIVE_FAILED);
1899 			}
1900 			*zip->ppstream.next_out++ = (unsigned char)sym;
1901 			zip->ppstream.avail_out--;
1902 			zip->ppstream.total_out++;
1903 			if (flush_bytes)
1904 				flush_bytes--;
1905 		} while (zip->ppstream.avail_out &&
1906 			(zip->ppstream.avail_in || flush_bytes));
1907 
1908 		t_avail_in = (size_t)zip->ppstream.avail_in;
1909 		t_avail_out = (size_t)zip->ppstream.avail_out;
1910 		break;
1911 	}
1912 	default:
1913 		archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
1914 		    "Decompression internal error");
1915 		return (ARCHIVE_FAILED);
1916 	}
1917 	if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF)
1918 		return (ret);
1919 
1920 	*used = o_avail_in - t_avail_in;
1921 	*outbytes = o_avail_out - t_avail_out;
1922 
1923 	/*
1924 	 * Decord BCJ.
1925 	 */
1926 	if (zip->codec != _7Z_LZMA2) {
1927 		if (zip->codec2 == _7Z_X86) {
1928 			size_t l = x86_Convert(zip, buff, *outbytes);
1929 
1930 			zip->odd_bcj_size = *outbytes - l;
1931 			if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
1932 		    	o_avail_in && ret != ARCHIVE_EOF) {
1933 				memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
1934 			    	zip->odd_bcj_size);
1935 				*outbytes = l;
1936 			} else
1937 				zip->odd_bcj_size = 0;
1938 		} else if (zip->codec2 == _7Z_ARM) {
1939 			*outbytes = arm_Convert(zip, buff, *outbytes);
1940 		} else if (zip->codec2 == _7Z_ARM64) {
1941 			*outbytes = arm64_Convert(zip, buff, *outbytes);
1942 		} else if (zip->codec2 == _7Z_SPARC) {
1943 			*outbytes = sparc_Convert(zip, buff, *outbytes);
1944 		} else if (zip->codec2 == _7Z_POWERPC) {
1945 			*outbytes = powerpc_Convert(zip, buff, *outbytes);
1946 		}
1947 	}
1948 
1949 	/*
1950 	 * Decord BCJ2 with a decompressed main stream.
1951 	 */
1952 	if (zip->codec2 == _7Z_X86_BCJ2) {
1953 		ssize_t bytes;
1954 
1955 		zip->tmp_stream_bytes_avail =
1956 		    zip->tmp_stream_buff_size - t_avail_out;
1957 		if (zip->tmp_stream_bytes_avail >
1958 		      zip->main_stream_bytes_remaining)
1959 			zip->tmp_stream_bytes_avail =
1960 			    zip->main_stream_bytes_remaining;
1961 		zip->tmp_stream_bytes_remaining = zip->tmp_stream_bytes_avail;
1962 		bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out);
1963 		if (bytes < 0) {
1964 			archive_set_error(&(a->archive),
1965 			    ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed");
1966 			return (ARCHIVE_FAILED);
1967 		}
1968 		zip->main_stream_bytes_remaining -=
1969 		    zip->tmp_stream_bytes_avail
1970 		      - zip->tmp_stream_bytes_remaining;
1971 		bcj2_avail_out -= bytes;
1972 		*outbytes = o_avail_out - bcj2_avail_out;
1973 	}
1974 
1975 	return (ret);
1976 }
1977 
1978 static int
free_decompression(struct archive_read * a,struct _7zip * zip)1979 free_decompression(struct archive_read *a, struct _7zip *zip)
1980 {
1981 	int r = ARCHIVE_OK;
1982 
1983 #if !defined(HAVE_ZLIB_H) &&\
1984 	!(defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR))
1985 	(void)a;/* UNUSED */
1986 #endif
1987 #ifdef HAVE_LZMA_H
1988 	if (zip->lzstream_valid)
1989 		lzma_end(&(zip->lzstream));
1990 #endif
1991 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1992 	if (zip->bzstream_valid) {
1993 		if (BZ2_bzDecompressEnd(&(zip->bzstream)) != BZ_OK) {
1994 			archive_set_error(&a->archive,
1995 			    ARCHIVE_ERRNO_MISC,
1996 			    "Failed to clean up bzip2 decompressor");
1997 			r = ARCHIVE_FATAL;
1998 		}
1999 		zip->bzstream_valid = 0;
2000 	}
2001 #endif
2002 #ifdef HAVE_ZLIB_H
2003 	if (zip->stream_valid) {
2004 		if (inflateEnd(&(zip->stream)) != Z_OK) {
2005 			archive_set_error(&a->archive,
2006 			    ARCHIVE_ERRNO_MISC,
2007 			    "Failed to clean up zlib decompressor");
2008 			r = ARCHIVE_FATAL;
2009 		}
2010 		zip->stream_valid = 0;
2011 	}
2012 #endif
2013 #ifdef HAVE_ZSTD_H
2014 	if (zip->zstdstream_valid)
2015 		ZSTD_freeDStream(zip->zstd_dstream);
2016 #endif
2017 	if (zip->ppmd7_valid) {
2018 		__archive_ppmd7_functions.Ppmd7_Free(
2019 			&zip->ppmd7_context);
2020 		zip->ppmd7_valid = 0;
2021 	}
2022 	return (r);
2023 }
2024 
2025 static int
parse_7zip_uint64(struct archive_read * a,uint64_t * val)2026 parse_7zip_uint64(struct archive_read *a, uint64_t *val)
2027 {
2028 	const unsigned char *p;
2029 	unsigned char avail, mask;
2030 	int i;
2031 
2032 	if ((p = header_bytes(a, 1)) == NULL)
2033 		return (-1);
2034 	avail = *p;
2035 	mask = 0x80;
2036 	*val = 0;
2037 	for (i = 0; i < 8; i++) {
2038 		if (avail & mask) {
2039 			if ((p = header_bytes(a, 1)) == NULL)
2040 				return (-1);
2041 			*val |= ((uint64_t)*p) << (8 * i);
2042 			mask >>= 1;
2043 			continue;
2044 		}
2045 		*val += ((uint64_t)(avail & (mask -1))) << (8 * i);
2046 		break;
2047 	}
2048 	return (0);
2049 }
2050 
2051 static int
read_Bools(struct archive_read * a,unsigned char * data,size_t num)2052 read_Bools(struct archive_read *a, unsigned char *data, size_t num)
2053 {
2054 	const unsigned char *p;
2055 	unsigned i, mask = 0, avail = 0;
2056 
2057 	for (i = 0; i < num; i++) {
2058 		if (mask == 0) {
2059 			if ((p = header_bytes(a, 1)) == NULL)
2060 				return (-1);
2061 			avail = *p;
2062 			mask = 0x80;
2063 		}
2064 		data[i] = (avail & mask)?1:0;
2065 		mask >>= 1;
2066 	}
2067 	return (0);
2068 }
2069 
2070 static void
free_Digest(struct _7z_digests * d)2071 free_Digest(struct _7z_digests *d)
2072 {
2073 	free(d->defineds);
2074 	free(d->digests);
2075 }
2076 
2077 static int
read_Digests(struct archive_read * a,struct _7z_digests * d,size_t num)2078 read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
2079 {
2080 	const unsigned char *p;
2081 	unsigned i;
2082 
2083 	if (num == 0)
2084 		return (-1);
2085 	memset(d, 0, sizeof(*d));
2086 
2087 	d->defineds = malloc(num);
2088 	if (d->defineds == NULL)
2089 		return (-1);
2090 	/*
2091 	 * Read Bools.
2092 	 */
2093 	if ((p = header_bytes(a, 1)) == NULL)
2094 		return (-1);
2095 	if (*p == 0) {
2096 		if (read_Bools(a, d->defineds, num) < 0)
2097 			return (-1);
2098 	} else
2099 		/* All are defined */
2100 		memset(d->defineds, 1, num);
2101 
2102 	d->digests = calloc(num, sizeof(*d->digests));
2103 	if (d->digests == NULL)
2104 		return (-1);
2105 	for (i = 0; i < num; i++) {
2106 		if (d->defineds[i]) {
2107 			if ((p = header_bytes(a, 4)) == NULL)
2108 				return (-1);
2109 			d->digests[i] = archive_le32dec(p);
2110 		}
2111 	}
2112 
2113 	return (0);
2114 }
2115 
2116 static void
free_PackInfo(struct _7z_pack_info * pi)2117 free_PackInfo(struct _7z_pack_info *pi)
2118 {
2119 	free(pi->sizes);
2120 	free(pi->positions);
2121 	free_Digest(&(pi->digest));
2122 }
2123 
2124 static int
read_PackInfo(struct archive_read * a,struct _7z_pack_info * pi)2125 read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
2126 {
2127 	const unsigned char *p;
2128 	unsigned i;
2129 
2130 	memset(pi, 0, sizeof(*pi));
2131 
2132 	/*
2133 	 * Read PackPos.
2134 	 */
2135 	if (parse_7zip_uint64(a, &(pi->pos)) < 0)
2136 		return (-1);
2137 
2138 	/*
2139 	 * Read NumPackStreams.
2140 	 */
2141 	if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0)
2142 		return (-1);
2143 	if (pi->numPackStreams == 0)
2144 		return (-1);
2145 	if (UMAX_ENTRY < pi->numPackStreams)
2146 		return (-1);
2147 
2148 	/*
2149 	 * Read PackSizes[num]
2150 	 */
2151 	if ((p = header_bytes(a, 1)) == NULL)
2152 		return (-1);
2153 	if (*p == kEnd)
2154 		/* PackSizes[num] are not present. */
2155 		return (0);
2156 	if (*p != kSize)
2157 		return (-1);
2158 	pi->sizes = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
2159 	pi->positions = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
2160 	if (pi->sizes == NULL || pi->positions == NULL)
2161 		return (-1);
2162 
2163 	for (i = 0; i < pi->numPackStreams; i++) {
2164 		if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0)
2165 			return (-1);
2166 	}
2167 
2168 	/*
2169 	 * Read PackStreamDigests[num]
2170 	 */
2171 	if ((p = header_bytes(a, 1)) == NULL)
2172 		return (-1);
2173 	if (*p == kEnd) {
2174 		/* PackStreamDigests[num] are not present. */
2175 		pi->digest.defineds =
2176 		    calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.defineds));
2177 		pi->digest.digests =
2178 		    calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.digests));
2179 		if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
2180 			return (-1);
2181 		return (0);
2182 	}
2183 
2184 	if (*p != kCRC)
2185 		return (-1);
2186 
2187 	if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
2188 		return (-1);
2189 
2190 	/*
2191 	 *  Must be marked by kEnd.
2192 	 */
2193 	if ((p = header_bytes(a, 1)) == NULL)
2194 		return (-1);
2195 	if (*p != kEnd)
2196 		return (-1);
2197 	return (0);
2198 }
2199 
2200 static void
free_Folder(struct _7z_folder * f)2201 free_Folder(struct _7z_folder *f)
2202 {
2203 	unsigned i;
2204 
2205 	if (f->coders) {
2206 		for (i = 0; i< f->numCoders; i++) {
2207 			free(f->coders[i].properties);
2208 		}
2209 		free(f->coders);
2210 	}
2211 	free(f->bindPairs);
2212 	free(f->packedStreams);
2213 	free(f->unPackSize);
2214 }
2215 
2216 static int
read_Folder(struct archive_read * a,struct _7z_folder * f)2217 read_Folder(struct archive_read *a, struct _7z_folder *f)
2218 {
2219 	struct _7zip *zip = (struct _7zip *)a->format->data;
2220 	const unsigned char *p;
2221 	uint64_t numInStreamsTotal = 0;
2222 	uint64_t numOutStreamsTotal = 0;
2223 	unsigned i;
2224 
2225 	memset(f, 0, sizeof(*f));
2226 
2227 	/*
2228 	 * Read NumCoders.
2229 	 */
2230 	if (parse_7zip_uint64(a, &(f->numCoders)) < 0)
2231 		return (-1);
2232 	if (f->numCoders > 4)
2233 		/* Too many coders. */
2234 		return (-1);
2235 
2236 	f->coders = calloc((size_t)f->numCoders, sizeof(*f->coders));
2237 	if (f->coders == NULL)
2238 		return (-1);
2239 	for (i = 0; i< f->numCoders; i++) {
2240 		size_t codec_size;
2241 		int simple, attr;
2242 
2243 		if ((p = header_bytes(a, 1)) == NULL)
2244 			return (-1);
2245 		/*
2246 		 * 0:3 CodecIdSize
2247 		 * 4:  0 - IsSimple
2248 		 *     1 - Is not Simple
2249 		 * 5:  0 - No Attributes
2250 		 *     1 - There are Attributes;
2251 		 * 7:  Must be zero.
2252 		 */
2253 		codec_size = *p & 0xf;
2254 		simple = (*p & 0x10)?0:1;
2255 		attr = *p & 0x20;
2256 		if (*p & 0x80)
2257 			return (-1);/* Not supported. */
2258 
2259 		/*
2260 		 * Read Decompression Method IDs.
2261 		 */
2262 		if ((p = header_bytes(a, codec_size)) == NULL)
2263 			return (-1);
2264 
2265 		f->coders[i].codec = decode_codec_id(p, codec_size);
2266 
2267 		if (simple) {
2268 			f->coders[i].numInStreams = 1;
2269 			f->coders[i].numOutStreams = 1;
2270 		} else {
2271 			if (parse_7zip_uint64(
2272 			    a, &(f->coders[i].numInStreams)) < 0)
2273 				return (-1);
2274 			if (UMAX_ENTRY < f->coders[i].numInStreams)
2275 				return (-1);
2276 			if (parse_7zip_uint64(
2277 			    a, &(f->coders[i].numOutStreams)) < 0)
2278 				return (-1);
2279 			if (UMAX_ENTRY < f->coders[i].numOutStreams)
2280 				return (-1);
2281 		}
2282 
2283 		if (attr) {
2284 			if (parse_7zip_uint64(
2285 			    a, &(f->coders[i].propertiesSize)) < 0)
2286 				return (-1);
2287 			if (UMAX_ENTRY < f->coders[i].propertiesSize)
2288 				return (-1);
2289 			if ((p = header_bytes(
2290 			    a, (size_t)f->coders[i].propertiesSize)) == NULL)
2291 				return (-1);
2292 			f->coders[i].properties =
2293 			    malloc((size_t)f->coders[i].propertiesSize);
2294 			if (f->coders[i].properties == NULL)
2295 				return (-1);
2296 			memcpy(f->coders[i].properties, p,
2297 			    (size_t)f->coders[i].propertiesSize);
2298 		}
2299 
2300 		numInStreamsTotal += f->coders[i].numInStreams;
2301 		numOutStreamsTotal += f->coders[i].numOutStreams;
2302 	}
2303 
2304 	if (numOutStreamsTotal == 0 ||
2305 	    numInStreamsTotal < numOutStreamsTotal-1)
2306 		return (-1);
2307 
2308 	f->numBindPairs = numOutStreamsTotal - 1;
2309 	if (zip->header_bytes_remaining < f->numBindPairs)
2310 			return (-1);
2311 	if (f->numBindPairs > 0) {
2312 		f->bindPairs =
2313 			calloc((size_t)f->numBindPairs, sizeof(*f->bindPairs));
2314 		if (f->bindPairs == NULL)
2315 			return (-1);
2316 	} else
2317 		f->bindPairs = NULL;
2318 	for (i = 0; i < f->numBindPairs; i++) {
2319 		if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
2320 			return (-1);
2321 		if (UMAX_ENTRY < f->bindPairs[i].inIndex)
2322 			return (-1);
2323 		if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
2324 			return (-1);
2325 		if (UMAX_ENTRY < f->bindPairs[i].outIndex)
2326 			return (-1);
2327 	}
2328 
2329 	f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
2330 	f->packedStreams =
2331 	    calloc((size_t)f->numPackedStreams, sizeof(*f->packedStreams));
2332 	if (f->packedStreams == NULL)
2333 		return (-1);
2334 	if (f->numPackedStreams == 1) {
2335 		for (i = 0; i < numInStreamsTotal; i++) {
2336 			unsigned j;
2337 			for (j = 0; j < f->numBindPairs; j++) {
2338 				if (f->bindPairs[j].inIndex == i)
2339 					break;
2340 			}
2341 			if (j == f->numBindPairs)
2342 				break;
2343 		}
2344 		if (i == numInStreamsTotal)
2345 			return (-1);
2346 		f->packedStreams[0] = i;
2347 	} else {
2348 		for (i = 0; i < f->numPackedStreams; i++) {
2349 			if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
2350 				return (-1);
2351 			if (UMAX_ENTRY < f->packedStreams[i])
2352 				return (-1);
2353 		}
2354 	}
2355 	f->numInStreams = numInStreamsTotal;
2356 	f->numOutStreams = numOutStreamsTotal;
2357 
2358 	return (0);
2359 }
2360 
2361 static void
free_CodersInfo(struct _7z_coders_info * ci)2362 free_CodersInfo(struct _7z_coders_info *ci)
2363 {
2364 	unsigned i;
2365 
2366 	if (ci->folders) {
2367 		for (i = 0; i < ci->numFolders; i++)
2368 			free_Folder(&(ci->folders[i]));
2369 		free(ci->folders);
2370 	}
2371 }
2372 
2373 static int
read_CodersInfo(struct archive_read * a,struct _7z_coders_info * ci)2374 read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
2375 {
2376 	const unsigned char *p;
2377 	struct _7z_digests digest;
2378 	unsigned i;
2379 
2380 	memset(ci, 0, sizeof(*ci));
2381 	memset(&digest, 0, sizeof(digest));
2382 
2383 	if ((p = header_bytes(a, 1)) == NULL)
2384 		goto failed;
2385 	if (*p != kFolder)
2386 		goto failed;
2387 
2388 	/*
2389 	 * Read NumFolders.
2390 	 */
2391 	if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
2392 		goto failed;
2393 	if (UMAX_ENTRY < ci->numFolders)
2394 		return (-1);
2395 
2396 	/*
2397 	 * Read External.
2398 	 */
2399 	if ((p = header_bytes(a, 1)) == NULL)
2400 		goto failed;
2401 	switch (*p) {
2402 	case 0:
2403 		ci->folders =
2404 			calloc((size_t)ci->numFolders, sizeof(*ci->folders));
2405 		if (ci->folders == NULL)
2406 			return (-1);
2407 		for (i = 0; i < ci->numFolders; i++) {
2408 			if (read_Folder(a, &(ci->folders[i])) < 0)
2409 				goto failed;
2410 		}
2411 		break;
2412 	case 1:
2413 		if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
2414 			return (-1);
2415 		if (UMAX_ENTRY < ci->dataStreamIndex)
2416 			return (-1);
2417 		if (ci->numFolders > 0) {
2418 			archive_set_error(&a->archive, -1,
2419 			    "Malformed 7-Zip archive");
2420 			goto failed;
2421 		}
2422 		break;
2423 	default:
2424 		archive_set_error(&a->archive, -1,
2425 		    "Malformed 7-Zip archive");
2426 		goto failed;
2427 	}
2428 
2429 	if ((p = header_bytes(a, 1)) == NULL)
2430 		goto failed;
2431 	if (*p != kCodersUnPackSize)
2432 		goto failed;
2433 
2434 	for (i = 0; i < ci->numFolders; i++) {
2435 		struct _7z_folder *folder = &(ci->folders[i]);
2436 		unsigned j;
2437 
2438 		folder->unPackSize =
2439 		    calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize));
2440 		if (folder->unPackSize == NULL)
2441 			goto failed;
2442 		for (j = 0; j < folder->numOutStreams; j++) {
2443 			if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
2444 				goto failed;
2445 		}
2446 	}
2447 
2448 	/*
2449 	 * Read CRCs.
2450 	 */
2451 	if ((p = header_bytes(a, 1)) == NULL)
2452 		goto failed;
2453 	if (*p == kEnd)
2454 		return (0);
2455 	if (*p != kCRC)
2456 		goto failed;
2457 	if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0)
2458 		goto failed;
2459 	for (i = 0; i < ci->numFolders; i++) {
2460 		ci->folders[i].digest_defined = digest.defineds[i];
2461 		ci->folders[i].digest = digest.digests[i];
2462 	}
2463 
2464 	/*
2465 	 *  Must be kEnd.
2466 	 */
2467 	if ((p = header_bytes(a, 1)) == NULL)
2468 		goto failed;
2469 	if (*p != kEnd)
2470 		goto failed;
2471 	free_Digest(&digest);
2472 	return (0);
2473 failed:
2474 	free_Digest(&digest);
2475 	return (-1);
2476 }
2477 
2478 static uint64_t
folder_uncompressed_size(struct _7z_folder * f)2479 folder_uncompressed_size(struct _7z_folder *f)
2480 {
2481 	int n = (int)f->numOutStreams;
2482 	unsigned pairs = (unsigned)f->numBindPairs;
2483 
2484 	while (--n >= 0) {
2485 		unsigned i;
2486 		for (i = 0; i < pairs; i++) {
2487 			if (f->bindPairs[i].outIndex == (uint64_t)n)
2488 				break;
2489 		}
2490 		if (i >= pairs)
2491 			return (f->unPackSize[n]);
2492 	}
2493 	return (0);
2494 }
2495 
2496 static void
free_SubStreamsInfo(struct _7z_substream_info * ss)2497 free_SubStreamsInfo(struct _7z_substream_info *ss)
2498 {
2499 	free(ss->unpackSizes);
2500 	free(ss->digestsDefined);
2501 	free(ss->digests);
2502 }
2503 
2504 static int
read_SubStreamsInfo(struct archive_read * a,struct _7z_substream_info * ss,struct _7z_folder * f,size_t numFolders)2505 read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
2506     struct _7z_folder *f, size_t numFolders)
2507 {
2508 	const unsigned char *p;
2509 	uint64_t *usizes;
2510 	size_t unpack_streams;
2511 	int type;
2512 	unsigned i;
2513 	uint32_t numDigests;
2514 
2515 	memset(ss, 0, sizeof(*ss));
2516 
2517 	for (i = 0; i < numFolders; i++)
2518 		f[i].numUnpackStreams = 1;
2519 
2520 	if ((p = header_bytes(a, 1)) == NULL)
2521 		return (-1);
2522 	type = *p;
2523 
2524 	if (type == kNumUnPackStream) {
2525 		unpack_streams = 0;
2526 		for (i = 0; i < numFolders; i++) {
2527 			if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
2528 				return (-1);
2529 			if (UMAX_ENTRY < f[i].numUnpackStreams)
2530 				return (-1);
2531 			if (unpack_streams > SIZE_MAX - UMAX_ENTRY) {
2532 				return (-1);
2533 			}
2534 			unpack_streams += (size_t)f[i].numUnpackStreams;
2535 		}
2536 		if ((p = header_bytes(a, 1)) == NULL)
2537 			return (-1);
2538 		type = *p;
2539 	} else
2540 		unpack_streams = numFolders;
2541 
2542 	ss->unpack_streams = unpack_streams;
2543 	if (unpack_streams) {
2544 		ss->unpackSizes = calloc(unpack_streams,
2545 		    sizeof(*ss->unpackSizes));
2546 		ss->digestsDefined = calloc(unpack_streams,
2547 		    sizeof(*ss->digestsDefined));
2548 		ss->digests = calloc(unpack_streams,
2549 		    sizeof(*ss->digests));
2550 		if (ss->unpackSizes == NULL || ss->digestsDefined == NULL ||
2551 		    ss->digests == NULL)
2552 			return (-1);
2553 	}
2554 
2555 	usizes = ss->unpackSizes;
2556 	for (i = 0; i < numFolders; i++) {
2557 		unsigned pack;
2558 		uint64_t size, sum;
2559 
2560 		if (f[i].numUnpackStreams == 0)
2561 			continue;
2562 
2563 		sum = 0;
2564 		if (type == kSize) {
2565 			for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
2566 				if (parse_7zip_uint64(a, usizes) < 0)
2567 					return (-1);
2568 				if (*usizes > UINT64_MAX - sum)
2569 					return (-1);
2570 				sum += *usizes++;
2571 			}
2572 		}
2573 		size = folder_uncompressed_size(&f[i]);
2574 		if (size < sum)
2575 			return (-1);
2576 		*usizes++ = size - sum;
2577 	}
2578 
2579 	if (type == kSize) {
2580 		if ((p = header_bytes(a, 1)) == NULL)
2581 			return (-1);
2582 		type = *p;
2583 	}
2584 
2585 	for (i = 0; i < unpack_streams; i++) {
2586 		ss->digestsDefined[i] = 0;
2587 		ss->digests[i] = 0;
2588 	}
2589 
2590 	numDigests = 0;
2591 	for (i = 0; i < numFolders; i++) {
2592 		if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
2593 			numDigests += (uint32_t)f[i].numUnpackStreams;
2594 	}
2595 
2596 	if (type == kCRC) {
2597 		struct _7z_digests tmpDigests;
2598 		unsigned char *digestsDefined = ss->digestsDefined;
2599 		uint32_t * digests = ss->digests;
2600 		int di = 0;
2601 
2602 		memset(&tmpDigests, 0, sizeof(tmpDigests));
2603 		if (read_Digests(a, &(tmpDigests), numDigests) < 0) {
2604 			free_Digest(&tmpDigests);
2605 			return (-1);
2606 		}
2607 		for (i = 0; i < numFolders; i++) {
2608 			if (f[i].numUnpackStreams == 1 && f[i].digest_defined) {
2609 				*digestsDefined++ = 1;
2610 				*digests++ = f[i].digest;
2611 			} else {
2612 				unsigned j;
2613 
2614 				for (j = 0; j < f[i].numUnpackStreams;
2615 				    j++, di++) {
2616 					*digestsDefined++ =
2617 					    tmpDigests.defineds[di];
2618 					*digests++ =
2619 					    tmpDigests.digests[di];
2620 				}
2621 			}
2622 		}
2623 		free_Digest(&tmpDigests);
2624 		if ((p = header_bytes(a, 1)) == NULL)
2625 			return (-1);
2626 		type = *p;
2627 	}
2628 
2629 	/*
2630 	 *  Must be kEnd.
2631 	 */
2632 	if (type != kEnd)
2633 		return (-1);
2634 	return (0);
2635 }
2636 
2637 static void
free_StreamsInfo(struct _7z_stream_info * si)2638 free_StreamsInfo(struct _7z_stream_info *si)
2639 {
2640 	free_PackInfo(&(si->pi));
2641 	free_CodersInfo(&(si->ci));
2642 	free_SubStreamsInfo(&(si->ss));
2643 }
2644 
2645 static int
read_StreamsInfo(struct archive_read * a,struct _7z_stream_info * si)2646 read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
2647 {
2648 	struct _7zip *zip = (struct _7zip *)a->format->data;
2649 	const unsigned char *p;
2650 	unsigned i;
2651 
2652 	memset(si, 0, sizeof(*si));
2653 
2654 	if ((p = header_bytes(a, 1)) == NULL)
2655 		return (-1);
2656 	if (*p == kPackInfo) {
2657 		uint64_t packPos;
2658 
2659 		if (read_PackInfo(a, &(si->pi)) < 0)
2660 			return (-1);
2661 
2662 		if (si->pi.positions == NULL || si->pi.sizes == NULL)
2663 			return (-1);
2664 		/*
2665 		 * Calculate packed stream positions.
2666 		 */
2667 		packPos = si->pi.pos;
2668 		for (i = 0; i < si->pi.numPackStreams; i++) {
2669 			si->pi.positions[i] = packPos;
2670 			if (packPos > UINT64_MAX - si->pi.sizes[i])
2671 				return (-1);
2672 			packPos += si->pi.sizes[i];
2673 			if (packPos > zip->header_offset)
2674 				return (-1);
2675 		}
2676 		if ((p = header_bytes(a, 1)) == NULL)
2677 			return (-1);
2678 	}
2679 	if (*p == kUnPackInfo) {
2680 		uint32_t packIndex;
2681 		struct _7z_folder *f;
2682 
2683 		if (read_CodersInfo(a, &(si->ci)) < 0)
2684 			return (-1);
2685 
2686 		/*
2687 		 * Calculate packed stream indexes.
2688 		 */
2689 		packIndex = 0;
2690 		f = si->ci.folders;
2691 		for (i = 0; i < si->ci.numFolders; i++) {
2692 			f[i].packIndex = packIndex;
2693 			if (f[i].numPackedStreams > UINT32_MAX)
2694 				return (-1);
2695 			if (packIndex > UINT32_MAX - (uint32_t)f[i].numPackedStreams)
2696 				return (-1);
2697 			packIndex += (uint32_t)f[i].numPackedStreams;
2698 			if (packIndex > si->pi.numPackStreams)
2699 				return (-1);
2700 		}
2701 		if ((p = header_bytes(a, 1)) == NULL)
2702 			return (-1);
2703 	}
2704 
2705 	if (*p == kSubStreamsInfo) {
2706 		if (read_SubStreamsInfo(a, &(si->ss),
2707 		    si->ci.folders, (size_t)si->ci.numFolders) < 0)
2708 			return (-1);
2709 		if ((p = header_bytes(a, 1)) == NULL)
2710 			return (-1);
2711 	}
2712 
2713 	/*
2714 	 *  Must be kEnd.
2715 	 */
2716 	if (*p != kEnd)
2717 		return (-1);
2718 	return (0);
2719 }
2720 
2721 static void
free_Header(struct _7z_header_info * h)2722 free_Header(struct _7z_header_info *h)
2723 {
2724 	free(h->emptyStreamBools);
2725 	free(h->emptyFileBools);
2726 	free(h->antiBools);
2727 	free(h->attrBools);
2728 }
2729 
2730 static int
read_Header(struct archive_read * a,struct _7z_header_info * h,int check_header_id)2731 read_Header(struct archive_read *a, struct _7z_header_info *h,
2732     int check_header_id)
2733 {
2734 	struct _7zip *zip = (struct _7zip *)a->format->data;
2735 	const unsigned char *p;
2736 	struct _7z_folder *folders;
2737 	struct _7z_stream_info *si = &(zip->si);
2738 	struct _7zip_entry *entries;
2739 	uint32_t folderIndex, indexInFolder;
2740 	unsigned i;
2741 	int eindex, empty_streams, sindex;
2742 
2743 	if (check_header_id) {
2744 		/*
2745 		 * Read Header.
2746 		 */
2747 		if ((p = header_bytes(a, 1)) == NULL)
2748 			return (-1);
2749 		if (*p != kHeader)
2750 			return (-1);
2751 	}
2752 
2753 	/*
2754 	 * Read ArchiveProperties.
2755 	 */
2756 	if ((p = header_bytes(a, 1)) == NULL)
2757 		return (-1);
2758 	if (*p == kArchiveProperties) {
2759 		for (;;) {
2760 			uint64_t size;
2761 			if ((p = header_bytes(a, 1)) == NULL)
2762 				return (-1);
2763 			if (*p == 0)
2764 				break;
2765 			if (parse_7zip_uint64(a, &size) < 0)
2766 				return (-1);
2767 		}
2768 		if ((p = header_bytes(a, 1)) == NULL)
2769 			return (-1);
2770 	}
2771 
2772 	/*
2773 	 * Read MainStreamsInfo.
2774 	 */
2775 	if (*p == kMainStreamsInfo) {
2776 		if (read_StreamsInfo(a, &(zip->si)) < 0)
2777 			return (-1);
2778 		if ((p = header_bytes(a, 1)) == NULL)
2779 			return (-1);
2780 	}
2781 	if (*p == kEnd)
2782 		return (0);
2783 
2784 	/*
2785 	 * Read FilesInfo.
2786 	 */
2787 	if (*p != kFilesInfo)
2788 		return (-1);
2789 
2790 	if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
2791 		return (-1);
2792 	if (UMAX_ENTRY < zip->numFiles)
2793 		return (-1);
2794 
2795 	zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries));
2796 	if (zip->entries == NULL)
2797 		return (-1);
2798 	entries = zip->entries;
2799 
2800 	empty_streams = 0;
2801 	for (;;) {
2802 		int type;
2803 		uint64_t size;
2804 		size_t ll;
2805 
2806 		if ((p = header_bytes(a, 1)) == NULL)
2807 			return (-1);
2808 		type = *p;
2809 		if (type == kEnd)
2810 			break;
2811 
2812 		if (parse_7zip_uint64(a, &size) < 0)
2813 			return (-1);
2814 		if (zip->header_bytes_remaining < size)
2815 			return (-1);
2816 		ll = (size_t)size;
2817 
2818 		switch (type) {
2819 		case kEmptyStream:
2820 			if (h->emptyStreamBools != NULL)
2821 				return (-1);
2822 			h->emptyStreamBools = calloc((size_t)zip->numFiles,
2823 			    sizeof(*h->emptyStreamBools));
2824 			if (h->emptyStreamBools == NULL)
2825 				return (-1);
2826 			if (read_Bools(
2827 			    a, h->emptyStreamBools, (size_t)zip->numFiles) < 0)
2828 				return (-1);
2829 			empty_streams = 0;
2830 			for (i = 0; i < zip->numFiles; i++) {
2831 				if (h->emptyStreamBools[i])
2832 					empty_streams++;
2833 			}
2834 			break;
2835 		case kEmptyFile:
2836 			if (empty_streams <= 0) {
2837 				/* Unexcepted sequence. Skip this. */
2838 				if (header_bytes(a, ll) == NULL)
2839 					return (-1);
2840 				break;
2841 			}
2842 			if (h->emptyFileBools != NULL)
2843 				return (-1);
2844 			h->emptyFileBools = calloc(empty_streams,
2845 			    sizeof(*h->emptyFileBools));
2846 			if (h->emptyFileBools == NULL)
2847 				return (-1);
2848 			if (read_Bools(a, h->emptyFileBools, empty_streams) < 0)
2849 				return (-1);
2850 			break;
2851 		case kAnti:
2852 			if (empty_streams <= 0) {
2853 				/* Unexcepted sequence. Skip this. */
2854 				if (header_bytes(a, ll) == NULL)
2855 					return (-1);
2856 				break;
2857 			}
2858 			if (h->antiBools != NULL)
2859 				return (-1);
2860 			h->antiBools = calloc(empty_streams,
2861 			    sizeof(*h->antiBools));
2862 			if (h->antiBools == NULL)
2863 				return (-1);
2864 			if (read_Bools(a, h->antiBools, empty_streams) < 0)
2865 				return (-1);
2866 			break;
2867 		case kCTime:
2868 		case kATime:
2869 		case kMTime:
2870 			if (read_Times(a, h, type) < 0)
2871 				return (-1);
2872 			break;
2873 		case kName:
2874 		{
2875 			unsigned char *np;
2876 			size_t nl, nb;
2877 
2878 			/* Skip one byte. */
2879 			if ((p = header_bytes(a, 1)) == NULL)
2880 				return (-1);
2881 			ll--;
2882 
2883 			if ((ll & 1) || ll < zip->numFiles * 4)
2884 				return (-1);
2885 
2886 			if (zip->entry_names != NULL)
2887 				return (-1);
2888 			zip->entry_names = malloc(ll);
2889 			if (zip->entry_names == NULL)
2890 				return (-1);
2891 			np = zip->entry_names;
2892 			nb = ll;
2893 			/*
2894 			 * Copy whole file names.
2895 			 * NOTE: This loop prevents from expanding
2896 			 * the uncompressed buffer in order not to
2897 			 * use extra memory resource.
2898 			 */
2899 			while (nb) {
2900 				size_t b;
2901 				if (nb > UBUFF_SIZE)
2902 					b = UBUFF_SIZE;
2903 				else
2904 					b = nb;
2905 				if ((p = header_bytes(a, b)) == NULL)
2906 					return (-1);
2907 				memcpy(np, p, b);
2908 				np += b;
2909 				nb -= b;
2910 			}
2911 			np = zip->entry_names;
2912 			nl = ll;
2913 
2914 			for (i = 0; i < zip->numFiles; i++) {
2915 				entries[i].utf16name = np;
2916 #if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
2917 				entries[i].wname = (wchar_t *)np;
2918 #endif
2919 
2920 				/* Find a terminator. */
2921 				while (nl >= 2 && (np[0] || np[1])) {
2922 					np += 2;
2923 					nl -= 2;
2924 				}
2925 				if (nl < 2)
2926 					return (-1);/* Terminator not found */
2927 				entries[i].name_len = np - entries[i].utf16name;
2928 				np += 2;
2929 				nl -= 2;
2930 			}
2931 			break;
2932 		}
2933 		case kAttributes:
2934 		{
2935 			int allAreDefined;
2936 
2937 			if ((p = header_bytes(a, 2)) == NULL)
2938 				return (-1);
2939 			allAreDefined = *p;
2940 			if (h->attrBools != NULL)
2941 				return (-1);
2942 			h->attrBools = calloc((size_t)zip->numFiles,
2943 			    sizeof(*h->attrBools));
2944 			if (h->attrBools == NULL)
2945 				return (-1);
2946 			if (allAreDefined)
2947 				memset(h->attrBools, 1, (size_t)zip->numFiles);
2948 			else {
2949 				if (read_Bools(a, h->attrBools,
2950 				      (size_t)zip->numFiles) < 0)
2951 					return (-1);
2952 			}
2953 			for (i = 0; i < zip->numFiles; i++) {
2954 				if (h->attrBools[i]) {
2955 					if ((p = header_bytes(a, 4)) == NULL)
2956 						return (-1);
2957 					entries[i].attr = archive_le32dec(p);
2958 				}
2959 			}
2960 			break;
2961 		}
2962 		case kDummy:
2963 			if (ll == 0)
2964 				break;
2965 			__LA_FALLTHROUGH;
2966 		default:
2967 			if (header_bytes(a, ll) == NULL)
2968 				return (-1);
2969 			break;
2970 		}
2971 	}
2972 
2973 	/*
2974 	 * Set up entry's attributes.
2975 	 */
2976 	folders = si->ci.folders;
2977 	eindex = sindex = 0;
2978 	folderIndex = indexInFolder = 0;
2979 	for (i = 0; i < zip->numFiles; i++) {
2980 		if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0)
2981 			entries[i].flg |= HAS_STREAM;
2982 		/* The high 16 bits of attributes is a posix file mode. */
2983 		entries[i].mode = entries[i].attr >> 16;
2984 
2985 		if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) {
2986 			// Only windows permissions specified for this entry. Translate to
2987 			// reasonable corresponding unix permissions.
2988 
2989 			if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
2990 				if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
2991 					// Read-only directory.
2992 					entries[i].mode = AE_IFDIR | 0555;
2993 				} else {
2994 					// Read-write directory.
2995 					entries[i].mode = AE_IFDIR | 0755;
2996 				}
2997 			} else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
2998 				// Readonly file.
2999 				entries[i].mode = AE_IFREG | 0444;
3000 			} else {
3001 				// Assume read-write file.
3002 				entries[i].mode = AE_IFREG | 0644;
3003 			}
3004 		}
3005 
3006 		if (entries[i].flg & HAS_STREAM) {
3007 			if ((size_t)sindex >= si->ss.unpack_streams)
3008 				return (-1);
3009 			if (entries[i].mode == 0)
3010 				entries[i].mode = AE_IFREG | 0666;
3011 			if (si->ss.digestsDefined[sindex])
3012 				entries[i].flg |= CRC32_IS_SET;
3013 			entries[i].ssIndex = sindex;
3014 			sindex++;
3015 		} else {
3016 			int dir;
3017 			if (h->emptyFileBools == NULL)
3018 				dir = 1;
3019 			else {
3020 				if (h->emptyFileBools[eindex])
3021 					dir = 0;
3022 				else
3023 					dir = 1;
3024 				eindex++;
3025 			}
3026 			if (entries[i].mode == 0) {
3027 				if (dir)
3028 					entries[i].mode = AE_IFDIR | 0777;
3029 				else
3030 					entries[i].mode = AE_IFREG | 0666;
3031 			} else if (dir &&
3032 			    (entries[i].mode & AE_IFMT) != AE_IFDIR) {
3033 				entries[i].mode &= ~AE_IFMT;
3034 				entries[i].mode |= AE_IFDIR;
3035 			}
3036 			if ((entries[i].mode & AE_IFMT) == AE_IFDIR &&
3037 			    entries[i].name_len >= 2 &&
3038 			    (entries[i].utf16name[entries[i].name_len-2] != '/' ||
3039 			     entries[i].utf16name[entries[i].name_len-1] != 0)) {
3040 				entries[i].utf16name[entries[i].name_len] = '/';
3041 				entries[i].utf16name[entries[i].name_len+1] = 0;
3042 				entries[i].name_len += 2;
3043 			}
3044 			entries[i].ssIndex = -1;
3045 		}
3046 		if (entries[i].attr & FILE_ATTRIBUTE_READONLY)
3047 			entries[i].mode &= ~0222;/* Read only. */
3048 
3049 		if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
3050 			/*
3051 			 * The entry is an empty file or a directory file,
3052 			 * those both have no contents.
3053 			 */
3054 			entries[i].folderIndex = -1;
3055 			continue;
3056 		}
3057 		if (indexInFolder == 0) {
3058 			for (;;) {
3059 				if (folderIndex >= si->ci.numFolders)
3060 					return (-1);
3061 				if (folders[folderIndex].numUnpackStreams)
3062 					break;
3063 				folderIndex++;
3064 			}
3065 		}
3066 		entries[i].folderIndex = folderIndex;
3067 		if ((entries[i].flg & HAS_STREAM) == 0)
3068 			continue;
3069 		indexInFolder++;
3070 		if (indexInFolder >= folders[folderIndex].numUnpackStreams) {
3071 			folderIndex++;
3072 			indexInFolder = 0;
3073 		}
3074 	}
3075 
3076 	return (0);
3077 }
3078 
3079 static int
read_Times(struct archive_read * a,struct _7z_header_info * h,int type)3080 read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
3081 {
3082 	struct _7zip *zip = (struct _7zip *)a->format->data;
3083 	const unsigned char *p;
3084 	struct _7zip_entry *entries = zip->entries;
3085 	unsigned char *timeBools;
3086 	int allAreDefined;
3087 	unsigned i;
3088 
3089 	timeBools = calloc((size_t)zip->numFiles, sizeof(*timeBools));
3090 	if (timeBools == NULL)
3091 		return (-1);
3092 
3093 	/* Read allAreDefined. */
3094 	if ((p = header_bytes(a, 1)) == NULL)
3095 		goto failed;
3096 	allAreDefined = *p;
3097 	if (allAreDefined)
3098 		memset(timeBools, 1, (size_t)zip->numFiles);
3099 	else {
3100 		if (read_Bools(a, timeBools, (size_t)zip->numFiles) < 0)
3101 			goto failed;
3102 	}
3103 
3104 	/* Read external. */
3105 	if ((p = header_bytes(a, 1)) == NULL)
3106 		goto failed;
3107 	if (*p) {
3108 		if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
3109 			goto failed;
3110 		if (UMAX_ENTRY < h->dataIndex)
3111 			goto failed;
3112 	}
3113 
3114 	for (i = 0; i < zip->numFiles; i++) {
3115 		if (!timeBools[i])
3116 			continue;
3117 		if ((p = header_bytes(a, 8)) == NULL)
3118 			goto failed;
3119 		switch (type) {
3120 		case kCTime:
3121 			ntfs_to_unix(archive_le64dec(p),
3122 			    &(entries[i].ctime),
3123 			    &(entries[i].ctime_ns));
3124 			entries[i].flg |= CTIME_IS_SET;
3125 			break;
3126 		case kATime:
3127 			ntfs_to_unix(archive_le64dec(p),
3128 			    &(entries[i].atime),
3129 			    &(entries[i].atime_ns));
3130 			entries[i].flg |= ATIME_IS_SET;
3131 			break;
3132 		case kMTime:
3133 			ntfs_to_unix(archive_le64dec(p),
3134 			    &(entries[i].mtime),
3135 			    &(entries[i].mtime_ns));
3136 			entries[i].flg |= MTIME_IS_SET;
3137 			break;
3138 		}
3139 	}
3140 
3141 	free(timeBools);
3142 	return (0);
3143 failed:
3144 	free(timeBools);
3145 	return (-1);
3146 }
3147 
3148 static int
decode_encoded_header_info(struct archive_read * a,struct _7z_stream_info * si)3149 decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si)
3150 {
3151 	struct _7zip *zip = (struct _7zip *)a->format->data;
3152 
3153 	errno = 0;
3154 	if (read_StreamsInfo(a, si) < 0) {
3155 		if (errno == ENOMEM)
3156 			archive_set_error(&a->archive, -1,
3157 			    "Couldn't allocate memory");
3158 		else
3159 			archive_set_error(&a->archive, -1,
3160 			    "Malformed 7-Zip archive");
3161 		return (ARCHIVE_FATAL);
3162 	}
3163 
3164 	if (si->pi.numPackStreams == 0 || si->ci.numFolders == 0) {
3165 		archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
3166 		return (ARCHIVE_FATAL);
3167 	}
3168 
3169 	if (zip->header_offset < si->pi.pos + si->pi.sizes[0] ||
3170 	    (int64_t)(si->pi.pos + si->pi.sizes[0]) < 0 ||
3171 	    si->pi.sizes[0] == 0 || (int64_t)si->pi.pos < 0) {
3172 		archive_set_error(&a->archive, -1, "Malformed Header offset");
3173 		return (ARCHIVE_FATAL);
3174 	}
3175 
3176 	return (ARCHIVE_OK);
3177 }
3178 
3179 static const unsigned char *
header_bytes(struct archive_read * a,size_t rbytes)3180 header_bytes(struct archive_read *a, size_t rbytes)
3181 {
3182 	struct _7zip *zip = (struct _7zip *)a->format->data;
3183 	const unsigned char *p;
3184 
3185 	if (zip->header_bytes_remaining < rbytes)
3186 		return (NULL);
3187 	if (zip->pack_stream_bytes_unconsumed)
3188 		read_consume(a);
3189 
3190 	if (zip->header_is_encoded == 0) {
3191 		p = __archive_read_ahead(a, rbytes, NULL);
3192 		if (p == NULL)
3193 			return (NULL);
3194 		zip->header_bytes_remaining -= rbytes;
3195 		zip->pack_stream_bytes_unconsumed = rbytes;
3196 	} else {
3197 		const void *buff;
3198 		ssize_t bytes;
3199 
3200 		bytes = read_stream(a, &buff, rbytes, rbytes);
3201 		if (bytes <= 0)
3202 			return (NULL);
3203 		zip->header_bytes_remaining -= bytes;
3204 		p = buff;
3205 	}
3206 
3207 	/* Update checksum */
3208 	zip->header_crc32 = crc32(zip->header_crc32, p, (unsigned)rbytes);
3209 	return (p);
3210 }
3211 
3212 static int
slurp_central_directory(struct archive_read * a,struct _7zip * zip,struct _7z_header_info * header)3213 slurp_central_directory(struct archive_read *a, struct _7zip *zip,
3214     struct _7z_header_info *header)
3215 {
3216 	const unsigned char *p;
3217 	uint64_t next_header_offset;
3218 	uint64_t next_header_size;
3219 	uint32_t next_header_crc;
3220 	ssize_t bytes_avail;
3221 	int check_header_crc, r;
3222 
3223 	if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
3224 		return (ARCHIVE_FATAL);
3225 
3226 	if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
3227 		/* This is an executable ? Must be self-extracting... */
3228 		const ssize_t min_addr = p[0] == 'M' ? find_pe_overlay(a) :
3229 						       find_elf_data_sec(a);
3230 		r = skip_sfx(a, min_addr);
3231 		if (r < ARCHIVE_WARN)
3232 			return (r);
3233 		if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
3234 			return (ARCHIVE_FATAL);
3235 	}
3236 	zip->seek_base += 32;
3237 
3238 	if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) {
3239 		archive_set_error(&a->archive, -1, "Not 7-Zip archive file");
3240 		return (ARCHIVE_FATAL);
3241 	}
3242 
3243 	/* CRC check. */
3244 	if (crc32(0, (const unsigned char *)p + 12, 20)
3245 	    != archive_le32dec(p + 8)) {
3246 #ifndef DONT_FAIL_ON_CRC_ERROR
3247 		archive_set_error(&a->archive, -1, "Header CRC error");
3248 		return (ARCHIVE_FATAL);
3249 #endif
3250 	}
3251 
3252 	next_header_offset = archive_le64dec(p + 12);
3253 	next_header_size = archive_le64dec(p + 20);
3254 	next_header_crc = archive_le32dec(p + 28);
3255 
3256 	if (next_header_size == 0)
3257 		/* There is no entry in an archive file. */
3258 		return (ARCHIVE_EOF);
3259 
3260 	if (((int64_t)next_header_offset) < 0) {
3261 		archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
3262 		return (ARCHIVE_FATAL);
3263 	}
3264 	__archive_read_consume(a, 32);
3265 	if (next_header_offset != 0) {
3266 		if (bytes_avail >= (ssize_t)next_header_offset)
3267 			__archive_read_consume(a, next_header_offset);
3268 		else if (__archive_read_seek(a,
3269 		    next_header_offset + zip->seek_base, SEEK_SET) < 0)
3270 			return (ARCHIVE_FATAL);
3271 	}
3272 	zip->stream_offset = next_header_offset;
3273 	zip->header_offset = next_header_offset;
3274 	zip->header_bytes_remaining = next_header_size;
3275 	zip->header_crc32 = 0;
3276 	zip->header_is_encoded = 0;
3277 	zip->header_is_being_read = 1;
3278 	zip->has_encrypted_entries = 0;
3279 	check_header_crc = 1;
3280 
3281 	if ((p = header_bytes(a, 1)) == NULL) {
3282 		archive_set_error(&a->archive,
3283 		    ARCHIVE_ERRNO_FILE_FORMAT,
3284 		    "Truncated 7-Zip file body");
3285 		return (ARCHIVE_FATAL);
3286 	}
3287 	/* Parse ArchiveProperties. */
3288 	switch (p[0]) {
3289 	case kEncodedHeader:
3290 		/*
3291 		 * The archive has an encoded header and we have to decode it
3292 		 * in order to parse the header correctly.
3293 		 */
3294 		r = decode_encoded_header_info(a, &(zip->si));
3295 
3296 		/* Check the EncodedHeader CRC.*/
3297 		if (r == 0 && zip->header_crc32 != next_header_crc) {
3298 #ifndef DONT_FAIL_ON_CRC_ERROR
3299 			archive_set_error(&a->archive, -1,
3300 			    "Damaged 7-Zip archive");
3301 			r = -1;
3302 #endif
3303 		}
3304 		if (r == 0) {
3305 			if (zip->si.ci.folders[0].digest_defined)
3306 				next_header_crc = zip->si.ci.folders[0].digest;
3307 			else
3308 				check_header_crc = 0;
3309 			if (zip->pack_stream_bytes_unconsumed)
3310 				read_consume(a);
3311 			r = setup_decode_folder(a, zip->si.ci.folders, 1);
3312 			if (r == 0) {
3313 				zip->header_bytes_remaining =
3314 					zip->folder_outbytes_remaining;
3315 				r = seek_pack(a);
3316 			}
3317 		}
3318 		/* Clean up StreamsInfo. */
3319 		free_StreamsInfo(&(zip->si));
3320 		memset(&(zip->si), 0, sizeof(zip->si));
3321 		if (r < 0)
3322 			return (ARCHIVE_FATAL);
3323 		zip->header_is_encoded = 1;
3324 		zip->header_crc32 = 0;
3325 		/* FALL THROUGH */
3326 	case kHeader:
3327 		/*
3328 		 * Parse the header.
3329 		 */
3330 		errno = 0;
3331 		r = read_Header(a, header, zip->header_is_encoded);
3332 		if (r < 0) {
3333 			if (errno == ENOMEM)
3334 				archive_set_error(&a->archive, -1,
3335 				    "Couldn't allocate memory");
3336 			else
3337 				archive_set_error(&a->archive, -1,
3338 				    "Damaged 7-Zip archive");
3339 			return (ARCHIVE_FATAL);
3340 		}
3341 
3342 		/*
3343 		 *  Must be kEnd.
3344 		 */
3345 		if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) {
3346 			archive_set_error(&a->archive, -1,
3347 			    "Malformed 7-Zip archive");
3348 			return (ARCHIVE_FATAL);
3349 		}
3350 
3351 		/* Check the Header CRC.*/
3352 		if (check_header_crc && zip->header_crc32 != next_header_crc) {
3353 #ifndef DONT_FAIL_ON_CRC_ERROR
3354 			archive_set_error(&a->archive, -1,
3355 			    "Malformed 7-Zip archive");
3356 			return (ARCHIVE_FATAL);
3357 #endif
3358 		}
3359 		break;
3360 	default:
3361 		archive_set_error(&a->archive, -1,
3362 		    "Unexpected Property ID = %X", p[0]);
3363 		return (ARCHIVE_FATAL);
3364 	}
3365 
3366 	/* Clean up variables be used for decoding the archive header */
3367 	zip->pack_stream_remaining = 0;
3368 	zip->pack_stream_index = 0;
3369 	zip->folder_outbytes_remaining = 0;
3370 	zip->uncompressed_buffer_bytes_remaining = 0;
3371 	zip->pack_stream_bytes_unconsumed = 0;
3372 	zip->header_is_being_read = 0;
3373 
3374 	return (ARCHIVE_OK);
3375 }
3376 
3377 static ssize_t
get_uncompressed_data(struct archive_read * a,const void ** buff,size_t size,size_t minimum)3378 get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
3379     size_t minimum)
3380 {
3381 	struct _7zip *zip = (struct _7zip *)a->format->data;
3382 	ssize_t bytes_avail;
3383 
3384 	if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
3385 		/* Copy mode. */
3386 
3387 		*buff = __archive_read_ahead(a, minimum, &bytes_avail);
3388 		if (*buff == NULL) {
3389 			archive_set_error(&a->archive,
3390 			    ARCHIVE_ERRNO_FILE_FORMAT,
3391 			    "Truncated 7-Zip file data");
3392 			return (ARCHIVE_FATAL);
3393 		}
3394 		if ((size_t)bytes_avail >
3395 		    zip->uncompressed_buffer_bytes_remaining)
3396 			bytes_avail = (ssize_t)
3397 			    zip->uncompressed_buffer_bytes_remaining;
3398 		if ((size_t)bytes_avail > size)
3399 			bytes_avail = (ssize_t)size;
3400 
3401 		zip->pack_stream_bytes_unconsumed = bytes_avail;
3402 	} else if (zip->uncompressed_buffer_pointer == NULL) {
3403 		/* Decompression has failed. */
3404 		archive_set_error(&(a->archive),
3405 		    ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
3406 		return (ARCHIVE_FATAL);
3407 	} else {
3408 		/* Packed mode. */
3409 		if (minimum > zip->uncompressed_buffer_bytes_remaining) {
3410 			/*
3411 			 * If remaining uncompressed data size is less than
3412 			 * the minimum size, fill the buffer up to the
3413 			 * minimum size.
3414 			 */
3415 			if (extract_pack_stream(a, minimum) < 0)
3416 				return (ARCHIVE_FATAL);
3417 		}
3418 		if (size > zip->uncompressed_buffer_bytes_remaining)
3419 			bytes_avail = (ssize_t)
3420 			    zip->uncompressed_buffer_bytes_remaining;
3421 		else
3422 			bytes_avail = (ssize_t)size;
3423 		*buff = zip->uncompressed_buffer_pointer;
3424 		zip->uncompressed_buffer_pointer += bytes_avail;
3425 	}
3426 	zip->uncompressed_buffer_bytes_remaining -= bytes_avail;
3427 	return (bytes_avail);
3428 }
3429 
3430 static ssize_t
extract_pack_stream(struct archive_read * a,size_t minimum)3431 extract_pack_stream(struct archive_read *a, size_t minimum)
3432 {
3433 	struct _7zip *zip = (struct _7zip *)a->format->data;
3434 	ssize_t bytes_avail;
3435 	int r;
3436 
3437 	if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
3438 		if (minimum == 0)
3439 			minimum = 1;
3440 		if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL
3441 		    || bytes_avail <= 0) {
3442 			archive_set_error(&a->archive,
3443 			    ARCHIVE_ERRNO_FILE_FORMAT,
3444 			    "Truncated 7-Zip file body");
3445 			return (ARCHIVE_FATAL);
3446 		}
3447 		if ((uint64_t)bytes_avail > zip->pack_stream_inbytes_remaining)
3448 			bytes_avail = (ssize_t)zip->pack_stream_inbytes_remaining;
3449 		zip->pack_stream_inbytes_remaining -= bytes_avail;
3450 		if ((uint64_t)bytes_avail > zip->folder_outbytes_remaining)
3451 			bytes_avail = (ssize_t)zip->folder_outbytes_remaining;
3452 		zip->folder_outbytes_remaining -= bytes_avail;
3453 		zip->uncompressed_buffer_bytes_remaining = bytes_avail;
3454 		return (ARCHIVE_OK);
3455 	}
3456 
3457 	/* If the buffer hasn't been allocated, allocate it now. */
3458 	if (zip->uncompressed_buffer == NULL) {
3459 		zip->uncompressed_buffer_size = UBUFF_SIZE;
3460 		if (zip->uncompressed_buffer_size < minimum) {
3461 			zip->uncompressed_buffer_size = minimum + 1023;
3462 			zip->uncompressed_buffer_size &= ~0x3ff;
3463 		}
3464 		zip->uncompressed_buffer =
3465 		    malloc(zip->uncompressed_buffer_size);
3466 		if (zip->uncompressed_buffer == NULL) {
3467 			archive_set_error(&a->archive, ENOMEM,
3468 			    "No memory for 7-Zip decompression");
3469 			return (ARCHIVE_FATAL);
3470 		}
3471 		zip->uncompressed_buffer_bytes_remaining = 0;
3472 	} else if (zip->uncompressed_buffer_size < minimum ||
3473 	    zip->uncompressed_buffer_bytes_remaining < minimum) {
3474 		/*
3475 		 * Make sure the uncompressed buffer can have bytes
3476 		 * at least `minimum' bytes.
3477 		 * NOTE: This case happen when reading the header.
3478 		 */
3479 		size_t used;
3480 		if (zip->uncompressed_buffer_pointer != 0)
3481 			used = zip->uncompressed_buffer_pointer -
3482 				zip->uncompressed_buffer;
3483 		else
3484 			used = 0;
3485 		if (zip->uncompressed_buffer_size < minimum) {
3486 			/*
3487 			 * Expand the uncompressed buffer up to
3488 			 * the minimum size.
3489 			 */
3490 			void *p;
3491 			size_t new_size;
3492 
3493 			new_size = minimum + 1023;
3494 			new_size &= ~0x3ff;
3495 			p = realloc(zip->uncompressed_buffer, new_size);
3496 			if (p == NULL) {
3497 				archive_set_error(&a->archive, ENOMEM,
3498 				    "No memory for 7-Zip decompression");
3499 				return (ARCHIVE_FATAL);
3500 			}
3501 			zip->uncompressed_buffer = (unsigned char *)p;
3502 			zip->uncompressed_buffer_size = new_size;
3503 		}
3504 		/*
3505 		 * Move unconsumed bytes to the head.
3506 		 */
3507 		if (used) {
3508 			memmove(zip->uncompressed_buffer,
3509 				zip->uncompressed_buffer + used,
3510 				zip->uncompressed_buffer_bytes_remaining);
3511 		}
3512 	} else
3513 		zip->uncompressed_buffer_bytes_remaining = 0;
3514 	zip->uncompressed_buffer_pointer = NULL;
3515 	for (;;) {
3516 		size_t bytes_in, bytes_out;
3517 		const void *buff_in;
3518 		unsigned char *buff_out;
3519 		int end_of_data;
3520 
3521 		/*
3522 		 * Note: '1' here is a performance optimization.
3523 		 * Recall that the decompression layer returns a count of
3524 		 * available bytes; asking for more than that forces the
3525 		 * decompressor to combine reads by copying data.
3526 		 */
3527 		buff_in = __archive_read_ahead(a, 1, &bytes_avail);
3528 		if (bytes_avail <= 0) {
3529 			archive_set_error(&a->archive,
3530 			    ARCHIVE_ERRNO_FILE_FORMAT,
3531 			    "Truncated 7-Zip file body");
3532 			return (ARCHIVE_FATAL);
3533 		}
3534 
3535 		buff_out = zip->uncompressed_buffer
3536 			+ zip->uncompressed_buffer_bytes_remaining;
3537 		bytes_out = zip->uncompressed_buffer_size
3538 			- zip->uncompressed_buffer_bytes_remaining;
3539 		bytes_in = bytes_avail;
3540 		if (bytes_in > zip->pack_stream_inbytes_remaining)
3541 			bytes_in = (size_t)zip->pack_stream_inbytes_remaining;
3542 		/* Drive decompression. */
3543 		r = decompress(a, zip, buff_out, &bytes_out,
3544 			buff_in, &bytes_in);
3545 		switch (r) {
3546 		case ARCHIVE_OK:
3547 			end_of_data = 0;
3548 			break;
3549 		case ARCHIVE_EOF:
3550 			end_of_data = 1;
3551 			break;
3552 		default:
3553 			return (ARCHIVE_FATAL);
3554 		}
3555 		zip->pack_stream_inbytes_remaining -= bytes_in;
3556 		if (bytes_out > zip->folder_outbytes_remaining)
3557 			bytes_out = (size_t)zip->folder_outbytes_remaining;
3558 		zip->folder_outbytes_remaining -= bytes_out;
3559 		zip->uncompressed_buffer_bytes_remaining += bytes_out;
3560 		zip->pack_stream_bytes_unconsumed = bytes_in;
3561 
3562 		/*
3563 		 * Continue decompression until uncompressed_buffer is full.
3564 		 */
3565 		if (zip->uncompressed_buffer_bytes_remaining ==
3566 		    zip->uncompressed_buffer_size)
3567 			break;
3568 		if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size &&
3569 		    zip->uncompressed_buffer_bytes_remaining + 5 >
3570 		    zip->uncompressed_buffer_size)
3571 			break;
3572 		if (zip->pack_stream_inbytes_remaining == 0 &&
3573 		    zip->folder_outbytes_remaining == 0)
3574 			break;
3575 		if (end_of_data || (bytes_in == 0 && bytes_out == 0)) {
3576 			archive_set_error(&(a->archive),
3577 			    ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
3578 			return (ARCHIVE_FATAL);
3579 		}
3580 		read_consume(a);
3581 	}
3582 	if (zip->uncompressed_buffer_bytes_remaining < minimum) {
3583 		archive_set_error(&(a->archive),
3584 		    ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
3585 		return (ARCHIVE_FATAL);
3586 	}
3587 	zip->uncompressed_buffer_pointer = zip->uncompressed_buffer;
3588 	return (ARCHIVE_OK);
3589 }
3590 
3591 static int
seek_pack(struct archive_read * a)3592 seek_pack(struct archive_read *a)
3593 {
3594 	struct _7zip *zip = (struct _7zip *)a->format->data;
3595 	int64_t pack_offset;
3596 
3597 	if (zip->pack_stream_remaining <= 0) {
3598 		archive_set_error(&(a->archive),
3599 		    ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
3600 		return (ARCHIVE_FATAL);
3601 	}
3602 	zip->pack_stream_inbytes_remaining =
3603 	    zip->si.pi.sizes[zip->pack_stream_index];
3604 	pack_offset = zip->si.pi.positions[zip->pack_stream_index];
3605 	if (zip->stream_offset != pack_offset) {
3606 		if (0 > __archive_read_seek(a, pack_offset + zip->seek_base,
3607 		    SEEK_SET))
3608 			return (ARCHIVE_FATAL);
3609 		zip->stream_offset = pack_offset;
3610 	}
3611 	zip->pack_stream_index++;
3612 	zip->pack_stream_remaining--;
3613 	return (ARCHIVE_OK);
3614 }
3615 
3616 static ssize_t
read_stream(struct archive_read * a,const void ** buff,size_t size,size_t minimum)3617 read_stream(struct archive_read *a, const void **buff, size_t size,
3618     size_t minimum)
3619 {
3620 	struct _7zip *zip = (struct _7zip *)a->format->data;
3621 	uint64_t skip_bytes = 0;
3622 	ssize_t r;
3623 
3624 	if (zip->uncompressed_buffer_bytes_remaining == 0) {
3625 		if (zip->pack_stream_inbytes_remaining > 0) {
3626 			r = extract_pack_stream(a, 0);
3627 			if (r < 0)
3628 				return (r);
3629 			return (get_uncompressed_data(a, buff, size, minimum));
3630 		} else if (zip->folder_outbytes_remaining > 0) {
3631 			/* Extract a remaining pack stream. */
3632 			r = extract_pack_stream(a, 0);
3633 			if (r < 0)
3634 				return (r);
3635 			return (get_uncompressed_data(a, buff, size, minimum));
3636 		}
3637 	} else
3638 		return (get_uncompressed_data(a, buff, size, minimum));
3639 
3640 	/*
3641 	 * Current pack stream has been consumed.
3642 	 */
3643 	if (zip->pack_stream_remaining == 0) {
3644 		if (zip->header_is_being_read) {
3645 			/* Invalid sequence. This might happen when
3646 			 * reading a malformed archive. */
3647 			archive_set_error(&(a->archive),
3648 			    ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive");
3649 			return (ARCHIVE_FATAL);
3650 		}
3651 
3652 		/*
3653 		 * All current folder's pack streams have been
3654 		 * consumed. Switch to next folder.
3655 		 */
3656 		if (zip->folder_index == 0 &&
3657 		    (zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
3658 		     || zip->folder_index != zip->entry->folderIndex)) {
3659 			zip->folder_index = zip->entry->folderIndex;
3660 			skip_bytes =
3661 			    zip->si.ci.folders[zip->folder_index].skipped_bytes;
3662 		}
3663 
3664 		if (zip->folder_index >= zip->si.ci.numFolders) {
3665 			/*
3666 			 * We have consumed all folders and its pack streams.
3667 			 */
3668 			*buff = NULL;
3669 			return (0);
3670 		}
3671 		r = setup_decode_folder(a,
3672 			&(zip->si.ci.folders[zip->folder_index]), 0);
3673 		if (r != ARCHIVE_OK)
3674 			return (ARCHIVE_FATAL);
3675 
3676 		zip->folder_index++;
3677 	}
3678 
3679 	/*
3680 	 * Switch to next pack stream.
3681 	 */
3682 	r = seek_pack(a);
3683 	if (r < 0)
3684 		return (r);
3685 
3686 	/* Extract a new pack stream. */
3687 	r = extract_pack_stream(a, 0);
3688 	if (r < 0)
3689 		return (r);
3690 
3691 	/*
3692 	 * Skip the bytes we already has skipped in skip_stream().
3693 	 */
3694 	while (1) {
3695 		ssize_t skipped;
3696 
3697 		if (zip->uncompressed_buffer_bytes_remaining == 0) {
3698 			if (zip->pack_stream_inbytes_remaining > 0) {
3699 				r = extract_pack_stream(a, 0);
3700 				if (r < 0)
3701 					return (r);
3702 			} else if (zip->folder_outbytes_remaining > 0) {
3703 				/* Extract a remaining pack stream. */
3704 				r = extract_pack_stream(a, 0);
3705 				if (r < 0)
3706 					return (r);
3707 			} else {
3708 				archive_set_error(&a->archive,
3709 				    ARCHIVE_ERRNO_FILE_FORMAT,
3710 				    "Truncated 7-Zip file body");
3711 				return (ARCHIVE_FATAL);
3712 			}
3713 		}
3714 
3715 		if (!skip_bytes)
3716 			break;
3717 
3718 		skipped = get_uncompressed_data(
3719 			a, buff, (size_t)skip_bytes, 0);
3720 		if (skipped < 0)
3721 			return (skipped);
3722 		skip_bytes -= skipped;
3723 		if (zip->pack_stream_bytes_unconsumed)
3724 			read_consume(a);
3725 	}
3726 
3727 	return (get_uncompressed_data(a, buff, size, minimum));
3728 }
3729 
3730 static int
setup_decode_folder(struct archive_read * a,struct _7z_folder * folder,int header)3731 setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
3732     int header)
3733 {
3734 	struct _7zip *zip = (struct _7zip *)a->format->data;
3735 	const struct _7z_coder *coder1, *coder2;
3736 	const char *cname = (header)?"archive header":"file content";
3737 	unsigned i;
3738 	int r, found_bcj2 = 0;
3739 
3740 	/*
3741 	 * Release the memory which the previous folder used for BCJ2.
3742 	 */
3743 	for (i = 0; i < 3; i++) {
3744 		free(zip->sub_stream_buff[i]);
3745 		zip->sub_stream_buff[i] = NULL;
3746 	}
3747 
3748 	/*
3749 	 * Initialize a stream reader.
3750 	 */
3751 	zip->pack_stream_remaining = (unsigned)folder->numPackedStreams;
3752 	zip->pack_stream_index = (unsigned)folder->packIndex;
3753 	zip->folder_outbytes_remaining = folder_uncompressed_size(folder);
3754 	zip->uncompressed_buffer_bytes_remaining = 0;
3755 
3756 	/*
3757 	 * Check coder types.
3758 	 */
3759 	for (i = 0; i < folder->numCoders; i++) {
3760 		switch(folder->coders[i].codec) {
3761 			case _7Z_CRYPTO_MAIN_ZIP:
3762 			case _7Z_CRYPTO_RAR_29:
3763 			case _7Z_CRYPTO_AES_256_SHA_256: {
3764 				/* For entry that is associated with this folder, mark
3765 				   it as encrypted (data+metadata). */
3766 				zip->has_encrypted_entries = 1;
3767 				if (a->entry) {
3768 					archive_entry_set_is_data_encrypted(a->entry, 1);
3769 					archive_entry_set_is_metadata_encrypted(a->entry, 1);
3770 				}
3771 				archive_set_error(&(a->archive),
3772 					ARCHIVE_ERRNO_MISC,
3773 					"The %s is encrypted, "
3774 					"but currently not supported", cname);
3775 				return (ARCHIVE_FATAL);
3776 			}
3777 			case _7Z_X86_BCJ2: {
3778 				found_bcj2++;
3779 				break;
3780 			}
3781 		}
3782 	}
3783 	/* Now that we've checked for encryption, if there were still no
3784 	 * encrypted entries found we can say for sure that there are none.
3785 	 */
3786 	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
3787 		zip->has_encrypted_entries = 0;
3788 	}
3789 
3790 	if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
3791 		archive_set_error(&(a->archive),
3792 		    ARCHIVE_ERRNO_MISC,
3793 		    "The %s is encoded with many filters, "
3794 		    "but currently not supported", cname);
3795 		return (ARCHIVE_FATAL);
3796 	}
3797 	coder1 = &(folder->coders[0]);
3798 	if (folder->numCoders == 2)
3799 		coder2 = &(folder->coders[1]);
3800 	else
3801 		coder2 = NULL;
3802 
3803 	if (found_bcj2) {
3804 		/*
3805 		 * Preparation to decode BCJ2.
3806 		 * Decoding BCJ2 requires four sources. Those are at least,
3807 		 * as far as I know, two types of the storage form.
3808 		 */
3809 		const struct _7z_coder *fc = folder->coders;
3810 		static const struct _7z_coder coder_copy = {0, 1, 1, 0, NULL};
3811 		const struct _7z_coder *scoder[3] =
3812 			{&coder_copy, &coder_copy, &coder_copy};
3813 		const void *buff;
3814 		ssize_t bytes;
3815 		unsigned char *b[3] = {NULL, NULL, NULL};
3816 		uint64_t sunpack[3] ={-1, -1, -1};
3817 		size_t s[3] = {0, 0, 0};
3818 		int idx[3] = {0, 1, 2};
3819 
3820 		if (folder->numCoders == 4 && fc[3].codec == _7Z_X86_BCJ2 &&
3821 		    folder->numInStreams == 7 && folder->numOutStreams == 4 &&
3822 		    zip->pack_stream_remaining == 4) {
3823 			/* Source type 1 made by 7zr or 7z with -m options. */
3824 			if (folder->bindPairs[0].inIndex == 5) {
3825 				/* The form made by 7zr */
3826 				idx[0] = 1; idx[1] = 2; idx[2] = 0;
3827 				scoder[1] = &(fc[1]);
3828 				scoder[2] = &(fc[0]);
3829 				sunpack[1] = folder->unPackSize[1];
3830 				sunpack[2] = folder->unPackSize[0];
3831 				coder1 = &(fc[2]);
3832 			} else {
3833 				/*
3834 				 * NOTE: Some patterns do not work.
3835 				 * work:
3836 				 *  7z a -m0=BCJ2 -m1=COPY -m2=COPY
3837 				 *       -m3=(any)
3838 				 *  7z a -m0=BCJ2 -m1=COPY -m2=(any)
3839 				 *       -m3=COPY
3840 				 *  7z a -m0=BCJ2 -m1=(any) -m2=COPY
3841 				 *       -m3=COPY
3842 				 * not work:
3843 				 *  other patterns.
3844 				 *
3845 				 * We have to handle this like `pipe' or
3846 				 * our libarchive7s filter frame work,
3847 				 * decoding the BCJ2 main stream sequentially,
3848 				 * m3 -> m2 -> m1 -> BCJ2.
3849 				 *
3850 				 */
3851 				if (fc[0].codec == _7Z_COPY &&
3852 				    fc[1].codec == _7Z_COPY)
3853 					coder1 = &(folder->coders[2]);
3854 				else if (fc[0].codec == _7Z_COPY &&
3855 				    fc[2].codec == _7Z_COPY)
3856 					coder1 = &(folder->coders[1]);
3857 				else if (fc[1].codec == _7Z_COPY &&
3858 				    fc[2].codec == _7Z_COPY)
3859 					coder1 = &(folder->coders[0]);
3860 				else {
3861 					archive_set_error(&(a->archive),
3862 					    ARCHIVE_ERRNO_MISC,
3863 					    "Unsupported form of "
3864 					    "BCJ2 streams");
3865 					return (ARCHIVE_FATAL);
3866 				}
3867 			}
3868 			coder2 = &(fc[3]);
3869 			zip->main_stream_bytes_remaining =
3870 				(size_t)folder->unPackSize[2];
3871 		} else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 &&
3872 		    zip->pack_stream_remaining == 4 &&
3873 		    folder->numInStreams == 5 && folder->numOutStreams == 2) {
3874 			/* Source type 0 made by 7z */
3875 			zip->main_stream_bytes_remaining =
3876 				(size_t)folder->unPackSize[0];
3877 		} else {
3878 			/* We got an unexpected form. */
3879 			archive_set_error(&(a->archive),
3880 			    ARCHIVE_ERRNO_MISC,
3881 			    "Unsupported form of BCJ2 streams");
3882 			return (ARCHIVE_FATAL);
3883 		}
3884 
3885 		/* Skip the main stream at this time. */
3886 		if ((r = seek_pack(a)) < 0)
3887 			return (r);
3888 		zip->pack_stream_bytes_unconsumed =
3889 		    (size_t)zip->pack_stream_inbytes_remaining;
3890 		read_consume(a);
3891 
3892 		/* Read following three sub streams. */
3893 		for (i = 0; i < 3; i++) {
3894 			const struct _7z_coder *coder = scoder[i];
3895 
3896 			if ((r = seek_pack(a)) < 0) {
3897 				free(b[0]); free(b[1]); free(b[2]);
3898 				return (r);
3899 			}
3900 
3901 			if (sunpack[i] == (uint64_t)-1)
3902 				zip->folder_outbytes_remaining =
3903 				    zip->pack_stream_inbytes_remaining;
3904 			else
3905 				zip->folder_outbytes_remaining = sunpack[i];
3906 
3907 			r = init_decompression(a, zip, coder, NULL);
3908 			if (r != ARCHIVE_OK) {
3909 				free(b[0]); free(b[1]); free(b[2]);
3910 				return (ARCHIVE_FATAL);
3911 			}
3912 
3913 			/* Allocate memory for the decoded data of a sub
3914 			 * stream. */
3915 			b[i] = malloc((size_t)zip->folder_outbytes_remaining);
3916 			if (b[i] == NULL) {
3917 				free(b[0]); free(b[1]); free(b[2]);
3918 				archive_set_error(&a->archive, ENOMEM,
3919 				    "No memory for 7-Zip decompression");
3920 				return (ARCHIVE_FATAL);
3921 			}
3922 
3923 			/* Extract a sub stream. */
3924 			while (zip->pack_stream_inbytes_remaining > 0) {
3925 				r = (int)extract_pack_stream(a, 0);
3926 				if (r < 0) {
3927 					free(b[0]); free(b[1]); free(b[2]);
3928 					return (r);
3929 				}
3930 				bytes = get_uncompressed_data(a, &buff,
3931 				    zip->uncompressed_buffer_bytes_remaining,
3932 				    0);
3933 				if (bytes < 0) {
3934 					free(b[0]); free(b[1]); free(b[2]);
3935 					return ((int)bytes);
3936 				}
3937 				memcpy(b[i]+s[i], buff, bytes);
3938 				s[i] += bytes;
3939 				if (zip->pack_stream_bytes_unconsumed)
3940 					read_consume(a);
3941 			}
3942 		}
3943 
3944 		/* Set the sub streams to the right place. */
3945 		for (i = 0; i < 3; i++) {
3946 			zip->sub_stream_buff[i] = b[idx[i]];
3947 			zip->sub_stream_size[i] = s[idx[i]];
3948 			zip->sub_stream_bytes_remaining[i] = s[idx[i]];
3949 		}
3950 
3951 		/* Allocate memory used for decoded main stream bytes. */
3952 		if (zip->tmp_stream_buff == NULL) {
3953 			zip->tmp_stream_buff_size = 32 * 1024;
3954 			zip->tmp_stream_buff =
3955 			    malloc(zip->tmp_stream_buff_size);
3956 			if (zip->tmp_stream_buff == NULL) {
3957 				archive_set_error(&a->archive, ENOMEM,
3958 				    "No memory for 7-Zip decompression");
3959 				return (ARCHIVE_FATAL);
3960 			}
3961 		}
3962 		zip->tmp_stream_bytes_avail = 0;
3963 		zip->tmp_stream_bytes_remaining = 0;
3964 		zip->odd_bcj_size = 0;
3965 		zip->bcj2_outPos = 0;
3966 
3967 		/*
3968 		 * Reset a stream reader in order to read the main stream
3969 		 * of BCJ2.
3970 		 */
3971 		zip->pack_stream_remaining = 1;
3972 		zip->pack_stream_index = (unsigned)folder->packIndex;
3973 		zip->folder_outbytes_remaining =
3974 		    folder_uncompressed_size(folder);
3975 		zip->uncompressed_buffer_bytes_remaining = 0;
3976 	}
3977 
3978 	/*
3979 	 * Initialize the decompressor for the new folder's pack streams.
3980 	 */
3981 	r = init_decompression(a, zip, coder1, coder2);
3982 	if (r != ARCHIVE_OK)
3983 		return (ARCHIVE_FATAL);
3984 	return (ARCHIVE_OK);
3985 }
3986 
3987 static int64_t
skip_stream(struct archive_read * a,size_t skip_bytes)3988 skip_stream(struct archive_read *a, size_t skip_bytes)
3989 {
3990 	struct _7zip *zip = (struct _7zip *)a->format->data;
3991 	const void *p;
3992 	int64_t skipped_bytes;
3993 	size_t bytes = skip_bytes;
3994 
3995 	if (zip->folder_index == 0) {
3996 		/*
3997 		 * Optimization for a list mode.
3998 		 * Avoid unnecessary decoding operations.
3999 		 */
4000 		zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
4001 		    += skip_bytes;
4002 		return (skip_bytes);
4003 	}
4004 
4005 	while (bytes) {
4006 		skipped_bytes = read_stream(a, &p, bytes, 0);
4007 		if (skipped_bytes < 0)
4008 			return (skipped_bytes);
4009 		if (skipped_bytes == 0) {
4010 			archive_set_error(&a->archive,
4011 			    ARCHIVE_ERRNO_FILE_FORMAT,
4012 			    "Truncated 7-Zip file body");
4013 			return (ARCHIVE_FATAL);
4014 		}
4015 		bytes -= (size_t)skipped_bytes;
4016 		if (zip->pack_stream_bytes_unconsumed)
4017 			read_consume(a);
4018 	}
4019 	return (skip_bytes);
4020 }
4021 
4022 /*
4023  * Brought from LZMA SDK.
4024  *
4025  * Bra86.c -- Converter for x86 code (BCJ)
4026  * 2008-10-04 : Igor Pavlov : Public domain
4027  *
4028  */
4029 
4030 #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
4031 
4032 static void
x86_Init(struct _7zip * zip)4033 x86_Init(struct _7zip *zip)
4034 {
4035 	zip->bcj_state = 0;
4036 	zip->bcj_prevPosT = (size_t)0 - 1;
4037 	zip->bcj_prevMask = 0;
4038 	zip->bcj_ip = 5;
4039 }
4040 
4041 static size_t
x86_Convert(struct _7zip * zip,uint8_t * data,size_t size)4042 x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
4043 {
4044 	static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
4045 	static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
4046 	size_t bufferPos, prevPosT;
4047 	uint32_t ip, prevMask;
4048 
4049 	if (size < 5)
4050 		return 0;
4051 
4052 	bufferPos = 0;
4053 	prevPosT = zip->bcj_prevPosT;
4054 	prevMask = zip->bcj_prevMask;
4055 	ip = zip->bcj_ip;
4056 
4057 	for (;;) {
4058 		uint8_t *p = data + bufferPos;
4059 		uint8_t *limit = data + size - 4;
4060 
4061 		for (; p < limit; p++)
4062 			if ((*p & 0xFE) == 0xE8)
4063 				break;
4064 		bufferPos = (size_t)(p - data);
4065 		if (p >= limit)
4066 			break;
4067 		prevPosT = bufferPos - prevPosT;
4068 		if (prevPosT > 3)
4069 			prevMask = 0;
4070 		else {
4071 			prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
4072 			if (prevMask != 0) {
4073 				unsigned char b =
4074 					p[4 - kMaskToBitNumber[prevMask]];
4075 				if (!kMaskToAllowedStatus[prevMask] ||
4076 				    Test86MSByte(b)) {
4077 					prevPosT = bufferPos;
4078 					prevMask = ((prevMask << 1) & 0x7) | 1;
4079 					bufferPos++;
4080 					continue;
4081 				}
4082 			}
4083 		}
4084 		prevPosT = bufferPos;
4085 
4086 		if (Test86MSByte(p[4])) {
4087 			uint32_t src = ((uint32_t)p[4] << 24) |
4088 				((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) |
4089 				((uint32_t)p[1]);
4090 			uint32_t dest;
4091 			for (;;) {
4092 				uint8_t b;
4093 				int b_index;
4094 
4095 				dest = src - (ip + (uint32_t)bufferPos);
4096 				if (prevMask == 0)
4097 					break;
4098 				b_index = kMaskToBitNumber[prevMask] * 8;
4099 				b = (uint8_t)(dest >> (24 - b_index));
4100 				if (!Test86MSByte(b))
4101 					break;
4102 				src = dest ^ ((1 << (32 - b_index)) - 1);
4103 			}
4104 			p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
4105 			p[3] = (uint8_t)(dest >> 16);
4106 			p[2] = (uint8_t)(dest >> 8);
4107 			p[1] = (uint8_t)dest;
4108 			bufferPos += 5;
4109 		} else {
4110 			prevMask = ((prevMask << 1) & 0x7) | 1;
4111 			bufferPos++;
4112 		}
4113 	}
4114 	zip->bcj_prevPosT = prevPosT;
4115 	zip->bcj_prevMask = prevMask;
4116 	zip->bcj_ip += (uint32_t)bufferPos;
4117 	return (bufferPos);
4118 }
4119 
4120 static void
arm_Init(struct _7zip * zip)4121 arm_Init(struct _7zip *zip)
4122 {
4123 	zip->bcj_ip = 8;
4124 }
4125 
4126 static size_t
arm_Convert(struct _7zip * zip,uint8_t * buf,size_t size)4127 arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
4128 {
4129 	// This function was adapted from
4130 	// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
4131 	// in https://git.tukaani.org/xz-embedded.git
4132 
4133 	/*
4134 	 * Branch/Call/Jump (BCJ) filter decoders
4135 	 *
4136 	 * Authors: Lasse Collin <lasse.collin@tukaani.org>
4137 	 *          Igor Pavlov <https://7-zip.org/>
4138 	 *
4139 	 * This file has been put into the public domain.
4140 	 * You can do whatever you want with this file.
4141 	 */
4142 
4143 	size_t i;
4144 	uint32_t addr;
4145 
4146 	for (i = 0; i + 4 <= size; i += 4) {
4147 		if (buf[i + 3] == 0xEB) {
4148 			// Calculate the transformed addr.
4149 			addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
4150 				| ((uint32_t)buf[i + 2] << 16);
4151 			addr <<= 2;
4152 			addr -= zip->bcj_ip + (uint32_t)i;
4153 			addr >>= 2;
4154 
4155 			// Store the transformed addr in buf.
4156 			buf[i] = (uint8_t)addr;
4157 			buf[i + 1] = (uint8_t)(addr >> 8);
4158 			buf[i + 2] = (uint8_t)(addr >> 16);
4159 		}
4160 	}
4161 
4162 	zip->bcj_ip += (uint32_t)i;
4163 
4164 	return i;
4165 }
4166 
4167 static size_t
arm64_Convert(struct _7zip * zip,uint8_t * buf,size_t size)4168 arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
4169 {
4170 	// This function was adapted from
4171 	// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
4172 	// in https://git.tukaani.org/xz-embedded.git
4173 
4174 	/*
4175 	 * Branch/Call/Jump (BCJ) filter decoders
4176 	 *
4177 	 * Authors: Lasse Collin <lasse.collin@tukaani.org>
4178 	 *          Igor Pavlov <https://7-zip.org/>
4179 	 *
4180 	 * This file has been put into the public domain.
4181 	 * You can do whatever you want with this file.
4182 	 */
4183 
4184 	size_t i;
4185 	uint32_t instr;
4186 	uint32_t addr;
4187 
4188 	for (i = 0; i + 4 <= size; i += 4) {
4189 		instr = (uint32_t)buf[i]
4190 			| ((uint32_t)buf[i+1] << 8)
4191 			| ((uint32_t)buf[i+2] << 16)
4192 			| ((uint32_t)buf[i+3] << 24);
4193 
4194 		if ((instr >> 26) == 0x25) {
4195 			/* BL instruction */
4196 			addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
4197 			instr = 0x94000000 | (addr & 0x03FFFFFF);
4198 
4199 			buf[i]   = (uint8_t)instr;
4200 			buf[i+1] = (uint8_t)(instr >> 8);
4201 			buf[i+2] = (uint8_t)(instr >> 16);
4202 			buf[i+3] = (uint8_t)(instr >> 24);
4203 		} else if ((instr & 0x9F000000) == 0x90000000) {
4204 			/* ADRP instruction */
4205 			addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
4206 
4207 			/* Only convert values in the range +/-512 MiB. */
4208 			if ((addr + 0x020000) & 0x1C0000)
4209 				continue;
4210 
4211 			addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
4212 
4213 			instr &= 0x9000001F;
4214 			instr |= (addr & 3) << 29;
4215 			instr |= (addr & 0x03FFFC) << 3;
4216 			instr |= (0U - (addr & 0x020000)) & 0xE00000;
4217 
4218 			buf[i]   = (uint8_t)instr;
4219 			buf[i+1] = (uint8_t)(instr >> 8);
4220 			buf[i+2] = (uint8_t)(instr >> 16);
4221 			buf[i+3] = (uint8_t)(instr >> 24);
4222 		}
4223 	}
4224 
4225 	zip->bcj_ip += (uint32_t)i;
4226 
4227 	return i;
4228 }
4229 
4230 static size_t
sparc_Convert(struct _7zip * zip,uint8_t * buf,size_t size)4231 sparc_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
4232 {
4233 	// This function was adapted from
4234 	// static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
4235 	// in https://git.tukaani.org/xz-embedded.git
4236 
4237 	/*
4238 	 * Branch/Call/Jump (BCJ) filter decoders
4239 	 *
4240 	 * Authors: Lasse Collin <lasse.collin@tukaani.org>
4241 	 *          Igor Pavlov <https://7-zip.org/>
4242 	 *
4243 	 * Copyright (C) The XZ Embedded authors and contributors
4244 	 *
4245 	 * Permission to use, copy, modify, and/or distribute this
4246 	 * software for any purpose with or without fee is hereby granted.
4247 	 *
4248 	 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
4249 	 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
4250 	 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
4251 	 * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
4252 	 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4253 	 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
4254 	 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
4255 	 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4256 	 */
4257 
4258 	size_t i;
4259 	uint32_t instr;
4260 
4261 	size &= ~(size_t)3;
4262 
4263 	for (i = 0; i < size; i += 4) {
4264 		instr = (uint32_t)(buf[i] << 24)
4265 			| ((uint32_t)buf[i+1] << 16)
4266 			| ((uint32_t)buf[i+2] << 8)
4267 			| (uint32_t)buf[i+3];
4268 
4269 		if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
4270 			instr <<= 2;
4271 			instr -= zip->bcj_ip + (uint32_t)i;
4272 			instr >>= 2;
4273 			instr = ((uint32_t)0x40000000 - (instr & 0x400000))
4274 			        | 0x40000000 | (instr & 0x3FFFFF);
4275 
4276 			buf[i] = (uint8_t)(instr >> 24);
4277 			buf[i+1] = (uint8_t)(instr >> 16);
4278 			buf[i+2] = (uint8_t)(instr >> 8);
4279 			buf[i+3] = (uint8_t)instr;
4280 		}
4281 	}
4282 
4283 	zip->bcj_ip += (uint32_t)i;
4284 
4285 	return i;
4286 }
4287 
4288 static size_t
powerpc_Convert(struct _7zip * zip,uint8_t * buf,size_t size)4289 powerpc_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
4290 {
4291 	// This function was adapted from
4292 	// static size_t powerpc_code(void *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size)
4293 	// in https://git.tukaani.org/xz.git
4294 
4295 	/*
4296 	 * Filter for PowerPC (big endian) binaries
4297 	 *
4298 	 * Authors: Igor Pavlov
4299 	 *          Lasse Collin
4300 	 *
4301 	 * Copyright (C) The XZ Utils authors and contributors
4302 	 *
4303 	 * Permission to use, copy, modify, and/or distribute this
4304 	 * software for any purpose with or without fee is hereby granted.
4305 	 *
4306 	 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
4307 	 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
4308 	 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
4309 	 * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
4310 	 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4311 	 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
4312 	 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
4313 	 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4314 	 */
4315 
4316 	size &= ~(size_t)3;
4317 
4318 	size_t i;
4319 	for (i = 0; i < size; i += 4) {
4320 		// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
4321 		if ((buf[i] >> 2) == 0x12
4322 			&& ((buf[i + 3] & 3) == 1)) {
4323 
4324 			const uint32_t src
4325 				= (((uint32_t)(buf[i + 0]) & 3) << 24)
4326 				| ((uint32_t)(buf[i + 1]) << 16)
4327 				| ((uint32_t)(buf[i + 2]) << 8)
4328 				| ((uint32_t)(buf[i + 3]) & ~UINT32_C(3));
4329 
4330 			uint32_t dest = src - (zip->bcj_ip + (uint32_t)(i));
4331 
4332 			buf[i + 0] = 0x48 | ((dest >> 24) &  0x03);
4333 			buf[i + 1] = (dest >> 16);
4334 			buf[i + 2] = (dest >> 8);
4335 			buf[i + 3] &= 0x03;
4336 			buf[i + 3] |= dest;
4337 		}
4338 	}
4339 
4340 	zip->bcj_ip += (uint32_t)i;
4341 
4342 	return i;
4343 }
4344 
4345 /*
4346  * Brought from LZMA SDK.
4347  *
4348  * Bcj2.c -- Converter for x86 code (BCJ2)
4349  * 2008-10-04 : Igor Pavlov : Public domain
4350  *
4351  */
4352 
4353 #define SZ_ERROR_DATA	 ARCHIVE_FAILED
4354 
4355 #define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
4356 #define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
4357 
4358 #define kNumTopBits 24
4359 #define kTopValue ((uint32_t)1 << kNumTopBits)
4360 
4361 #define kNumBitModelTotalBits 11
4362 #define kBitModelTotal (1 << kNumBitModelTotalBits)
4363 #define kNumMoveBits 5
4364 
4365 #define RC_READ_BYTE (*buffer++)
4366 #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
4367 #define RC_INIT2 do {							\
4368 	zip->bcj2_code = 0;						\
4369 	zip->bcj2_range = 0xFFFFFFFF;					\
4370 	{								\
4371 		int ii;							\
4372 		for (ii = 0; ii < 5; ii++) {				\
4373 			RC_TEST;					\
4374 			zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; \
4375 		}							\
4376 	}								\
4377 } while (0)
4378 
4379 #define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }
4380 
4381 #define IF_BIT_0(p) ttt = *(p); bound = (zip->bcj2_range >> kNumBitModelTotalBits) * ttt; if (zip->bcj2_code < bound)
4382 #define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
4383 #define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
4384 
4385 static ssize_t
Bcj2_Decode(struct _7zip * zip,uint8_t * outBuf,size_t outSize)4386 Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
4387 {
4388 	size_t inPos = 0, outPos = 0;
4389 	const uint8_t *buf0, *buf1, *buf2, *buf3;
4390 	size_t size0, size1, size2, size3;
4391 	const uint8_t *buffer, *bufferLim;
4392 	unsigned int i, j;
4393 
4394 	size0 = zip->tmp_stream_bytes_remaining;
4395 	buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0;
4396 	size1 = zip->sub_stream_bytes_remaining[0];
4397 	buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1;
4398 	size2 = zip->sub_stream_bytes_remaining[1];
4399 	buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2;
4400 	size3 = zip->sub_stream_bytes_remaining[2];
4401 	buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3;
4402 
4403 	buffer = buf3;
4404 	bufferLim = buffer + size3;
4405 
4406 	if (zip->bcj_state == 0) {
4407 		/*
4408 		 * Initialize.
4409 		 */
4410 		zip->bcj2_prevByte = 0;
4411 		for (i = 0;
4412 		    i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++)
4413 			zip->bcj2_p[i] = kBitModelTotal >> 1;
4414 		RC_INIT2;
4415 		zip->bcj_state = 1;
4416 	}
4417 
4418 	/*
4419 	 * Gather the odd bytes of a previous call.
4420 	 */
4421 	for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) {
4422 		outBuf[outPos++] = zip->odd_bcj[i];
4423 		zip->odd_bcj_size--;
4424 	}
4425 
4426 	if (outSize == 0) {
4427 		zip->bcj2_outPos += outPos;
4428 		return (outPos);
4429 	}
4430 
4431 	for (;;) {
4432 		uint8_t b;
4433 		CProb *prob;
4434 		uint32_t bound;
4435 		uint32_t ttt;
4436 
4437 		size_t limit = size0 - inPos;
4438 		if (outSize - outPos < limit)
4439 			limit = outSize - outPos;
4440 
4441 		if (zip->bcj_state == 1) {
4442 			while (limit != 0) {
4443 				uint8_t bb = buf0[inPos];
4444 				outBuf[outPos++] = bb;
4445 				if (IsJ(zip->bcj2_prevByte, bb)) {
4446 					zip->bcj_state = 2;
4447 					break;
4448 				}
4449 				inPos++;
4450 				zip->bcj2_prevByte = bb;
4451 				limit--;
4452 			}
4453 		}
4454 
4455 		if (limit == 0 || outPos == outSize)
4456 			break;
4457 		zip->bcj_state = 1;
4458 
4459 		b = buf0[inPos++];
4460 
4461 		if (b == 0xE8)
4462 			prob = zip->bcj2_p + zip->bcj2_prevByte;
4463 		else if (b == 0xE9)
4464 			prob = zip->bcj2_p + 256;
4465 		else
4466 			prob = zip->bcj2_p + 257;
4467 
4468 		IF_BIT_0(prob) {
4469 			UPDATE_0(prob)
4470 			zip->bcj2_prevByte = b;
4471 		} else {
4472 			uint32_t dest;
4473 			const uint8_t *v;
4474 			uint8_t out[4];
4475 
4476 			UPDATE_1(prob)
4477 			if (b == 0xE8) {
4478 				v = buf1;
4479 				if (size1 < 4)
4480 					return SZ_ERROR_DATA;
4481 				buf1 += 4;
4482 				size1 -= 4;
4483 			} else {
4484 				v = buf2;
4485 				if (size2 < 4)
4486 					return SZ_ERROR_DATA;
4487 				buf2 += 4;
4488 				size2 -= 4;
4489 			}
4490 			dest = (((uint32_t)v[0] << 24) |
4491 			    ((uint32_t)v[1] << 16) |
4492 			    ((uint32_t)v[2] << 8) |
4493 			    ((uint32_t)v[3])) -
4494 			    ((uint32_t)zip->bcj2_outPos + (uint32_t)outPos + 4);
4495 			out[0] = (uint8_t)dest;
4496 			out[1] = (uint8_t)(dest >> 8);
4497 			out[2] = (uint8_t)(dest >> 16);
4498 			out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24);
4499 
4500 			for (i = 0; i < 4 && outPos < outSize; i++)
4501 				outBuf[outPos++] = out[i];
4502 			if (i < 4) {
4503 				/*
4504 				 * Save odd bytes which we could not add into
4505 				 * the output buffer because of out of space.
4506 				 */
4507 				zip->odd_bcj_size = 4 -i;
4508 				for (; i < 4; i++) {
4509 					j = i - 4 + (unsigned)zip->odd_bcj_size;
4510 					zip->odd_bcj[j] = out[i];
4511 				}
4512 				break;
4513 			}
4514 		}
4515 	}
4516 	zip->tmp_stream_bytes_remaining -= inPos;
4517 	zip->sub_stream_bytes_remaining[0] = size1;
4518 	zip->sub_stream_bytes_remaining[1] = size2;
4519 	zip->sub_stream_bytes_remaining[2] = bufferLim - buffer;
4520 	zip->bcj2_outPos += outPos;
4521 
4522 	return ((ssize_t)outPos);
4523 }
4524