1 /*-
2 * Copyright (c) 2011-2012 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 __FBSDID("$FreeBSD$");
28
29 #ifdef HAVE_ERRNO_H
30 #include <errno.h>
31 #endif
32 #include <stdlib.h>
33 #ifdef HAVE_BZLIB_H
34 #include <bzlib.h>
35 #endif
36 #if HAVE_LZMA_H
37 #include <lzma.h>
38 #endif
39 #ifdef HAVE_ZLIB_H
40 #include <zlib.h>
41 #endif
42
43 #include "archive.h"
44 #ifndef HAVE_ZLIB_H
45 #include "archive_crc32.h"
46 #endif
47 #include "archive_endian.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_rb.h"
53 #include "archive_string.h"
54 #include "archive_write_private.h"
55
56 /*
57 * Codec ID
58 */
59 #define _7Z_COPY 0
60 #define _7Z_LZMA1 0x030101
61 #define _7Z_LZMA2 0x21
62 #define _7Z_DEFLATE 0x040108
63 #define _7Z_BZIP2 0x040202
64 #define _7Z_PPMD 0x030401
65
66 /*
67 * 7-Zip header property IDs.
68 */
69 #define kEnd 0x00
70 #define kHeader 0x01
71 #define kArchiveProperties 0x02
72 #define kAdditionalStreamsInfo 0x03
73 #define kMainStreamsInfo 0x04
74 #define kFilesInfo 0x05
75 #define kPackInfo 0x06
76 #define kUnPackInfo 0x07
77 #define kSubStreamsInfo 0x08
78 #define kSize 0x09
79 #define kCRC 0x0A
80 #define kFolder 0x0B
81 #define kCodersUnPackSize 0x0C
82 #define kNumUnPackStream 0x0D
83 #define kEmptyStream 0x0E
84 #define kEmptyFile 0x0F
85 #define kAnti 0x10
86 #define kName 0x11
87 #define kCTime 0x12
88 #define kATime 0x13
89 #define kMTime 0x14
90 #define kAttributes 0x15
91 #define kEncodedHeader 0x17
92
93 enum la_zaction {
94 ARCHIVE_Z_FINISH,
95 ARCHIVE_Z_RUN
96 };
97
98 /*
99 * A stream object of universal compressor.
100 */
101 struct la_zstream {
102 const uint8_t *next_in;
103 size_t avail_in;
104 uint64_t total_in;
105
106 uint8_t *next_out;
107 size_t avail_out;
108 uint64_t total_out;
109
110 uint32_t prop_size;
111 uint8_t *props;
112
113 int valid;
114 void *real_stream;
115 int (*code) (struct archive *a,
116 struct la_zstream *lastrm,
117 enum la_zaction action);
118 int (*end)(struct archive *a,
119 struct la_zstream *lastrm);
120 };
121
122 #define PPMD7_DEFAULT_ORDER 6
123 #define PPMD7_DEFAULT_MEM_SIZE (1 << 24)
124
125 struct ppmd_stream {
126 int stat;
127 CPpmd7 ppmd7_context;
128 CPpmd7z_RangeEnc range_enc;
129 IByteOut byteout;
130 uint8_t *buff;
131 uint8_t *buff_ptr;
132 uint8_t *buff_end;
133 size_t buff_bytes;
134 };
135
136 struct coder {
137 unsigned codec;
138 size_t prop_size;
139 uint8_t *props;
140 };
141
142 struct file {
143 struct archive_rb_node rbnode;
144
145 struct file *next;
146 unsigned name_len;
147 uint8_t *utf16name;/* UTF16-LE name. */
148 uint64_t size;
149 unsigned flg;
150 #define MTIME_IS_SET (1<<0)
151 #define ATIME_IS_SET (1<<1)
152 #define CTIME_IS_SET (1<<2)
153 #define CRC32_IS_SET (1<<3)
154 #define HAS_STREAM (1<<4)
155
156 struct {
157 time_t time;
158 long time_ns;
159 } times[3];
160 #define MTIME 0
161 #define ATIME 1
162 #define CTIME 2
163
164 mode_t mode;
165 uint32_t crc32;
166
167 int dir:1;
168 };
169
170 struct _7zip {
171 int temp_fd;
172 uint64_t temp_offset;
173
174 struct file *cur_file;
175 size_t total_number_entry;
176 size_t total_number_nonempty_entry;
177 size_t total_number_empty_entry;
178 size_t total_number_dir_entry;
179 size_t total_bytes_entry_name;
180 size_t total_number_time_defined[3];
181 uint64_t total_bytes_compressed;
182 uint64_t total_bytes_uncompressed;
183 uint64_t entry_bytes_remaining;
184 uint32_t entry_crc32;
185 uint32_t precode_crc32;
186 uint32_t encoded_crc32;
187 int crc32flg;
188 #define PRECODE_CRC32 1
189 #define ENCODED_CRC32 2
190
191 unsigned opt_compression;
192 int opt_compression_level;
193
194 struct la_zstream stream;
195 struct coder coder;
196
197 struct archive_string_conv *sconv;
198
199 /*
200 * Compressed data buffer.
201 */
202 unsigned char wbuff[512 * 20 * 6];
203 size_t wbuff_remaining;
204
205 /*
206 * The list of the file entries which has its contents is used to
207 * manage struct file objects.
208 * We use 'next' (a member of struct file) to chain.
209 */
210 struct {
211 struct file *first;
212 struct file **last;
213 } file_list, empty_list;
214 struct archive_rb_tree rbtree;/* for empty files */
215 };
216
217 static int _7z_options(struct archive_write *,
218 const char *, const char *);
219 static int _7z_write_header(struct archive_write *,
220 struct archive_entry *);
221 static ssize_t _7z_write_data(struct archive_write *,
222 const void *, size_t);
223 static int _7z_finish_entry(struct archive_write *);
224 static int _7z_close(struct archive_write *);
225 static int _7z_free(struct archive_write *);
226 static int file_cmp_node(const struct archive_rb_node *,
227 const struct archive_rb_node *);
228 static int file_cmp_key(const struct archive_rb_node *, const void *);
229 static int file_new(struct archive_write *a, struct archive_entry *,
230 struct file **);
231 static void file_free(struct file *);
232 static void file_register(struct _7zip *, struct file *);
233 static void file_register_empty(struct _7zip *, struct file *);
234 static void file_init_register(struct _7zip *);
235 static void file_init_register_empty(struct _7zip *);
236 static void file_free_register(struct _7zip *);
237 static ssize_t compress_out(struct archive_write *, const void *, size_t ,
238 enum la_zaction);
239 static int compression_init_encoder_copy(struct archive *,
240 struct la_zstream *);
241 static int compression_code_copy(struct archive *,
242 struct la_zstream *, enum la_zaction);
243 static int compression_end_copy(struct archive *, struct la_zstream *);
244 static int compression_init_encoder_deflate(struct archive *,
245 struct la_zstream *, int, int);
246 #ifdef HAVE_ZLIB_H
247 static int compression_code_deflate(struct archive *,
248 struct la_zstream *, enum la_zaction);
249 static int compression_end_deflate(struct archive *, struct la_zstream *);
250 #endif
251 static int compression_init_encoder_bzip2(struct archive *,
252 struct la_zstream *, int);
253 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
254 static int compression_code_bzip2(struct archive *,
255 struct la_zstream *, enum la_zaction);
256 static int compression_end_bzip2(struct archive *, struct la_zstream *);
257 #endif
258 static int compression_init_encoder_lzma1(struct archive *,
259 struct la_zstream *, int);
260 static int compression_init_encoder_lzma2(struct archive *,
261 struct la_zstream *, int);
262 #if defined(HAVE_LZMA_H)
263 static int compression_code_lzma(struct archive *,
264 struct la_zstream *, enum la_zaction);
265 static int compression_end_lzma(struct archive *, struct la_zstream *);
266 #endif
267 static int compression_init_encoder_ppmd(struct archive *,
268 struct la_zstream *, unsigned, uint32_t);
269 static int compression_code_ppmd(struct archive *,
270 struct la_zstream *, enum la_zaction);
271 static int compression_end_ppmd(struct archive *, struct la_zstream *);
272 static int _7z_compression_init_encoder(struct archive_write *, unsigned,
273 int);
274 static int compression_code(struct archive *,
275 struct la_zstream *, enum la_zaction);
276 static int compression_end(struct archive *,
277 struct la_zstream *);
278 static int enc_uint64(struct archive_write *, uint64_t);
279 static int make_header(struct archive_write *, uint64_t, uint64_t,
280 uint64_t, int, struct coder *);
281 static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t,
282 uint64_t, int, struct coder *, int, uint32_t);
283
284 int
archive_write_set_format_7zip(struct archive * _a)285 archive_write_set_format_7zip(struct archive *_a)
286 {
287 static const struct archive_rb_tree_ops rb_ops = {
288 file_cmp_node, file_cmp_key
289 };
290 struct archive_write *a = (struct archive_write *)_a;
291 struct _7zip *zip;
292
293 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
294 ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");
295
296 /* If another format was already registered, unregister it. */
297 if (a->format_free != NULL)
298 (a->format_free)(a);
299
300 zip = calloc(1, sizeof(*zip));
301 if (zip == NULL) {
302 archive_set_error(&a->archive, ENOMEM,
303 "Can't allocate 7-Zip data");
304 return (ARCHIVE_FATAL);
305 }
306 zip->temp_fd = -1;
307 __archive_rb_tree_init(&(zip->rbtree), &rb_ops);
308 file_init_register(zip);
309 file_init_register_empty(zip);
310
311 /* Set default compression type and its level. */
312 #if HAVE_LZMA_H
313 zip->opt_compression = _7Z_LZMA1;
314 #elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
315 zip->opt_compression = _7Z_BZIP2;
316 #elif defined(HAVE_ZLIB_H)
317 zip->opt_compression = _7Z_DEFLATE;
318 #else
319 zip->opt_compression = _7Z_COPY;
320 #endif
321 zip->opt_compression_level = 6;
322
323 a->format_data = zip;
324
325 a->format_name = "7zip";
326 a->format_options = _7z_options;
327 a->format_write_header = _7z_write_header;
328 a->format_write_data = _7z_write_data;
329 a->format_finish_entry = _7z_finish_entry;
330 a->format_close = _7z_close;
331 a->format_free = _7z_free;
332 a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
333 a->archive.archive_format_name = "7zip";
334
335 return (ARCHIVE_OK);
336 }
337
338 static int
_7z_options(struct archive_write * a,const char * key,const char * value)339 _7z_options(struct archive_write *a, const char *key, const char *value)
340 {
341 struct _7zip *zip;
342
343 zip = (struct _7zip *)a->format_data;
344
345 if (strcmp(key, "compression") == 0) {
346 const char *name = NULL;
347
348 if (value == NULL || strcmp(value, "copy") == 0 ||
349 strcmp(value, "COPY") == 0 ||
350 strcmp(value, "store") == 0 ||
351 strcmp(value, "STORE") == 0)
352 zip->opt_compression = _7Z_COPY;
353 else if (strcmp(value, "deflate") == 0 ||
354 strcmp(value, "DEFLATE") == 0)
355 #if HAVE_ZLIB_H
356 zip->opt_compression = _7Z_DEFLATE;
357 #else
358 name = "deflate";
359 #endif
360 else if (strcmp(value, "bzip2") == 0 ||
361 strcmp(value, "BZIP2") == 0)
362 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
363 zip->opt_compression = _7Z_BZIP2;
364 #else
365 name = "bzip2";
366 #endif
367 else if (strcmp(value, "lzma1") == 0 ||
368 strcmp(value, "LZMA1") == 0)
369 #if HAVE_LZMA_H
370 zip->opt_compression = _7Z_LZMA1;
371 #else
372 name = "lzma1";
373 #endif
374 else if (strcmp(value, "lzma2") == 0 ||
375 strcmp(value, "LZMA2") == 0)
376 #if HAVE_LZMA_H
377 zip->opt_compression = _7Z_LZMA2;
378 #else
379 name = "lzma2";
380 #endif
381 else if (strcmp(value, "ppmd") == 0 ||
382 strcmp(value, "PPMD") == 0 ||
383 strcmp(value, "PPMd") == 0)
384 zip->opt_compression = _7Z_PPMD;
385 else {
386 archive_set_error(&(a->archive),
387 ARCHIVE_ERRNO_MISC,
388 "Unknown compression name: `%s'",
389 value);
390 return (ARCHIVE_FAILED);
391 }
392 if (name != NULL) {
393 archive_set_error(&(a->archive),
394 ARCHIVE_ERRNO_MISC,
395 "`%s' compression not supported "
396 "on this platform",
397 name);
398 return (ARCHIVE_FAILED);
399 }
400 return (ARCHIVE_OK);
401 }
402 if (strcmp(key, "compression-level") == 0) {
403 if (value == NULL ||
404 !(value[0] >= '0' && value[0] <= '9') ||
405 value[1] != '\0') {
406 archive_set_error(&(a->archive),
407 ARCHIVE_ERRNO_MISC,
408 "Illegal value `%s'",
409 value);
410 return (ARCHIVE_FAILED);
411 }
412 zip->opt_compression_level = value[0] - '0';
413 return (ARCHIVE_OK);
414 }
415
416 /* Note: The "warn" return is just to inform the options
417 * supervisor that we didn't handle it. It will generate
418 * a suitable error if no one used this option. */
419 return (ARCHIVE_WARN);
420 }
421
422 static int
_7z_write_header(struct archive_write * a,struct archive_entry * entry)423 _7z_write_header(struct archive_write *a, struct archive_entry *entry)
424 {
425 struct _7zip *zip;
426 struct file *file;
427 int r;
428
429 zip = (struct _7zip *)a->format_data;
430 zip->cur_file = NULL;
431 zip->entry_bytes_remaining = 0;
432
433 if (zip->sconv == NULL) {
434 zip->sconv = archive_string_conversion_to_charset(
435 &a->archive, "UTF-16LE", 1);
436 if (zip->sconv == NULL)
437 return (ARCHIVE_FATAL);
438 }
439
440 r = file_new(a, entry, &file);
441 if (r < ARCHIVE_WARN) {
442 file_free(file);
443 return (r);
444 }
445 if (file->size == 0 && file->dir) {
446 if (!__archive_rb_tree_insert_node(&(zip->rbtree),
447 (struct archive_rb_node *)file)) {
448 /* We have already had the same file. */
449 file_free(file);
450 return (ARCHIVE_OK);
451 }
452 }
453
454 if (file->flg & MTIME_IS_SET)
455 zip->total_number_time_defined[MTIME]++;
456 if (file->flg & CTIME_IS_SET)
457 zip->total_number_time_defined[CTIME]++;
458 if (file->flg & ATIME_IS_SET)
459 zip->total_number_time_defined[ATIME]++;
460
461 zip->total_number_entry++;
462 zip->total_bytes_entry_name += file->name_len + 2;
463 if (file->size == 0) {
464 /* Count up the number of empty files. */
465 zip->total_number_empty_entry++;
466 if (file->dir)
467 zip->total_number_dir_entry++;
468 else
469 file_register_empty(zip, file);
470 return (r);
471 }
472
473 /*
474 * Init compression.
475 */
476 if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) {
477 r = _7z_compression_init_encoder(a, zip->opt_compression,
478 zip->opt_compression_level);
479 if (r < 0) {
480 file_free(file);
481 return (ARCHIVE_FATAL);
482 }
483 }
484
485 /* Register a non-empty file. */
486 file_register(zip, file);
487
488 /*
489 * Set the current file to cur_file to read its contents.
490 */
491 zip->cur_file = file;
492
493
494 /* Save a offset of current file in temporary file. */
495 zip->entry_bytes_remaining = file->size;
496 zip->entry_crc32 = 0;
497
498 /*
499 * Store a symbolic link name as file contents.
500 */
501 if (archive_entry_filetype(entry) == AE_IFLNK) {
502 ssize_t bytes;
503 const void *p = (const void *)archive_entry_symlink(entry);
504 bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN);
505 if (bytes < 0)
506 return ((int)bytes);
507 zip->entry_crc32 = crc32(zip->entry_crc32, p, (unsigned)bytes);
508 zip->entry_bytes_remaining -= bytes;
509 }
510
511 return (r);
512 }
513
514 /*
515 * Write data to a temporary file.
516 */
517 static int
write_to_temp(struct archive_write * a,const void * buff,size_t s)518 write_to_temp(struct archive_write *a, const void *buff, size_t s)
519 {
520 struct _7zip *zip;
521 const unsigned char *p;
522 ssize_t ws;
523
524 zip = (struct _7zip *)a->format_data;
525
526 /*
527 * Open a temporary file.
528 */
529 if (zip->temp_fd == -1) {
530 zip->temp_offset = 0;
531 zip->temp_fd = __archive_mktemp(NULL);
532 if (zip->temp_fd < 0) {
533 archive_set_error(&a->archive, errno,
534 "Couldn't create temporary file");
535 return (ARCHIVE_FATAL);
536 }
537 }
538
539 p = (const unsigned char *)buff;
540 while (s) {
541 ws = write(zip->temp_fd, p, s);
542 if (ws < 0) {
543 archive_set_error(&(a->archive), errno,
544 "fwrite function failed");
545 return (ARCHIVE_FATAL);
546 }
547 s -= ws;
548 p += ws;
549 zip->temp_offset += ws;
550 }
551 return (ARCHIVE_OK);
552 }
553
554 static ssize_t
compress_out(struct archive_write * a,const void * buff,size_t s,enum la_zaction run)555 compress_out(struct archive_write *a, const void *buff, size_t s,
556 enum la_zaction run)
557 {
558 struct _7zip *zip = (struct _7zip *)a->format_data;
559 int r;
560
561 if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0)
562 return (0);
563
564 if ((zip->crc32flg & PRECODE_CRC32) && s)
565 zip->precode_crc32 = crc32(zip->precode_crc32, buff,
566 (unsigned)s);
567 zip->stream.next_in = (const unsigned char *)buff;
568 zip->stream.avail_in = s;
569 for (;;) {
570 /* Compress file data. */
571 r = compression_code(&(a->archive), &(zip->stream), run);
572 if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
573 return (ARCHIVE_FATAL);
574 if (zip->stream.avail_out == 0) {
575 if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff))
576 != ARCHIVE_OK)
577 return (ARCHIVE_FATAL);
578 zip->stream.next_out = zip->wbuff;
579 zip->stream.avail_out = sizeof(zip->wbuff);
580 if (zip->crc32flg & ENCODED_CRC32)
581 zip->encoded_crc32 = crc32(zip->encoded_crc32,
582 zip->wbuff, sizeof(zip->wbuff));
583 if (run == ARCHIVE_Z_FINISH && r != ARCHIVE_EOF)
584 continue;
585 }
586 if (zip->stream.avail_in == 0)
587 break;
588 }
589 if (run == ARCHIVE_Z_FINISH) {
590 uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out;
591 if (write_to_temp(a, zip->wbuff, (size_t)bytes) != ARCHIVE_OK)
592 return (ARCHIVE_FATAL);
593 if ((zip->crc32flg & ENCODED_CRC32) && bytes)
594 zip->encoded_crc32 = crc32(zip->encoded_crc32,
595 zip->wbuff, (unsigned)bytes);
596 }
597
598 return (s);
599 }
600
601 static ssize_t
_7z_write_data(struct archive_write * a,const void * buff,size_t s)602 _7z_write_data(struct archive_write *a, const void *buff, size_t s)
603 {
604 struct _7zip *zip;
605 ssize_t bytes;
606
607 zip = (struct _7zip *)a->format_data;
608
609 if (s > zip->entry_bytes_remaining)
610 s = (size_t)zip->entry_bytes_remaining;
611 if (s == 0 || zip->cur_file == NULL)
612 return (0);
613 bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN);
614 if (bytes < 0)
615 return (bytes);
616 zip->entry_crc32 = crc32(zip->entry_crc32, buff, (unsigned)bytes);
617 zip->entry_bytes_remaining -= bytes;
618 return (bytes);
619 }
620
621 static int
_7z_finish_entry(struct archive_write * a)622 _7z_finish_entry(struct archive_write *a)
623 {
624 struct _7zip *zip;
625 size_t s;
626 ssize_t r;
627
628 zip = (struct _7zip *)a->format_data;
629 if (zip->cur_file == NULL)
630 return (ARCHIVE_OK);
631
632 while (zip->entry_bytes_remaining > 0) {
633 s = (size_t)zip->entry_bytes_remaining;
634 if (s > a->null_length)
635 s = a->null_length;
636 r = _7z_write_data(a, a->nulls, s);
637 if (r < 0)
638 return ((int)r);
639 }
640 zip->total_bytes_compressed += zip->stream.total_in;
641 zip->total_bytes_uncompressed += zip->stream.total_out;
642 zip->cur_file->crc32 = zip->entry_crc32;
643 zip->cur_file = NULL;
644
645 return (ARCHIVE_OK);
646 }
647
648 static int
flush_wbuff(struct archive_write * a)649 flush_wbuff(struct archive_write *a)
650 {
651 struct _7zip *zip;
652 int r;
653 size_t s;
654
655 zip = (struct _7zip *)a->format_data;
656 s = sizeof(zip->wbuff) - zip->wbuff_remaining;
657 r = __archive_write_output(a, zip->wbuff, s);
658 if (r != ARCHIVE_OK)
659 return (r);
660 zip->wbuff_remaining = sizeof(zip->wbuff);
661 return (r);
662 }
663
664 static int
copy_out(struct archive_write * a,uint64_t offset,uint64_t length)665 copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
666 {
667 struct _7zip *zip;
668 int r;
669
670 zip = (struct _7zip *)a->format_data;
671 if (zip->temp_offset > 0 &&
672 lseek(zip->temp_fd, offset, SEEK_SET) < 0) {
673 archive_set_error(&(a->archive), errno, "lseek failed");
674 return (ARCHIVE_FATAL);
675 }
676 while (length) {
677 size_t rsize;
678 ssize_t rs;
679 unsigned char *wb;
680
681 if (length > zip->wbuff_remaining)
682 rsize = zip->wbuff_remaining;
683 else
684 rsize = (size_t)length;
685 wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining);
686 rs = read(zip->temp_fd, wb, rsize);
687 if (rs < 0) {
688 archive_set_error(&(a->archive), errno,
689 "Can't read temporary file(%jd)",
690 (intmax_t)rs);
691 return (ARCHIVE_FATAL);
692 }
693 if (rs == 0) {
694 archive_set_error(&(a->archive), 0,
695 "Truncated 7-Zip archive");
696 return (ARCHIVE_FATAL);
697 }
698 zip->wbuff_remaining -= rs;
699 length -= rs;
700 if (zip->wbuff_remaining == 0) {
701 r = flush_wbuff(a);
702 if (r != ARCHIVE_OK)
703 return (r);
704 }
705 }
706 return (ARCHIVE_OK);
707 }
708
709 static int
_7z_close(struct archive_write * a)710 _7z_close(struct archive_write *a)
711 {
712 struct _7zip *zip;
713 unsigned char *wb;
714 uint64_t header_offset, header_size, header_unpacksize;
715 uint64_t length;
716 uint32_t header_crc32;
717 int r;
718
719 zip = (struct _7zip *)a->format_data;
720
721 if (zip->total_number_entry > 0) {
722 struct archive_rb_node *n;
723 uint64_t data_offset, data_size, data_unpacksize;
724 unsigned header_compression;
725
726 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
727 if (r < 0)
728 return (r);
729 data_offset = 0;
730 data_size = zip->stream.total_out;
731 data_unpacksize = zip->stream.total_in;
732 zip->coder.codec = zip->opt_compression;
733 zip->coder.prop_size = zip->stream.prop_size;
734 zip->coder.props = zip->stream.props;
735 zip->stream.prop_size = 0;
736 zip->stream.props = NULL;
737 zip->total_number_nonempty_entry =
738 zip->total_number_entry - zip->total_number_empty_entry;
739
740 /* Connect an empty file list. */
741 if (zip->empty_list.first != NULL) {
742 *zip->file_list.last = zip->empty_list.first;
743 zip->file_list.last = zip->empty_list.last;
744 }
745 /* Connect a directory file list. */
746 ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
747 file_register(zip, (struct file *)n);
748 }
749
750 /*
751 * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
752 * the compression type for encoding the header.
753 */
754 #if HAVE_LZMA_H
755 header_compression = _7Z_LZMA1;
756 /* If the stored file is only one, do not encode the header.
757 * This is the same way 7z command does. */
758 if (zip->total_number_entry == 1)
759 header_compression = _7Z_COPY;
760 #else
761 header_compression = _7Z_COPY;
762 #endif
763 r = _7z_compression_init_encoder(a, header_compression, 6);
764 if (r < 0)
765 return (r);
766 zip->crc32flg = PRECODE_CRC32;
767 zip->precode_crc32 = 0;
768 r = make_header(a, data_offset, data_size, data_unpacksize,
769 1, &(zip->coder));
770 if (r < 0)
771 return (r);
772 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
773 if (r < 0)
774 return (r);
775 header_offset = data_offset + data_size;
776 header_size = zip->stream.total_out;
777 header_crc32 = zip->precode_crc32;
778 header_unpacksize = zip->stream.total_in;
779
780 if (header_compression != _7Z_COPY) {
781 /*
782 * Encode the header in order to reduce the size
783 * of the archive.
784 */
785 free(zip->coder.props);
786 zip->coder.codec = header_compression;
787 zip->coder.prop_size = zip->stream.prop_size;
788 zip->coder.props = zip->stream.props;
789 zip->stream.prop_size = 0;
790 zip->stream.props = NULL;
791
792 r = _7z_compression_init_encoder(a, _7Z_COPY, 0);
793 if (r < 0)
794 return (r);
795 zip->crc32flg = ENCODED_CRC32;
796 zip->encoded_crc32 = 0;
797
798 /*
799 * Make EncodedHeader.
800 */
801 r = enc_uint64(a, kEncodedHeader);
802 if (r < 0)
803 return (r);
804 r = make_streamsInfo(a, header_offset, header_size,
805 header_unpacksize, 1, &(zip->coder), 0,
806 header_crc32);
807 if (r < 0)
808 return (r);
809 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
810 if (r < 0)
811 return (r);
812 header_offset = header_offset + header_size;
813 header_size = zip->stream.total_out;
814 header_crc32 = zip->encoded_crc32;
815 }
816 zip->crc32flg = 0;
817 } else {
818 header_offset = header_size = 0;
819 header_crc32 = 0;
820 }
821
822 length = zip->temp_offset;
823
824 /*
825 * Make the zip header on wbuff(write buffer).
826 */
827 wb = zip->wbuff;
828 zip->wbuff_remaining = sizeof(zip->wbuff);
829 memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6);
830 wb[6] = 0;/* Major version. */
831 wb[7] = 3;/* Minor version. */
832 archive_le64enc(&wb[12], header_offset);/* Next Header Offset */
833 archive_le64enc(&wb[20], header_size);/* Next Header Size */
834 archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */
835 archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */
836 zip->wbuff_remaining -= 32;
837
838 /*
839 * Read all file contents and an encoded header from the temporary
840 * file and write out it.
841 */
842 r = copy_out(a, 0, length);
843 if (r != ARCHIVE_OK)
844 return (r);
845 r = flush_wbuff(a);
846 return (r);
847 }
848
849 /*
850 * Encode 64 bits value into 7-Zip's encoded UINT64 value.
851 */
852 static int
enc_uint64(struct archive_write * a,uint64_t val)853 enc_uint64(struct archive_write *a, uint64_t val)
854 {
855 unsigned mask = 0x80;
856 uint8_t numdata[9];
857 int i;
858
859 numdata[0] = 0;
860 for (i = 1; i < (int)sizeof(numdata); i++) {
861 if (val < mask) {
862 numdata[0] |= (uint8_t)val;
863 break;
864 }
865 numdata[i] = (uint8_t)val;
866 val >>= 8;
867 numdata[0] |= mask;
868 mask >>= 1;
869 }
870 return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN));
871 }
872
873 static int
make_substreamsInfo(struct archive_write * a,struct coder * coders)874 make_substreamsInfo(struct archive_write *a, struct coder *coders)
875 {
876 struct _7zip *zip = (struct _7zip *)a->format_data;
877 struct file *file;
878 int r;
879
880 /*
881 * Make SubStreamsInfo.
882 */
883 r = enc_uint64(a, kSubStreamsInfo);
884 if (r < 0)
885 return (r);
886
887 if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) {
888 /*
889 * Make NumUnPackStream.
890 */
891 r = enc_uint64(a, kNumUnPackStream);
892 if (r < 0)
893 return (r);
894
895 /* Write numUnpackStreams */
896 r = enc_uint64(a, zip->total_number_nonempty_entry);
897 if (r < 0)
898 return (r);
899
900 /*
901 * Make kSize.
902 */
903 r = enc_uint64(a, kSize);
904 if (r < 0)
905 return (r);
906 file = zip->file_list.first;
907 for (;file != NULL; file = file->next) {
908 if (file->next == NULL ||
909 file->next->size == 0)
910 break;
911 r = enc_uint64(a, file->size);
912 if (r < 0)
913 return (r);
914 }
915 }
916
917 /*
918 * Make CRC.
919 */
920 r = enc_uint64(a, kCRC);
921 if (r < 0)
922 return (r);
923
924
925 /* All are defined */
926 r = enc_uint64(a, 1);
927 if (r < 0)
928 return (r);
929 file = zip->file_list.first;
930 for (;file != NULL; file = file->next) {
931 uint8_t crc[4];
932 if (file->size == 0)
933 break;
934 archive_le32enc(crc, file->crc32);
935 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
936 if (r < 0)
937 return (r);
938 }
939
940 /* Write End. */
941 r = enc_uint64(a, kEnd);
942 if (r < 0)
943 return (r);
944 return (ARCHIVE_OK);
945 }
946
947 static int
make_streamsInfo(struct archive_write * a,uint64_t offset,uint64_t pack_size,uint64_t unpack_size,int num_coder,struct coder * coders,int substrm,uint32_t header_crc)948 make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size,
949 uint64_t unpack_size, int num_coder, struct coder *coders, int substrm,
950 uint32_t header_crc)
951 {
952 struct _7zip *zip = (struct _7zip *)a->format_data;
953 uint8_t codec_buff[8];
954 int numFolders, fi;
955 int codec_size;
956 int i, r;
957
958 if (coders->codec == _7Z_COPY)
959 numFolders = (int)zip->total_number_nonempty_entry;
960 else
961 numFolders = 1;
962
963 /*
964 * Make PackInfo.
965 */
966 r = enc_uint64(a, kPackInfo);
967 if (r < 0)
968 return (r);
969
970 /* Write PackPos. */
971 r = enc_uint64(a, offset);
972 if (r < 0)
973 return (r);
974
975 /* Write NumPackStreams. */
976 r = enc_uint64(a, numFolders);
977 if (r < 0)
978 return (r);
979
980 /* Make Size. */
981 r = enc_uint64(a, kSize);
982 if (r < 0)
983 return (r);
984
985 if (numFolders > 1) {
986 struct file *file = zip->file_list.first;
987 for (;file != NULL; file = file->next) {
988 if (file->size == 0)
989 break;
990 r = enc_uint64(a, file->size);
991 if (r < 0)
992 return (r);
993 }
994 } else {
995 /* Write size. */
996 r = enc_uint64(a, pack_size);
997 if (r < 0)
998 return (r);
999 }
1000
1001 r = enc_uint64(a, kEnd);
1002 if (r < 0)
1003 return (r);
1004
1005 /*
1006 * Make UnPackInfo.
1007 */
1008 r = enc_uint64(a, kUnPackInfo);
1009 if (r < 0)
1010 return (r);
1011
1012 /*
1013 * Make Folder.
1014 */
1015 r = enc_uint64(a, kFolder);
1016 if (r < 0)
1017 return (r);
1018
1019 /* Write NumFolders. */
1020 r = enc_uint64(a, numFolders);
1021 if (r < 0)
1022 return (r);
1023
1024 /* Write External. */
1025 r = enc_uint64(a, 0);
1026 if (r < 0)
1027 return (r);
1028
1029 for (fi = 0; fi < numFolders; fi++) {
1030 /* Write NumCoders. */
1031 r = enc_uint64(a, num_coder);
1032 if (r < 0)
1033 return (r);
1034
1035 for (i = 0; i < num_coder; i++) {
1036 unsigned codec_id = coders[i].codec;
1037
1038 /* Write Codec flag. */
1039 archive_be64enc(codec_buff, codec_id);
1040 for (codec_size = 8; codec_size > 0; codec_size--) {
1041 if (codec_buff[8 - codec_size])
1042 break;
1043 }
1044 if (codec_size == 0)
1045 codec_size = 1;
1046 if (coders[i].prop_size)
1047 r = enc_uint64(a, codec_size | 0x20);
1048 else
1049 r = enc_uint64(a, codec_size);
1050 if (r < 0)
1051 return (r);
1052
1053 /* Write Codec ID. */
1054 codec_size &= 0x0f;
1055 r = (int)compress_out(a, &codec_buff[8-codec_size],
1056 codec_size, ARCHIVE_Z_RUN);
1057 if (r < 0)
1058 return (r);
1059
1060 if (coders[i].prop_size) {
1061 /* Write Codec property size. */
1062 r = enc_uint64(a, coders[i].prop_size);
1063 if (r < 0)
1064 return (r);
1065
1066 /* Write Codec properties. */
1067 r = (int)compress_out(a, coders[i].props,
1068 coders[i].prop_size, ARCHIVE_Z_RUN);
1069 if (r < 0)
1070 return (r);
1071 }
1072 }
1073 }
1074
1075 /*
1076 * Make CodersUnPackSize.
1077 */
1078 r = enc_uint64(a, kCodersUnPackSize);
1079 if (r < 0)
1080 return (r);
1081
1082 if (numFolders > 1) {
1083 struct file *file = zip->file_list.first;
1084 for (;file != NULL; file = file->next) {
1085 if (file->size == 0)
1086 break;
1087 r = enc_uint64(a, file->size);
1088 if (r < 0)
1089 return (r);
1090 }
1091
1092 } else {
1093 /* Write UnPackSize. */
1094 r = enc_uint64(a, unpack_size);
1095 if (r < 0)
1096 return (r);
1097 }
1098
1099 if (!substrm) {
1100 uint8_t crc[4];
1101 /*
1102 * Make CRC.
1103 */
1104 r = enc_uint64(a, kCRC);
1105 if (r < 0)
1106 return (r);
1107
1108 /* All are defined */
1109 r = enc_uint64(a, 1);
1110 if (r < 0)
1111 return (r);
1112 archive_le32enc(crc, header_crc);
1113 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
1114 if (r < 0)
1115 return (r);
1116 }
1117
1118 /* Write End. */
1119 r = enc_uint64(a, kEnd);
1120 if (r < 0)
1121 return (r);
1122
1123 if (substrm) {
1124 /*
1125 * Make SubStreamsInfo.
1126 */
1127 r = make_substreamsInfo(a, coders);
1128 if (r < 0)
1129 return (r);
1130 }
1131
1132
1133 /* Write End. */
1134 r = enc_uint64(a, kEnd);
1135 if (r < 0)
1136 return (r);
1137
1138 return (ARCHIVE_OK);
1139 }
1140
1141
1142 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1143 static uint64_t
utcToFiletime(time_t t,long ns)1144 utcToFiletime(time_t t, long ns)
1145 {
1146 uint64_t fileTime;
1147
1148 fileTime = t;
1149 fileTime *= 10000000;
1150 fileTime += ns / 100;
1151 fileTime += EPOC_TIME;
1152 return (fileTime);
1153 }
1154
1155 static int
make_time(struct archive_write * a,uint8_t type,unsigned flg,int ti)1156 make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti)
1157 {
1158 uint8_t filetime[8];
1159 struct _7zip *zip = (struct _7zip *)a->format_data;
1160 struct file *file;
1161 int r;
1162 uint8_t b, mask;
1163
1164 /*
1165 * Make Time Bools.
1166 */
1167 if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
1168 /* Write Time Type. */
1169 r = enc_uint64(a, type);
1170 if (r < 0)
1171 return (r);
1172 /* Write EmptyStream Size. */
1173 r = enc_uint64(a, 2 + zip->total_number_entry * 8);
1174 if (r < 0)
1175 return (r);
1176 /* All are defined. */
1177 r = enc_uint64(a, 1);
1178 if (r < 0)
1179 return (r);
1180 } else {
1181 if (zip->total_number_time_defined[ti] == 0)
1182 return (ARCHIVE_OK);
1183
1184 /* Write Time Type. */
1185 r = enc_uint64(a, type);
1186 if (r < 0)
1187 return (r);
1188 /* Write EmptyStream Size. */
1189 r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
1190 + zip->total_number_time_defined[ti] * 8);
1191 if (r < 0)
1192 return (r);
1193
1194 /* All are not defined. */
1195 r = enc_uint64(a, 0);
1196 if (r < 0)
1197 return (r);
1198
1199 b = 0;
1200 mask = 0x80;
1201 file = zip->file_list.first;
1202 for (;file != NULL; file = file->next) {
1203 if (file->flg & flg)
1204 b |= mask;
1205 mask >>= 1;
1206 if (mask == 0) {
1207 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1208 if (r < 0)
1209 return (r);
1210 mask = 0x80;
1211 b = 0;
1212 }
1213 }
1214 if (mask != 0x80) {
1215 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1216 if (r < 0)
1217 return (r);
1218 }
1219 }
1220
1221 /* External. */
1222 r = enc_uint64(a, 0);
1223 if (r < 0)
1224 return (r);
1225
1226
1227 /*
1228 * Make Times.
1229 */
1230 file = zip->file_list.first;
1231 for (;file != NULL; file = file->next) {
1232 if ((file->flg & flg) == 0)
1233 continue;
1234 archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
1235 file->times[ti].time_ns));
1236 r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
1237 if (r < 0)
1238 return (r);
1239 }
1240
1241 return (ARCHIVE_OK);
1242 }
1243
1244 static int
make_header(struct archive_write * a,uint64_t offset,uint64_t pack_size,uint64_t unpack_size,int codernum,struct coder * coders)1245 make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
1246 uint64_t unpack_size, int codernum, struct coder *coders)
1247 {
1248 struct _7zip *zip = (struct _7zip *)a->format_data;
1249 struct file *file;
1250 int r;
1251 uint8_t b, mask;
1252
1253 /*
1254 * Make FilesInfo.
1255 */
1256 r = enc_uint64(a, kHeader);
1257 if (r < 0)
1258 return (r);
1259
1260 /*
1261 * If there are empty files only, do not write MainStreamInfo.
1262 */
1263 if (zip->total_number_nonempty_entry) {
1264 /*
1265 * Make MainStreamInfo.
1266 */
1267 r = enc_uint64(a, kMainStreamsInfo);
1268 if (r < 0)
1269 return (r);
1270 r = make_streamsInfo(a, offset, pack_size, unpack_size,
1271 codernum, coders, 1, 0);
1272 if (r < 0)
1273 return (r);
1274 }
1275
1276 /*
1277 * Make FilesInfo.
1278 */
1279 r = enc_uint64(a, kFilesInfo);
1280 if (r < 0)
1281 return (r);
1282
1283 /* Write numFiles. */
1284 r = enc_uint64(a, zip->total_number_entry);
1285 if (r < 0)
1286 return (r);
1287
1288 if (zip->total_number_empty_entry > 0) {
1289 /* Make EmptyStream. */
1290 r = enc_uint64(a, kEmptyStream);
1291 if (r < 0)
1292 return (r);
1293
1294 /* Write EmptyStream Size. */
1295 r = enc_uint64(a, (zip->total_number_entry+7)>>3);
1296 if (r < 0)
1297 return (r);
1298
1299 b = 0;
1300 mask = 0x80;
1301 file = zip->file_list.first;
1302 for (;file != NULL; file = file->next) {
1303 if (file->size == 0)
1304 b |= mask;
1305 mask >>= 1;
1306 if (mask == 0) {
1307 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1308 if (r < 0)
1309 return (r);
1310 mask = 0x80;
1311 b = 0;
1312 }
1313 }
1314 if (mask != 0x80) {
1315 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1316 if (r < 0)
1317 return (r);
1318 }
1319 }
1320
1321 if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
1322 /* Make EmptyFile. */
1323 r = enc_uint64(a, kEmptyFile);
1324 if (r < 0)
1325 return (r);
1326
1327 /* Write EmptyFile Size. */
1328 r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
1329 if (r < 0)
1330 return (r);
1331
1332 b = 0;
1333 mask = 0x80;
1334 file = zip->file_list.first;
1335 for (;file != NULL; file = file->next) {
1336 if (file->size)
1337 continue;
1338 if (!file->dir)
1339 b |= mask;
1340 mask >>= 1;
1341 if (mask == 0) {
1342 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1343 if (r < 0)
1344 return (r);
1345 mask = 0x80;
1346 b = 0;
1347 }
1348 }
1349 if (mask != 0x80) {
1350 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1351 if (r < 0)
1352 return (r);
1353 }
1354 }
1355
1356 /* Make Name. */
1357 r = enc_uint64(a, kName);
1358 if (r < 0)
1359 return (r);
1360
1361 /* Write Name size. */
1362 r = enc_uint64(a, zip->total_bytes_entry_name+1);
1363 if (r < 0)
1364 return (r);
1365
1366 /* Write dmy byte. */
1367 r = enc_uint64(a, 0);
1368 if (r < 0)
1369 return (r);
1370
1371 file = zip->file_list.first;
1372 for (;file != NULL; file = file->next) {
1373 r = (int)compress_out(a, file->utf16name, file->name_len+2,
1374 ARCHIVE_Z_RUN);
1375 if (r < 0)
1376 return (r);
1377 }
1378
1379 /* Make MTime. */
1380 r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
1381 if (r < 0)
1382 return (r);
1383
1384 /* Make CTime. */
1385 r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
1386 if (r < 0)
1387 return (r);
1388
1389 /* Make ATime. */
1390 r = make_time(a, kATime, ATIME_IS_SET, ATIME);
1391 if (r < 0)
1392 return (r);
1393
1394 /* Make Attributes. */
1395 r = enc_uint64(a, kAttributes);
1396 if (r < 0)
1397 return (r);
1398
1399 /* Write Attributes size. */
1400 r = enc_uint64(a, 2 + zip->total_number_entry * 4);
1401 if (r < 0)
1402 return (r);
1403
1404 /* Write "All Are Defined". */
1405 r = enc_uint64(a, 1);
1406 if (r < 0)
1407 return (r);
1408
1409 /* Write dmy byte. */
1410 r = enc_uint64(a, 0);
1411 if (r < 0)
1412 return (r);
1413
1414 file = zip->file_list.first;
1415 for (;file != NULL; file = file->next) {
1416 /*
1417 * High 16bits is unix mode.
1418 * Low 16bits is Windows attributes.
1419 */
1420 uint32_t encattr, attr;
1421 if (file->dir)
1422 attr = 0x8010;
1423 else
1424 attr = 0x8020;
1425 if ((file->mode & 0222) == 0)
1426 attr |= 1;/* Read Only. */
1427 attr |= ((uint32_t)file->mode) << 16;
1428 archive_le32enc(&encattr, attr);
1429 r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
1430 if (r < 0)
1431 return (r);
1432 }
1433
1434 /* Write End. */
1435 r = enc_uint64(a, kEnd);
1436 if (r < 0)
1437 return (r);
1438
1439 /* Write End. */
1440 r = enc_uint64(a, kEnd);
1441 if (r < 0)
1442 return (r);
1443
1444 return (ARCHIVE_OK);
1445 }
1446
1447
1448 static int
_7z_free(struct archive_write * a)1449 _7z_free(struct archive_write *a)
1450 {
1451 struct _7zip *zip = (struct _7zip *)a->format_data;
1452
1453 /* Close the temporary file. */
1454 if (zip->temp_fd >= 0)
1455 close(zip->temp_fd);
1456
1457 file_free_register(zip);
1458 compression_end(&(a->archive), &(zip->stream));
1459 free(zip->coder.props);
1460 free(zip);
1461
1462 return (ARCHIVE_OK);
1463 }
1464
1465 static int
file_cmp_node(const struct archive_rb_node * n1,const struct archive_rb_node * n2)1466 file_cmp_node(const struct archive_rb_node *n1,
1467 const struct archive_rb_node *n2)
1468 {
1469 const struct file *f1 = (const struct file *)n1;
1470 const struct file *f2 = (const struct file *)n2;
1471
1472 if (f1->name_len == f2->name_len)
1473 return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
1474 return (f1->name_len > f2->name_len)?1:-1;
1475 }
1476
1477 static int
file_cmp_key(const struct archive_rb_node * n,const void * key)1478 file_cmp_key(const struct archive_rb_node *n, const void *key)
1479 {
1480 const struct file *f = (const struct file *)n;
1481
1482 return (f->name_len - *(const char *)key);
1483 }
1484
1485 static int
file_new(struct archive_write * a,struct archive_entry * entry,struct file ** newfile)1486 file_new(struct archive_write *a, struct archive_entry *entry,
1487 struct file **newfile)
1488 {
1489 struct _7zip *zip;
1490 struct file *file;
1491 const char *u16;
1492 size_t u16len;
1493 int ret = ARCHIVE_OK;
1494
1495 zip = (struct _7zip *)a->format_data;
1496 *newfile = NULL;
1497
1498 file = calloc(1, sizeof(*file));
1499 if (file == NULL) {
1500 archive_set_error(&a->archive, ENOMEM,
1501 "Can't allocate memory");
1502 return (ARCHIVE_FATAL);
1503 }
1504
1505 if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
1506 if (errno == ENOMEM) {
1507 free(file);
1508 archive_set_error(&a->archive, ENOMEM,
1509 "Can't allocate memory for UTF-16LE");
1510 return (ARCHIVE_FATAL);
1511 }
1512 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1513 "A filename cannot be converted to UTF-16LE;"
1514 "You should disable making Joliet extension");
1515 ret = ARCHIVE_WARN;
1516 }
1517 file->utf16name = malloc(u16len + 2);
1518 if (file->utf16name == NULL) {
1519 free(file);
1520 archive_set_error(&a->archive, ENOMEM,
1521 "Can't allocate memory for Name");
1522 return (ARCHIVE_FATAL);
1523 }
1524 memcpy(file->utf16name, u16, u16len);
1525 file->utf16name[u16len+0] = 0;
1526 file->utf16name[u16len+1] = 0;
1527 file->name_len = (unsigned)u16len;
1528 file->mode = archive_entry_mode(entry);
1529 if (archive_entry_filetype(entry) == AE_IFREG)
1530 file->size = archive_entry_size(entry);
1531 else
1532 archive_entry_set_size(entry, 0);
1533 if (archive_entry_filetype(entry) == AE_IFDIR)
1534 file->dir = 1;
1535 else if (archive_entry_filetype(entry) == AE_IFLNK)
1536 file->size = strlen(archive_entry_symlink(entry));
1537 if (archive_entry_mtime_is_set(entry)) {
1538 file->flg |= MTIME_IS_SET;
1539 file->times[MTIME].time = archive_entry_mtime(entry);
1540 file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
1541 }
1542 if (archive_entry_atime_is_set(entry)) {
1543 file->flg |= ATIME_IS_SET;
1544 file->times[ATIME].time = archive_entry_atime(entry);
1545 file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
1546 }
1547 if (archive_entry_ctime_is_set(entry)) {
1548 file->flg |= CTIME_IS_SET;
1549 file->times[CTIME].time = archive_entry_ctime(entry);
1550 file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
1551 }
1552
1553 *newfile = file;
1554 return (ret);
1555 }
1556
1557 static void
file_free(struct file * file)1558 file_free(struct file *file)
1559 {
1560 free(file->utf16name);
1561 free(file);
1562 }
1563
1564 static void
file_register(struct _7zip * zip,struct file * file)1565 file_register(struct _7zip *zip, struct file *file)
1566 {
1567 file->next = NULL;
1568 *zip->file_list.last = file;
1569 zip->file_list.last = &(file->next);
1570 }
1571
1572 static void
file_init_register(struct _7zip * zip)1573 file_init_register(struct _7zip *zip)
1574 {
1575 zip->file_list.first = NULL;
1576 zip->file_list.last = &(zip->file_list.first);
1577 }
1578
1579 static void
file_free_register(struct _7zip * zip)1580 file_free_register(struct _7zip *zip)
1581 {
1582 struct file *file, *file_next;
1583
1584 file = zip->file_list.first;
1585 while (file != NULL) {
1586 file_next = file->next;
1587 file_free(file);
1588 file = file_next;
1589 }
1590 }
1591
1592 static void
file_register_empty(struct _7zip * zip,struct file * file)1593 file_register_empty(struct _7zip *zip, struct file *file)
1594 {
1595 file->next = NULL;
1596 *zip->empty_list.last = file;
1597 zip->empty_list.last = &(file->next);
1598 }
1599
1600 static void
file_init_register_empty(struct _7zip * zip)1601 file_init_register_empty(struct _7zip *zip)
1602 {
1603 zip->empty_list.first = NULL;
1604 zip->empty_list.last = &(zip->empty_list.first);
1605 }
1606
1607 #if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\
1608 !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
1609 static int
compression_unsupported_encoder(struct archive * a,struct la_zstream * lastrm,const char * name)1610 compression_unsupported_encoder(struct archive *a,
1611 struct la_zstream *lastrm, const char *name)
1612 {
1613
1614 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1615 "%s compression not supported on this platform", name);
1616 lastrm->valid = 0;
1617 lastrm->real_stream = NULL;
1618 return (ARCHIVE_FAILED);
1619 }
1620 #endif
1621
1622 /*
1623 * _7_COPY compressor.
1624 */
1625 static int
compression_init_encoder_copy(struct archive * a,struct la_zstream * lastrm)1626 compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
1627 {
1628
1629 if (lastrm->valid)
1630 compression_end(a, lastrm);
1631 lastrm->valid = 1;
1632 lastrm->code = compression_code_copy;
1633 lastrm->end = compression_end_copy;
1634 return (ARCHIVE_OK);
1635 }
1636
1637 static int
compression_code_copy(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)1638 compression_code_copy(struct archive *a,
1639 struct la_zstream *lastrm, enum la_zaction action)
1640 {
1641 size_t bytes;
1642
1643 (void)a; /* UNUSED */
1644 if (lastrm->avail_out > lastrm->avail_in)
1645 bytes = lastrm->avail_in;
1646 else
1647 bytes = lastrm->avail_out;
1648 if (bytes) {
1649 memcpy(lastrm->next_out, lastrm->next_in, bytes);
1650 lastrm->next_in += bytes;
1651 lastrm->avail_in -= bytes;
1652 lastrm->total_in += bytes;
1653 lastrm->next_out += bytes;
1654 lastrm->avail_out -= bytes;
1655 lastrm->total_out += bytes;
1656 }
1657 if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
1658 return (ARCHIVE_EOF);
1659 return (ARCHIVE_OK);
1660 }
1661
1662 static int
compression_end_copy(struct archive * a,struct la_zstream * lastrm)1663 compression_end_copy(struct archive *a, struct la_zstream *lastrm)
1664 {
1665 (void)a; /* UNUSED */
1666 lastrm->valid = 0;
1667 return (ARCHIVE_OK);
1668 }
1669
1670 /*
1671 * _7_DEFLATE compressor.
1672 */
1673 #ifdef HAVE_ZLIB_H
1674 static int
compression_init_encoder_deflate(struct archive * a,struct la_zstream * lastrm,int level,int withheader)1675 compression_init_encoder_deflate(struct archive *a,
1676 struct la_zstream *lastrm, int level, int withheader)
1677 {
1678 z_stream *strm;
1679
1680 if (lastrm->valid)
1681 compression_end(a, lastrm);
1682 strm = calloc(1, sizeof(*strm));
1683 if (strm == NULL) {
1684 archive_set_error(a, ENOMEM,
1685 "Can't allocate memory for gzip stream");
1686 return (ARCHIVE_FATAL);
1687 }
1688 /* zlib.h is not const-correct, so we need this one bit
1689 * of ugly hackery to convert a const * pointer to
1690 * a non-const pointer. */
1691 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1692 strm->avail_in = (uInt)lastrm->avail_in;
1693 strm->total_in = (uLong)lastrm->total_in;
1694 strm->next_out = lastrm->next_out;
1695 strm->avail_out = (uInt)lastrm->avail_out;
1696 strm->total_out = (uLong)lastrm->total_out;
1697 if (deflateInit2(strm, level, Z_DEFLATED,
1698 (withheader)?15:-15,
1699 8, Z_DEFAULT_STRATEGY) != Z_OK) {
1700 free(strm);
1701 lastrm->real_stream = NULL;
1702 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1703 "Internal error initializing compression library");
1704 return (ARCHIVE_FATAL);
1705 }
1706 lastrm->real_stream = strm;
1707 lastrm->valid = 1;
1708 lastrm->code = compression_code_deflate;
1709 lastrm->end = compression_end_deflate;
1710 return (ARCHIVE_OK);
1711 }
1712
1713 static int
compression_code_deflate(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)1714 compression_code_deflate(struct archive *a,
1715 struct la_zstream *lastrm, enum la_zaction action)
1716 {
1717 z_stream *strm;
1718 int r;
1719
1720 strm = (z_stream *)lastrm->real_stream;
1721 /* zlib.h is not const-correct, so we need this one bit
1722 * of ugly hackery to convert a const * pointer to
1723 * a non-const pointer. */
1724 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1725 strm->avail_in = (uInt)lastrm->avail_in;
1726 strm->total_in = (uLong)lastrm->total_in;
1727 strm->next_out = lastrm->next_out;
1728 strm->avail_out = (uInt)lastrm->avail_out;
1729 strm->total_out = (uLong)lastrm->total_out;
1730 r = deflate(strm,
1731 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
1732 lastrm->next_in = strm->next_in;
1733 lastrm->avail_in = strm->avail_in;
1734 lastrm->total_in = strm->total_in;
1735 lastrm->next_out = strm->next_out;
1736 lastrm->avail_out = strm->avail_out;
1737 lastrm->total_out = strm->total_out;
1738 switch (r) {
1739 case Z_OK:
1740 return (ARCHIVE_OK);
1741 case Z_STREAM_END:
1742 return (ARCHIVE_EOF);
1743 default:
1744 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1745 "GZip compression failed:"
1746 " deflate() call returned status %d", r);
1747 return (ARCHIVE_FATAL);
1748 }
1749 }
1750
1751 static int
compression_end_deflate(struct archive * a,struct la_zstream * lastrm)1752 compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
1753 {
1754 z_stream *strm;
1755 int r;
1756
1757 strm = (z_stream *)lastrm->real_stream;
1758 r = deflateEnd(strm);
1759 free(strm);
1760 lastrm->real_stream = NULL;
1761 lastrm->valid = 0;
1762 if (r != Z_OK) {
1763 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1764 "Failed to clean up compressor");
1765 return (ARCHIVE_FATAL);
1766 }
1767 return (ARCHIVE_OK);
1768 }
1769 #else
1770 static int
compression_init_encoder_deflate(struct archive * a,struct la_zstream * lastrm,int level,int withheader)1771 compression_init_encoder_deflate(struct archive *a,
1772 struct la_zstream *lastrm, int level, int withheader)
1773 {
1774
1775 (void) level; /* UNUSED */
1776 (void) withheader; /* UNUSED */
1777 if (lastrm->valid)
1778 compression_end(a, lastrm);
1779 return (compression_unsupported_encoder(a, lastrm, "deflate"));
1780 }
1781 #endif
1782
1783 /*
1784 * _7_BZIP2 compressor.
1785 */
1786 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1787 static int
compression_init_encoder_bzip2(struct archive * a,struct la_zstream * lastrm,int level)1788 compression_init_encoder_bzip2(struct archive *a,
1789 struct la_zstream *lastrm, int level)
1790 {
1791 bz_stream *strm;
1792
1793 if (lastrm->valid)
1794 compression_end(a, lastrm);
1795 strm = calloc(1, sizeof(*strm));
1796 if (strm == NULL) {
1797 archive_set_error(a, ENOMEM,
1798 "Can't allocate memory for bzip2 stream");
1799 return (ARCHIVE_FATAL);
1800 }
1801 /* bzlib.h is not const-correct, so we need this one bit
1802 * of ugly hackery to convert a const * pointer to
1803 * a non-const pointer. */
1804 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1805 strm->avail_in = lastrm->avail_in;
1806 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1807 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1808 strm->next_out = (char *)lastrm->next_out;
1809 strm->avail_out = lastrm->avail_out;
1810 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1811 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1812 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
1813 free(strm);
1814 lastrm->real_stream = NULL;
1815 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1816 "Internal error initializing compression library");
1817 return (ARCHIVE_FATAL);
1818 }
1819 lastrm->real_stream = strm;
1820 lastrm->valid = 1;
1821 lastrm->code = compression_code_bzip2;
1822 lastrm->end = compression_end_bzip2;
1823 return (ARCHIVE_OK);
1824 }
1825
1826 static int
compression_code_bzip2(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)1827 compression_code_bzip2(struct archive *a,
1828 struct la_zstream *lastrm, enum la_zaction action)
1829 {
1830 bz_stream *strm;
1831 int r;
1832
1833 strm = (bz_stream *)lastrm->real_stream;
1834 /* bzlib.h is not const-correct, so we need this one bit
1835 * of ugly hackery to convert a const * pointer to
1836 * a non-const pointer. */
1837 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1838 strm->avail_in = lastrm->avail_in;
1839 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1840 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1841 strm->next_out = (char *)lastrm->next_out;
1842 strm->avail_out = lastrm->avail_out;
1843 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1844 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1845 r = BZ2_bzCompress(strm,
1846 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
1847 lastrm->next_in = (const unsigned char *)strm->next_in;
1848 lastrm->avail_in = strm->avail_in;
1849 lastrm->total_in =
1850 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
1851 + (uint64_t)(uint32_t)strm->total_in_lo32;
1852 lastrm->next_out = (unsigned char *)strm->next_out;
1853 lastrm->avail_out = strm->avail_out;
1854 lastrm->total_out =
1855 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
1856 + (uint64_t)(uint32_t)strm->total_out_lo32;
1857 switch (r) {
1858 case BZ_RUN_OK: /* Non-finishing */
1859 case BZ_FINISH_OK: /* Finishing: There's more work to do */
1860 return (ARCHIVE_OK);
1861 case BZ_STREAM_END: /* Finishing: all done */
1862 /* Only occurs in finishing case */
1863 return (ARCHIVE_EOF);
1864 default:
1865 /* Any other return value indicates an error */
1866 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1867 "Bzip2 compression failed:"
1868 " BZ2_bzCompress() call returned status %d", r);
1869 return (ARCHIVE_FATAL);
1870 }
1871 }
1872
1873 static int
compression_end_bzip2(struct archive * a,struct la_zstream * lastrm)1874 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
1875 {
1876 bz_stream *strm;
1877 int r;
1878
1879 strm = (bz_stream *)lastrm->real_stream;
1880 r = BZ2_bzCompressEnd(strm);
1881 free(strm);
1882 lastrm->real_stream = NULL;
1883 lastrm->valid = 0;
1884 if (r != BZ_OK) {
1885 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1886 "Failed to clean up compressor");
1887 return (ARCHIVE_FATAL);
1888 }
1889 return (ARCHIVE_OK);
1890 }
1891
1892 #else
1893 static int
compression_init_encoder_bzip2(struct archive * a,struct la_zstream * lastrm,int level)1894 compression_init_encoder_bzip2(struct archive *a,
1895 struct la_zstream *lastrm, int level)
1896 {
1897
1898 (void) level; /* UNUSED */
1899 if (lastrm->valid)
1900 compression_end(a, lastrm);
1901 return (compression_unsupported_encoder(a, lastrm, "bzip2"));
1902 }
1903 #endif
1904
1905 /*
1906 * _7_LZMA1, _7_LZMA2 compressor.
1907 */
1908 #if defined(HAVE_LZMA_H)
1909 static int
compression_init_encoder_lzma(struct archive * a,struct la_zstream * lastrm,int level,uint64_t filter_id)1910 compression_init_encoder_lzma(struct archive *a,
1911 struct la_zstream *lastrm, int level, uint64_t filter_id)
1912 {
1913 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
1914 lzma_stream *strm;
1915 lzma_filter *lzmafilters;
1916 lzma_options_lzma lzma_opt;
1917 int r;
1918
1919 if (lastrm->valid)
1920 compression_end(a, lastrm);
1921 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
1922 if (strm == NULL) {
1923 archive_set_error(a, ENOMEM,
1924 "Can't allocate memory for lzma stream");
1925 return (ARCHIVE_FATAL);
1926 }
1927 lzmafilters = (lzma_filter *)(strm+1);
1928 if (level > 6)
1929 level = 6;
1930 if (lzma_lzma_preset(&lzma_opt, level)) {
1931 free(strm);
1932 lastrm->real_stream = NULL;
1933 archive_set_error(a, ENOMEM,
1934 "Internal error initializing compression library");
1935 return (ARCHIVE_FATAL);
1936 }
1937 lzmafilters[0].id = filter_id;
1938 lzmafilters[0].options = &lzma_opt;
1939 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
1940
1941 r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
1942 if (r != LZMA_OK) {
1943 free(strm);
1944 lastrm->real_stream = NULL;
1945 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1946 "lzma_properties_size failed");
1947 return (ARCHIVE_FATAL);
1948 }
1949 if (lastrm->prop_size) {
1950 lastrm->props = malloc(lastrm->prop_size);
1951 if (lastrm->props == NULL) {
1952 free(strm);
1953 lastrm->real_stream = NULL;
1954 archive_set_error(a, ENOMEM,
1955 "Cannot allocate memory");
1956 return (ARCHIVE_FATAL);
1957 }
1958 r = lzma_properties_encode(lzmafilters, lastrm->props);
1959 if (r != LZMA_OK) {
1960 free(strm);
1961 lastrm->real_stream = NULL;
1962 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1963 "lzma_properties_encode failed");
1964 return (ARCHIVE_FATAL);
1965 }
1966 }
1967
1968 *strm = lzma_init_data;
1969 r = lzma_raw_encoder(strm, lzmafilters);
1970 switch (r) {
1971 case LZMA_OK:
1972 lastrm->real_stream = strm;
1973 lastrm->valid = 1;
1974 lastrm->code = compression_code_lzma;
1975 lastrm->end = compression_end_lzma;
1976 r = ARCHIVE_OK;
1977 break;
1978 case LZMA_MEM_ERROR:
1979 free(strm);
1980 lastrm->real_stream = NULL;
1981 archive_set_error(a, ENOMEM,
1982 "Internal error initializing compression library: "
1983 "Cannot allocate memory");
1984 r = ARCHIVE_FATAL;
1985 break;
1986 default:
1987 free(strm);
1988 lastrm->real_stream = NULL;
1989 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1990 "Internal error initializing compression library: "
1991 "It's a bug in liblzma");
1992 r = ARCHIVE_FATAL;
1993 break;
1994 }
1995 return (r);
1996 }
1997
1998 static int
compression_init_encoder_lzma1(struct archive * a,struct la_zstream * lastrm,int level)1999 compression_init_encoder_lzma1(struct archive *a,
2000 struct la_zstream *lastrm, int level)
2001 {
2002 return compression_init_encoder_lzma(a, lastrm, level,
2003 LZMA_FILTER_LZMA1);
2004 }
2005
2006 static int
compression_init_encoder_lzma2(struct archive * a,struct la_zstream * lastrm,int level)2007 compression_init_encoder_lzma2(struct archive *a,
2008 struct la_zstream *lastrm, int level)
2009 {
2010 return compression_init_encoder_lzma(a, lastrm, level,
2011 LZMA_FILTER_LZMA2);
2012 }
2013
2014 static int
compression_code_lzma(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)2015 compression_code_lzma(struct archive *a,
2016 struct la_zstream *lastrm, enum la_zaction action)
2017 {
2018 lzma_stream *strm;
2019 int r;
2020
2021 strm = (lzma_stream *)lastrm->real_stream;
2022 strm->next_in = lastrm->next_in;
2023 strm->avail_in = lastrm->avail_in;
2024 strm->total_in = lastrm->total_in;
2025 strm->next_out = lastrm->next_out;
2026 strm->avail_out = lastrm->avail_out;
2027 strm->total_out = lastrm->total_out;
2028 r = lzma_code(strm,
2029 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
2030 lastrm->next_in = strm->next_in;
2031 lastrm->avail_in = strm->avail_in;
2032 lastrm->total_in = strm->total_in;
2033 lastrm->next_out = strm->next_out;
2034 lastrm->avail_out = strm->avail_out;
2035 lastrm->total_out = strm->total_out;
2036 switch (r) {
2037 case LZMA_OK:
2038 /* Non-finishing case */
2039 return (ARCHIVE_OK);
2040 case LZMA_STREAM_END:
2041 /* This return can only occur in finishing case. */
2042 return (ARCHIVE_EOF);
2043 case LZMA_MEMLIMIT_ERROR:
2044 archive_set_error(a, ENOMEM,
2045 "lzma compression error:"
2046 " %ju MiB would have been needed",
2047 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
2048 / (1024 * 1024)));
2049 return (ARCHIVE_FATAL);
2050 default:
2051 /* Any other return value indicates an error */
2052 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2053 "lzma compression failed:"
2054 " lzma_code() call returned status %d", r);
2055 return (ARCHIVE_FATAL);
2056 }
2057 }
2058
2059 static int
compression_end_lzma(struct archive * a,struct la_zstream * lastrm)2060 compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
2061 {
2062 lzma_stream *strm;
2063
2064 (void)a; /* UNUSED */
2065 strm = (lzma_stream *)lastrm->real_stream;
2066 lzma_end(strm);
2067 free(strm);
2068 lastrm->valid = 0;
2069 lastrm->real_stream = NULL;
2070 return (ARCHIVE_OK);
2071 }
2072 #else
2073 static int
compression_init_encoder_lzma1(struct archive * a,struct la_zstream * lastrm,int level)2074 compression_init_encoder_lzma1(struct archive *a,
2075 struct la_zstream *lastrm, int level)
2076 {
2077
2078 (void) level; /* UNUSED */
2079 if (lastrm->valid)
2080 compression_end(a, lastrm);
2081 return (compression_unsupported_encoder(a, lastrm, "lzma"));
2082 }
2083 static int
compression_init_encoder_lzma2(struct archive * a,struct la_zstream * lastrm,int level)2084 compression_init_encoder_lzma2(struct archive *a,
2085 struct la_zstream *lastrm, int level)
2086 {
2087
2088 (void) level; /* UNUSED */
2089 if (lastrm->valid)
2090 compression_end(a, lastrm);
2091 return (compression_unsupported_encoder(a, lastrm, "lzma"));
2092 }
2093 #endif
2094
2095 /*
2096 * _7_PPMD compressor.
2097 */
2098 static void *
ppmd_alloc(void * p,size_t size)2099 ppmd_alloc(void *p, size_t size)
2100 {
2101 (void)p;
2102 return malloc(size);
2103 }
2104 static void
ppmd_free(void * p,void * address)2105 ppmd_free(void *p, void *address)
2106 {
2107 (void)p;
2108 free(address);
2109 }
2110 static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
2111 static void
ppmd_write(void * p,Byte b)2112 ppmd_write(void *p, Byte b)
2113 {
2114 struct archive_write *a = ((IByteOut *)p)->a;
2115 struct _7zip *zip = (struct _7zip *)(a->format_data);
2116 struct la_zstream *lastrm = &(zip->stream);
2117 struct ppmd_stream *strm;
2118
2119 if (lastrm->avail_out) {
2120 *lastrm->next_out++ = b;
2121 lastrm->avail_out--;
2122 lastrm->total_out++;
2123 return;
2124 }
2125 strm = (struct ppmd_stream *)lastrm->real_stream;
2126 if (strm->buff_ptr < strm->buff_end) {
2127 *strm->buff_ptr++ = b;
2128 strm->buff_bytes++;
2129 }
2130 }
2131
2132 static int
compression_init_encoder_ppmd(struct archive * a,struct la_zstream * lastrm,unsigned maxOrder,uint32_t msize)2133 compression_init_encoder_ppmd(struct archive *a,
2134 struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
2135 {
2136 struct ppmd_stream *strm;
2137 uint8_t *props;
2138 int r;
2139
2140 if (lastrm->valid)
2141 compression_end(a, lastrm);
2142 strm = calloc(1, sizeof(*strm));
2143 if (strm == NULL) {
2144 archive_set_error(a, ENOMEM,
2145 "Can't allocate memory for PPMd");
2146 return (ARCHIVE_FATAL);
2147 }
2148 strm->buff = malloc(32);
2149 if (strm->buff == NULL) {
2150 free(strm);
2151 archive_set_error(a, ENOMEM,
2152 "Can't allocate memory for PPMd");
2153 return (ARCHIVE_FATAL);
2154 }
2155 strm->buff_ptr = strm->buff;
2156 strm->buff_end = strm->buff + 32;
2157
2158 props = malloc(1+4);
2159 if (props == NULL) {
2160 free(strm->buff);
2161 free(strm);
2162 archive_set_error(a, ENOMEM,
2163 "Coludn't allocate memory for PPMd");
2164 return (ARCHIVE_FATAL);
2165 }
2166 props[0] = maxOrder;
2167 archive_le32enc(props+1, msize);
2168 __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
2169 r = __archive_ppmd7_functions.Ppmd7_Alloc(
2170 &strm->ppmd7_context, msize, &g_szalloc);
2171 if (r == 0) {
2172 free(strm->buff);
2173 free(strm);
2174 free(props);
2175 archive_set_error(a, ENOMEM,
2176 "Coludn't allocate memory for PPMd");
2177 return (ARCHIVE_FATAL);
2178 }
2179 __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
2180 strm->byteout.a = (struct archive_write *)a;
2181 strm->byteout.Write = ppmd_write;
2182 strm->range_enc.Stream = &(strm->byteout);
2183 __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
2184 strm->stat = 0;
2185
2186 lastrm->real_stream = strm;
2187 lastrm->valid = 1;
2188 lastrm->code = compression_code_ppmd;
2189 lastrm->end = compression_end_ppmd;
2190 lastrm->prop_size = 5;
2191 lastrm->props = props;
2192 return (ARCHIVE_OK);
2193 }
2194
2195 static int
compression_code_ppmd(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)2196 compression_code_ppmd(struct archive *a,
2197 struct la_zstream *lastrm, enum la_zaction action)
2198 {
2199 struct ppmd_stream *strm;
2200
2201 (void)a; /* UNUSED */
2202
2203 strm = (struct ppmd_stream *)lastrm->real_stream;
2204
2205 /* Copy encoded data if there are remaining bytes from previous call. */
2206 if (strm->buff_bytes) {
2207 uint8_t *p = strm->buff_ptr - strm->buff_bytes;
2208 while (lastrm->avail_out && strm->buff_bytes) {
2209 *lastrm->next_out++ = *p++;
2210 lastrm->avail_out--;
2211 lastrm->total_out++;
2212 strm->buff_bytes--;
2213 }
2214 if (strm->buff_bytes)
2215 return (ARCHIVE_OK);
2216 if (strm->stat == 1)
2217 return (ARCHIVE_EOF);
2218 strm->buff_ptr = strm->buff;
2219 }
2220 while (lastrm->avail_in && lastrm->avail_out) {
2221 __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
2222 &(strm->ppmd7_context), &(strm->range_enc),
2223 *lastrm->next_in++);
2224 lastrm->avail_in--;
2225 lastrm->total_in++;
2226 }
2227 if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
2228 __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
2229 &(strm->range_enc));
2230 strm->stat = 1;
2231 /* Return EOF if there are no remaining bytes. */
2232 if (strm->buff_bytes == 0)
2233 return (ARCHIVE_EOF);
2234 }
2235 return (ARCHIVE_OK);
2236 }
2237
2238 static int
compression_end_ppmd(struct archive * a,struct la_zstream * lastrm)2239 compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
2240 {
2241 struct ppmd_stream *strm;
2242
2243 (void)a; /* UNUSED */
2244
2245 strm = (struct ppmd_stream *)lastrm->real_stream;
2246 __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
2247 free(strm->buff);
2248 free(strm);
2249 lastrm->real_stream = NULL;
2250 lastrm->valid = 0;
2251 return (ARCHIVE_OK);
2252 }
2253
2254 /*
2255 * Universal compressor initializer.
2256 */
2257 static int
_7z_compression_init_encoder(struct archive_write * a,unsigned compression,int compression_level)2258 _7z_compression_init_encoder(struct archive_write *a, unsigned compression,
2259 int compression_level)
2260 {
2261 struct _7zip *zip;
2262 int r;
2263
2264 zip = (struct _7zip *)a->format_data;
2265 switch (compression) {
2266 case _7Z_DEFLATE:
2267 r = compression_init_encoder_deflate(
2268 &(a->archive), &(zip->stream),
2269 compression_level, 0);
2270 break;
2271 case _7Z_BZIP2:
2272 r = compression_init_encoder_bzip2(
2273 &(a->archive), &(zip->stream),
2274 compression_level);
2275 break;
2276 case _7Z_LZMA1:
2277 r = compression_init_encoder_lzma1(
2278 &(a->archive), &(zip->stream),
2279 compression_level);
2280 break;
2281 case _7Z_LZMA2:
2282 r = compression_init_encoder_lzma2(
2283 &(a->archive), &(zip->stream),
2284 compression_level);
2285 break;
2286 case _7Z_PPMD:
2287 r = compression_init_encoder_ppmd(
2288 &(a->archive), &(zip->stream),
2289 PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
2290 break;
2291 case _7Z_COPY:
2292 default:
2293 r = compression_init_encoder_copy(
2294 &(a->archive), &(zip->stream));
2295 break;
2296 }
2297 if (r == ARCHIVE_OK) {
2298 zip->stream.total_in = 0;
2299 zip->stream.next_out = zip->wbuff;
2300 zip->stream.avail_out = sizeof(zip->wbuff);
2301 zip->stream.total_out = 0;
2302 }
2303
2304 return (r);
2305 }
2306
2307 static int
compression_code(struct archive * a,struct la_zstream * lastrm,enum la_zaction action)2308 compression_code(struct archive *a, struct la_zstream *lastrm,
2309 enum la_zaction action)
2310 {
2311 if (lastrm->valid)
2312 return (lastrm->code(a, lastrm, action));
2313 return (ARCHIVE_OK);
2314 }
2315
2316 static int
compression_end(struct archive * a,struct la_zstream * lastrm)2317 compression_end(struct archive *a, struct la_zstream *lastrm)
2318 {
2319 if (lastrm->valid) {
2320 lastrm->prop_size = 0;
2321 free(lastrm->props);
2322 lastrm->props = NULL;
2323 return (lastrm->end(a, lastrm));
2324 }
2325 return (ARCHIVE_OK);
2326 }
2327
2328
2329