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