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