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