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