1 /* zip.c -- IO on .zip files using zlib
2 Version 1.2.0, September 16th, 2017
3 part of the MiniZip project
5 Copyright (C) 2010-2017 Nathan Moinvaziri
6 Modifications for AES, PKWARE disk spanning
7 https://github.com/nmoinvaz/minizip
8 Copyright (C) 2009-2010 Mathias Svensson
9 Modifications for Zip64 support
11 Copyright (C) 1998-2010 Gilles Vollant
12 http://www.winimage.com/zLibDll/minizip.html
14 This program is distributed under the terms of the same license as zlib.
15 See the accompanying LICENSE file for the full text of the license.
28 # define AES_METHOD (99)
29 # define AES_PWVERIFYSIZE (2)
30 # define AES_AUTHCODESIZE (10)
31 # define AES_MAXSALTLENGTH (16)
32 # define AES_VERSION (0x0001)
33 # define AES_ENCRYPTIONMODE (0x03)
36 # include "aes/fileenc.h"
37 # include "aes/prng.h"
39 #ifdef HAVE_APPLE_COMPRESSION
40 # include <compression.h>
47 #define SIZEDATA_INDATABLOCK (4096-(4*4))
49 #define DISKHEADERMAGIC (0x08074b50)
50 #define LOCALHEADERMAGIC (0x04034b50)
51 #define CENTRALHEADERMAGIC (0x02014b50)
52 #define ENDHEADERMAGIC (0x06054b50)
53 #define ZIP64ENDHEADERMAGIC (0x06064b50)
54 #define ZIP64ENDLOCHEADERMAGIC (0x07064b50)
55 #define DATADESCRIPTORMAGIC (0x08074b50)
57 #define FLAG_LOCALHEADER_OFFSET (0x06)
58 #define CRC_LOCALHEADER_OFFSET (0x0e)
60 #define SIZECENTRALHEADER (0x2e) /* 46 */
61 #define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */
62 #define SIZECENTRALDIRITEM (0x2e)
63 #define SIZEZIPLOCALHEADER (0x1e)
65 #ifndef BUFREADCOMMENT
66 # define BUFREADCOMMENT (0x400)
69 # define VERSIONMADEBY (0x0) /* platform dependent */
73 # define Z_BUFSIZE (UINT16_MAX)
77 # define ALLOC(size) (malloc(size))
80 # define TRYFREE(p) {if (p) free(p);}
83 /* NOT sure that this work on ALL platform */
84 #define MAKEULONG64(a, b) ((uint64_t)(((unsigned long)(a)) | ((uint64_t)((unsigned long)(b))) << 32))
87 # if MAX_MEM_LEVEL >= 8
88 # define DEF_MEM_LEVEL 8
90 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
94 const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
96 typedef struct linkedlist_datablock_internal_s
98 struct linkedlist_datablock_internal_s *next_datablock;
99 uint32_t avail_in_this_block;
100 uint32_t filled_in_this_block;
101 uint32_t unused; /* for future use and alignment */
102 uint8_t data[SIZEDATA_INDATABLOCK];
103 } linkedlist_datablock_internal;
105 typedef struct linkedlist_data_s
107 linkedlist_datablock_internal *first_block;
108 linkedlist_datablock_internal *last_block;
113 z_stream stream; /* zLib stream structure for inflate */
115 bz_stream bstream; /* bzLib stream structure for bziped */
117 #ifdef HAVE_APPLE_COMPRESSION
118 compression_stream astream; /* libcompression stream structure */
124 int stream_initialised; /* 1 is stream is initialized */
125 uint32_t pos_in_buffered_data; /* last written byte in buffered_data */
127 uint64_t pos_local_header; /* offset of the local header of the file currently writing */
128 char *central_header; /* central header data for the current file */
129 uint16_t size_centralextra;
130 uint16_t size_centralheader; /* size of the central header for cur file */
131 uint16_t size_centralextrafree; /* Extra bytes allocated to the central header but that are not used */
132 uint16_t size_comment;
133 uint16_t flag; /* flag of the file currently writing */
135 uint16_t method; /* compression method written to file.*/
136 uint16_t compression_method; /* compression method to use */
137 int raw; /* 1 for directly writing raw data */
138 uint8_t buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/
141 int zip64; /* add ZIP64 extended information in the extra field */
142 uint32_t number_disk; /* number of current disk used for spanning ZIP */
143 uint64_t total_compressed;
144 uint64_t total_uncompressed;
146 uint32_t keys[3]; /* keys defining the pseudo-random sequence */
147 const z_crc_t *pcrc_32_tab;
153 zlib_filefunc64_32_def z_filefunc;
154 voidpf filestream; /* io structure of the zipfile */
155 voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */
156 linkedlist_data central_dir; /* datablock with central dir in construction*/
157 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
158 int append; /* append mode */
159 curfile64_info ci; /* info on the file currently writing */
161 uint64_t add_position_when_writting_offset;
162 uint64_t number_entry;
163 uint64_t disk_size; /* size of each disk */
164 uint32_t number_disk; /* number of the current disk, used for spanning ZIP */
165 uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
166 #ifndef NO_ADDFILEINEXISTINGZIP
171 /* Allocate a new data block */
172 static linkedlist_datablock_internal *allocate_new_datablock(void)
174 linkedlist_datablock_internal *ldi = NULL;
176 ldi = (linkedlist_datablock_internal*)ALLOC(sizeof(linkedlist_datablock_internal));
180 ldi->next_datablock = NULL;
181 ldi->filled_in_this_block = 0;
182 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;
187 /* Free data block in linked list */
188 static void free_datablock(linkedlist_datablock_internal *ldi)
192 linkedlist_datablock_internal *ldinext = ldi->next_datablock;
198 /* Initialize linked list */
199 static void init_linkedlist(linkedlist_data *ll)
201 ll->first_block = ll->last_block = NULL;
204 /* Free entire linked list and all data blocks */
205 static void free_linkedlist(linkedlist_data *ll)
207 free_datablock(ll->first_block);
208 ll->first_block = ll->last_block = NULL;
211 /* Add data to linked list data block */
212 static int add_data_in_datablock(linkedlist_data *ll, const void *buf, uint32_t len)
214 linkedlist_datablock_internal *ldi = NULL;
215 const unsigned char *from_copy = NULL;
218 return ZIP_INTERNALERROR;
220 if (ll->last_block == NULL)
222 ll->first_block = ll->last_block = allocate_new_datablock();
223 if (ll->first_block == NULL)
224 return ZIP_INTERNALERROR;
227 ldi = ll->last_block;
228 from_copy = (unsigned char*)buf;
232 uint32_t copy_this = 0;
234 unsigned char *to_copy = NULL;
236 if (ldi->avail_in_this_block == 0)
238 ldi->next_datablock = allocate_new_datablock();
239 if (ldi->next_datablock == NULL)
240 return ZIP_INTERNALERROR;
241 ldi = ldi->next_datablock ;
242 ll->last_block = ldi;
245 if (ldi->avail_in_this_block < len)
246 copy_this = ldi->avail_in_this_block;
250 to_copy = &(ldi->data[ldi->filled_in_this_block]);
252 for (i = 0; i < copy_this; i++)
253 *(to_copy+i) = *(from_copy+i);
255 ldi->filled_in_this_block += copy_this;
256 ldi->avail_in_this_block -= copy_this;
257 from_copy += copy_this;
263 /* Inputs a long in LSB order to the given file: nbByte == 1, 2 ,4 or 8 (byte, short or long, uint64_t) */
264 static int zipWriteValue(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
265 uint64_t x, uint32_t len)
267 unsigned char buf[8];
270 for (n = 0; n < len; n++)
272 buf[n] = (unsigned char)(x & 0xff);
278 /* Data overflow - hack for ZIP64 (X Roche) */
279 for (n = 0; n < len; n++)
285 if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, len) != len)
291 static void zipWriteValueToMemory(void* dest, uint64_t x, uint32_t len)
293 unsigned char *buf = (unsigned char*)dest;
296 for (n = 0; n < len; n++)
298 buf[n] = (unsigned char)(x & 0xff);
304 /* data overflow - hack for ZIP64 */
305 for (n = 0; n < len; n++)
312 static void zipWriteValueToMemoryAndMove(unsigned char **dest_ptr, uint64_t x, uint32_t len)
314 zipWriteValueToMemory(*dest_ptr, x, len);
318 static int zipReadUInt8(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint8_t *value)
321 if (ZREAD64(*pzlib_filefunc_def, filestream, &c, 1) == 1)
326 if (ZERROR64(*pzlib_filefunc_def, filestream))
331 static int zipReadUInt16(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint16_t *value)
337 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
340 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
341 x += ((uint16_t)c) << 8;
350 static int zipReadUInt32(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint32_t *value)
356 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
359 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
360 x += ((uint32_t)c) << 8;
362 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
363 x += ((uint32_t)c) << 16;
365 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
366 x += ((uint32_t)c) << 24;
375 static int zipReadUInt64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint64_t *value)
381 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
384 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
385 x += ((uint64_t)c) << 8;
387 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
388 x += ((uint64_t)c) << 16;
390 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
391 x += ((uint64_t)c) << 24;
393 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
394 x += ((uint64_t)c) << 32;
396 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
397 x += ((uint64_t)c) << 40;
399 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
400 x += ((uint64_t)c) << 48;
402 err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
403 x += ((uint64_t)c) << 56;
413 /* Gets the amount of bytes left to write to the current disk for spanning archives */
414 static void zipGetDiskSizeAvailable(zipFile file, uint64_t *size_available)
416 zip64_internal *zi = NULL;
417 uint64_t current_disk_size = 0;
419 zi = (zip64_internal*)file;
420 ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
421 current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);
422 *size_available = zi->disk_size - current_disk_size;
425 /* Goes to a specific disk number for spanning archives */
426 static int zipGoToSpecificDisk(zipFile file, uint32_t number_disk, int open_existing)
428 zip64_internal *zi = NULL;
431 zi = (zip64_internal*)file;
432 if (zi->disk_size == 0)
435 if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))
436 ZCLOSE64(zi->z_filefunc, zi->filestream);
438 zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ?
439 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :
440 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));
442 if (zi->filestream == NULL)
448 /* Goes to the first disk in a spanned archive */
449 static int zipGoToFirstDisk(zipFile file)
451 zip64_internal *zi = NULL;
452 uint32_t number_disk_next = 0;
455 zi = (zip64_internal*)file;
457 if (zi->disk_size == 0)
459 number_disk_next = 0;
460 if (zi->number_disk_with_CD > 0)
461 number_disk_next = zi->number_disk_with_CD - 1;
462 err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
463 if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
464 err = zipGoToSpecificDisk(file, number_disk_next, 0);
466 zi->number_disk = number_disk_next;
467 ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
471 /* Goes to the next disk in a spanned archive */
472 static int zipGoToNextDisk(zipFile file)
474 zip64_internal *zi = NULL;
475 uint64_t size_available_in_disk = 0;
476 uint32_t number_disk_next = 0;
479 zi = (zip64_internal*)file;
480 if (zi->disk_size == 0)
483 number_disk_next = zi->number_disk + 1;
487 err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
488 if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
489 err = zipGoToSpecificDisk(file, number_disk_next, 0);
492 zipGetDiskSizeAvailable(file, &size_available_in_disk);
493 zi->number_disk = number_disk_next;
494 zi->number_disk_with_CD = zi->number_disk + 1;
496 number_disk_next += 1;
498 while (size_available_in_disk <= 0);
503 /* Locate the Central directory of a zipfile (at the end, just before the global comment) */
504 static uint64_t zipSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
506 unsigned char *buf = NULL;
507 uint64_t file_size = 0;
508 uint64_t back_read = 4;
509 uint64_t max_back = UINT16_MAX; /* maximum size of global comment */
510 uint64_t pos_found = 0;
511 uint32_t read_size = 0;
512 uint64_t read_pos = 0;
515 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
519 if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
525 file_size = ZTELL64(*pzlib_filefunc_def, filestream);
527 if (max_back > file_size)
528 max_back = file_size;
530 while (back_read < max_back)
532 if (back_read + BUFREADCOMMENT > max_back)
533 back_read = max_back;
535 back_read += BUFREADCOMMENT;
537 read_pos = file_size-back_read;
538 read_size = ((BUFREADCOMMENT+4) < (file_size - read_pos)) ?
539 (BUFREADCOMMENT+4) : (uint32_t)(file_size - read_pos);
541 if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
543 if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)
546 for (i = read_size-3; (i--) > 0;)
547 if ((*(buf+i)) == (ENDHEADERMAGIC & 0xff) &&
548 (*(buf+i+1)) == (ENDHEADERMAGIC >> 8 & 0xff) &&
549 (*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff) &&
550 (*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff))
552 pos_found = read_pos+i;
563 /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
564 static uint64_t zipSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
565 const uint64_t endcentraloffset)
568 uint32_t value32 = 0;
570 /* Zip64 end of central directory locator */
571 if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
574 /* Read locator signature */
575 if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
577 if (value32 != ZIP64ENDLOCHEADERMAGIC)
579 /* Number of the disk with the start of the zip64 end of central directory */
580 if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
582 /* Relative offset of the zip64 end of central directory record */
583 if (zipReadUInt64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK)
585 /* Total number of disks */
586 if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
588 /* Goto end of central directory record */
589 if (ZSEEK64(*pzlib_filefunc_def,filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
592 if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
594 if (value32 != ZIP64ENDHEADERMAGIC)
600 extern zipFile ZEXPORT zipOpen4(const void *path, int append, uint64_t disk_size, const char **globalcomment,
601 zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
603 zip64_internal ziinit;
604 zip64_internal *zi = NULL;
605 #ifndef NO_ADDFILEINEXISTINGZIP
606 uint64_t byte_before_the_zipfile = 0; /* byte before the zipfile, (>0 for sfx)*/
607 uint64_t size_central_dir = 0; /* size of the central directory */
608 uint64_t offset_central_dir = 0; /* offset of start of central directory */
609 uint64_t number_entry_CD = 0; /* total number of entries in the central dir */
610 uint64_t number_entry = 0;
611 uint64_t central_pos = 0;
612 uint64_t size_central_dir_to_read = 0;
613 uint16_t value16 = 0;
614 uint32_t value32 = 0;
615 uint16_t size_comment = 0;
616 size_t buf_size = SIZEDATA_INDATABLOCK;
617 void *buf_read = NULL;
622 ziinit.z_filefunc.zseek32_file = NULL;
623 ziinit.z_filefunc.ztell32_file = NULL;
625 if (pzlib_filefunc64_32_def == NULL)
626 fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
628 ziinit.z_filefunc = *pzlib_filefunc64_32_def;
630 if (append == APPEND_STATUS_CREATE)
631 mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE);
633 mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING);
635 ziinit.filestream = ZOPEN64(ziinit.z_filefunc, path, mode);
636 if (ziinit.filestream == NULL)
639 if (append == APPEND_STATUS_CREATEAFTER)
641 /* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */
645 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
648 ziinit.filestream_with_CD = ziinit.filestream;
649 ziinit.append = append;
650 ziinit.number_disk = 0;
651 ziinit.number_disk_with_CD = 0;
652 ziinit.disk_size = disk_size;
653 ziinit.in_opened_file_inzip = 0;
654 ziinit.ci.stream_initialised = 0;
655 ziinit.number_entry = 0;
656 ziinit.add_position_when_writting_offset = 0;
657 init_linkedlist(&(ziinit.central_dir));
659 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
662 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
666 #ifndef NO_ADDFILEINEXISTINGZIP
667 /* Add file in a zipfile */
668 ziinit.globalcomment = NULL;
669 if (append == APPEND_STATUS_ADDINZIP)
671 /* Read and Cache Central Directory Records */
672 central_pos = zipSearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
673 /* Disable to allow appending to empty ZIP archive (must be standard zip, not zip64)
674 if (central_pos == 0)
680 /* Read end of central directory info */
681 if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET) != 0)
684 /* The signature, already checked */
685 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
687 /* Number of this disk */
688 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
690 ziinit.number_disk = value16;
691 /* Number of the disk with the start of the central directory */
692 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
694 ziinit.number_disk_with_CD = value16;
695 /* Total number of entries in the central dir on this disk */
697 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
700 number_entry = value16;
701 /* Total number of entries in the central dir */
703 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
706 number_entry_CD = value16;
707 if (number_entry_CD!=number_entry)
708 err = ZIP_BADZIPFILE;
709 /* Size of the central directory */
710 size_central_dir = 0;
711 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
714 size_central_dir = value32;
715 /* Offset of start of central directory with respect to the starting disk number */
716 offset_central_dir = 0;
717 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
720 offset_central_dir = value32;
721 /* Zipfile global comment length */
722 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK)
725 if ((err == ZIP_OK) && ((number_entry_CD == UINT16_MAX) || (offset_central_dir == UINT32_MAX)))
727 /* Format should be Zip64, as the central directory or file size is too large */
728 central_pos = zipSearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos);
732 uint64_t sizeEndOfCentralDirectory;
734 if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
737 /* The signature, already checked */
738 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
740 /* Size of zip64 end of central directory record */
741 if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK)
743 /* Version made by */
744 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
746 /* Version needed to extract */
747 if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
749 /* Number of this disk */
750 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)
752 /* Number of the disk with the start of the central directory */
753 if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)
755 /* Total number of entries in the central directory on this disk */
756 if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK)
758 /* Total number of entries in the central directory */
759 if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK)
761 if (number_entry_CD!=number_entry)
762 err = ZIP_BADZIPFILE;
763 /* Size of the central directory */
764 if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK)
766 /* Offset of start of central directory with respect to the starting disk number */
767 if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK)
771 err = ZIP_BADZIPFILE;
775 if ((err == ZIP_OK) && (central_pos < offset_central_dir + size_central_dir))
776 err = ZIP_BADZIPFILE;
778 if ((err == ZIP_OK) && (size_comment > 0))
780 ziinit.globalcomment = (char*)ALLOC(size_comment+1);
781 if (ziinit.globalcomment)
783 if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment) != size_comment)
786 ziinit.globalcomment[size_comment] = 0;
792 ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
793 TRYFREE(ziinit.globalcomment);
798 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
799 ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
801 /* Store central directory in memory */
802 size_central_dir_to_read = size_central_dir;
803 buf_size = SIZEDATA_INDATABLOCK;
804 buf_read = (void*)ALLOC(buf_size);
806 if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
807 offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
810 while ((size_central_dir_to_read > 0) && (err == ZIP_OK))
812 uint64_t read_this = SIZEDATA_INDATABLOCK;
813 if (read_this > size_central_dir_to_read)
814 read_this = size_central_dir_to_read;
816 if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uint32_t)read_this) != read_this)
820 err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uint32_t)read_this);
822 size_central_dir_to_read -= read_this;
826 ziinit.number_entry = number_entry_CD;
828 if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
829 offset_central_dir+byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
834 *globalcomment = ziinit.globalcomment;
839 #ifndef NO_ADDFILEINEXISTINGZIP
840 TRYFREE(ziinit.globalcomment);
847 zipGoToFirstDisk((zipFile)zi);
851 extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment,
852 zlib_filefunc_def *pzlib_filefunc32_def)
854 if (pzlib_filefunc32_def != NULL)
856 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
857 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
858 return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
860 return zipOpen4(path, append, 0, globalcomment, NULL);
863 extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment,
864 zlib_filefunc64_def *pzlib_filefunc_def)
866 if (pzlib_filefunc_def != NULL)
868 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
869 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
870 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
871 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
872 return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
874 return zipOpen4(path, append, 0, globalcomment, NULL);
877 extern zipFile ZEXPORT zipOpen3(const char *path, int append, uint64_t disk_size, const char **globalcomment,
878 zlib_filefunc_def *pzlib_filefunc32_def)
880 if (pzlib_filefunc32_def != NULL)
882 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
883 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
884 return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
886 return zipOpen4(path, append, disk_size, globalcomment, NULL);
889 extern zipFile ZEXPORT zipOpen3_64(const void *path, int append, uint64_t disk_size, const char **globalcomment,
890 zlib_filefunc64_def *pzlib_filefunc_def)
892 if (pzlib_filefunc_def != NULL)
894 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
895 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
896 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
897 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
898 return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
900 return zipOpen4(path, append, disk_size, globalcomment, NULL);
903 extern zipFile ZEXPORT zipOpen(const char *path, int append)
905 return zipOpen3((const void*)path, append, 0, NULL, NULL);
908 extern zipFile ZEXPORT zipOpen64(const void *path, int append)
910 return zipOpen3(path, append, 0, NULL, NULL);
913 extern int ZEXPORT zipOpenNewFileInZip_internal(zipFile file,
914 const char *filename,
915 const zip_fileinfo *zipfi,
916 const void *extrafield_local,
917 uint16_t size_extrafield_local,
918 const void *extrafield_global,
919 uint16_t size_extrafield_global,
929 const char *password,
931 uint16_t version_madeby)
933 zip64_internal *zi = NULL;
934 uint64_t size_available = 0;
935 uint64_t size_needed = 0;
936 uint16_t size_filename = 0;
937 uint16_t size_comment = 0;
939 unsigned char *central_dir = NULL;
943 if (password != NULL)
944 return ZIP_PARAMERROR;
948 return ZIP_PARAMERROR;
952 (method != Z_BZIP2ED) &&
954 (method != Z_DEFLATED))
955 return ZIP_PARAMERROR;
957 zi = (zip64_internal*)file;
959 if (zi->in_opened_file_inzip == 1)
961 err = zipCloseFileInZip (file);
966 if (filename == NULL)
969 size_comment = (uint16_t)strlen(comment);
971 size_filename = (uint16_t)strlen(filename);
977 if (zipfi->dos_date != 0)
978 zi->ci.dos_date = zipfi->dos_date;
981 zi->ci.method = method;
982 zi->ci.compression_method = method;
984 zi->ci.flag = flag_base | 8;
985 if ((level == 8) || (level == 9))
992 if (password != NULL)
997 zi->ci.method = AES_METHOD;
1005 if (zi->disk_size > 0)
1007 if ((zi->number_disk == 0) && (zi->number_entry == 0))
1008 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DISKHEADERMAGIC, 4);
1010 /* Make sure enough space available on current disk for local header */
1011 zipGetDiskSizeAvailable((zipFile)zi, &size_available);
1012 size_needed = 30 + size_filename + size_extrafield_local;
1014 if (zi->ci.method == AES_METHOD)
1017 if (size_available < size_needed)
1018 zipGoToNextDisk((zipFile)zi);
1021 zi->ci.zip64 = zip64;
1023 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream);
1024 if (zi->ci.pos_local_header >= UINT32_MAX)
1027 zi->ci.size_comment = size_comment;
1028 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global;
1029 zi->ci.size_centralextra = size_extrafield_global;
1030 zi->ci.size_centralextrafree = 32; /* Extra space reserved for ZIP64 extra info */
1032 if (zi->ci.method == AES_METHOD)
1033 zi->ci.size_centralextrafree += 11; /* Extra space reserved for AES extra info */
1035 zi->ci.central_header = (char*)ALLOC((uint32_t)zi->ci.size_centralheader + zi->ci.size_centralextrafree + size_comment);
1036 zi->ci.number_disk = zi->number_disk;
1038 /* Write central directory header */
1039 central_dir = (unsigned char*)zi->ci.central_header;
1040 zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)CENTRALHEADERMAGIC, 4);
1041 zipWriteValueToMemoryAndMove(¢ral_dir, version_madeby, 2);
1043 zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)45, 2);
1045 zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)20, 2);
1046 zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.flag, 2);
1047 zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.method, 2);
1048 zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.dos_date, 4);
1049 zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*crc*/
1050 zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*compr size*/
1051 zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*uncompr size*/
1052 zipWriteValueToMemoryAndMove(¢ral_dir, size_filename, 2);
1053 zipWriteValueToMemoryAndMove(¢ral_dir, size_extrafield_global, 2);
1054 zipWriteValueToMemoryAndMove(¢ral_dir, size_comment, 2);
1055 zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)zi->ci.number_disk, 2); /*disk nm start*/
1058 zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)0, 2);
1060 zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->internal_fa, 2);
1062 zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4);
1064 zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->external_fa, 4);
1065 if (zi->ci.pos_local_header >= UINT32_MAX)
1066 zipWriteValueToMemoryAndMove(¢ral_dir, UINT32_MAX, 4);
1068 zipWriteValueToMemoryAndMove(¢ral_dir,
1069 (uint32_t)(zi->ci.pos_local_header - zi->add_position_when_writting_offset), 4);
1071 for (i = 0; i < size_filename; i++)
1072 zi->ci.central_header[SIZECENTRALHEADER+i] = filename[i];
1073 for (i = 0; i < size_extrafield_global; i++)
1074 zi->ci.central_header[SIZECENTRALHEADER+size_filename+i] =
1075 ((const char*)extrafield_global)[i];
1077 /* Store comment at the end for later repositioning */
1078 for (i = 0; i < size_comment; i++)
1079 zi->ci.central_header[zi->ci.size_centralheader+
1080 zi->ci.size_centralextrafree+i] = comment[i];
1082 if (zi->ci.central_header == NULL)
1083 return ZIP_INTERNALERROR;
1085 /* Write the local header */
1087 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)LOCALHEADERMAGIC, 4);
1092 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2); /* version needed to extract */
1094 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)20, 2); /* version needed to extract */
1097 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.flag, 2);
1099 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.method, 2);
1101 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.dos_date, 4);
1103 /* CRC & compressed size & uncompressed size is in data descriptor */
1105 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* crc 32, unknown */
1107 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* compressed size, unknown */
1109 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* uncompressed size, unknown */
1111 err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_filename, 2);
1114 uint64_t size_extrafield = size_extrafield_local;
1116 if (zi->ci.method == AES_METHOD)
1117 size_extrafield += 11;
1119 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)size_extrafield, 2);
1121 if ((err == ZIP_OK) && (size_filename > 0))
1123 if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename)
1126 if ((err == ZIP_OK) && (size_extrafield_local > 0))
1128 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
1133 /* Write the AES extended info */
1134 if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD))
1136 int headerid = 0x9901;
1139 err = zipWriteValue(&zi->z_filefunc, zi->filestream, headerid, 2);
1141 err = zipWriteValue(&zi->z_filefunc, zi->filestream, datasize, 2);
1143 err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2);
1145 err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'A', 1);
1147 err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'E', 1);
1149 err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1);
1151 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2);
1156 zi->ci.stream_initialised = 0;
1157 zi->ci.pos_in_buffered_data = 0;
1158 zi->ci.total_compressed = 0;
1159 zi->ci.total_uncompressed = 0;
1162 zi->ci.bstream.avail_in = (uint16_t)0;
1163 zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
1164 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1165 zi->ci.bstream.total_in_hi32 = 0;
1166 zi->ci.bstream.total_in_lo32 = 0;
1167 zi->ci.bstream.total_out_hi32 = 0;
1168 zi->ci.bstream.total_out_lo32 = 0;
1171 zi->ci.stream.avail_in = (uint16_t)0;
1172 zi->ci.stream.avail_out = Z_BUFSIZE;
1173 zi->ci.stream.next_out = zi->ci.buffered_data;
1174 zi->ci.stream.total_in = 0;
1175 zi->ci.stream.total_out = 0;
1176 zi->ci.stream.data_type = Z_BINARY;
1178 if ((err == ZIP_OK) && (!zi->ci.raw))
1180 if (method == Z_DEFLATED)
1182 zi->ci.stream.zalloc = (alloc_func)0;
1183 zi->ci.stream.zfree = (free_func)0;
1184 zi->ci.stream.opaque = (voidpf)zi;
1187 windowBits = -windowBits;
1189 #ifdef HAVE_APPLE_COMPRESSION
1190 err = compression_stream_init(&zi->ci.astream, COMPRESSION_STREAM_ENCODE, COMPRESSION_ZLIB);
1191 if (err == COMPRESSION_STATUS_ERROR)
1196 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
1199 zi->ci.stream_initialised = Z_DEFLATED;
1201 else if (method == Z_BZIP2ED)
1204 zi->ci.bstream.bzalloc = 0;
1205 zi->ci.bstream.bzfree = 0;
1206 zi->ci.bstream.opaque = (voidpf)0;
1208 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35);
1210 zi->ci.stream_initialised = Z_BZIP2ED;
1216 if ((err == Z_OK) && (password != NULL))
1219 if (zi->ci.method == AES_METHOD)
1221 unsigned char passverify[AES_PWVERIFYSIZE];
1222 unsigned char saltvalue[AES_MAXSALTLENGTH];
1223 uint16_t saltlength = 0;
1225 if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3))
1228 saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE);
1230 prng_init(cryptrand, zi->ci.aes_rng);
1231 prng_rand(saltvalue, saltlength, zi->ci.aes_rng);
1232 prng_end(zi->ci.aes_rng);
1234 fcrypt_init(AES_ENCRYPTIONMODE, (uint8_t *)password, (uint32_t)strlen(password), saltvalue, passverify, &zi->ci.aes_ctx);
1236 if (ZWRITE64(zi->z_filefunc, zi->filestream, saltvalue, saltlength) != saltlength)
1238 if (ZWRITE64(zi->z_filefunc, zi->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)
1241 zi->ci.total_compressed += saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE;
1246 unsigned char buf_head[RAND_HEAD_LEN];
1247 uint32_t size_head = 0;
1248 uint8_t verify1 = 0;
1249 uint8_t verify2 = 0;
1251 zi->ci.pcrc_32_tab = get_crc_table();
1254 Info-ZIP modification to ZipCrypto format:
1255 If bit 3 of the general purpose bit flag is set, it uses high byte of 16-bit File Time.
1257 verify1 = (uint8_t)((zi->ci.dos_date >> 16) & 0xff);
1258 verify2 = (uint8_t)((zi->ci.dos_date >> 8) & 0xff);
1260 size_head = crypthead(password, buf_head, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, verify1, verify2);
1261 zi->ci.total_compressed += size_head;
1263 if (ZWRITE64(zi->z_filefunc, zi->filestream, buf_head, size_head) != size_head)
1270 zi->in_opened_file_inzip = 1;
1274 extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1275 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1276 uint16_t size_extrafield_global, const char *comment, uint16_t flag_base, int zip64, uint16_t method, int level, int raw,
1277 int windowBits, int memLevel, int strategy, const char *password, int aes)
1279 return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
1280 size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
1284 extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1285 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1286 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
1287 int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
1293 return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
1294 size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
1298 extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1299 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1300 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
1301 int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base)
1303 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1304 extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
1305 strategy, password, crc_for_crypting, version_madeby, flag_base, 0);
1308 extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1309 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1310 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
1311 int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting)
1313 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1314 extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
1315 strategy, password, crc_for_crypting, VERSIONMADEBY, 0, 0);
1318 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1319 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1320 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
1321 int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, int zip64)
1323 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1324 extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy,
1325 password, crc_for_crypting, VERSIONMADEBY, 0, zip64);
1328 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1329 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1330 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw)
1332 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1333 extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
1334 Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
1337 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1338 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1339 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int zip64)
1341 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1342 extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
1343 Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
1346 extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1347 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1348 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int zip64)
1350 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1351 extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
1352 Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
1355 extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
1356 const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
1357 uint16_t size_extrafield_global, const char *comment, uint16_t method, int level)
1359 return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
1360 extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
1361 Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
1364 /* Flushes the write buffer to disk */
1365 static int zipFlushWriteBuffer(zip64_internal *zi)
1367 uint64_t size_available = 0;
1368 uint32_t written = 0;
1369 uint32_t total_written = 0;
1371 uint32_t max_write = 0;
1374 if ((zi->ci.flag & 1) != 0)
1378 if (zi->ci.method == AES_METHOD)
1380 fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx);
1388 for (i = 0; i < zi->ci.pos_in_buffered_data; i++)
1389 zi->ci.buffered_data[i] = (uint8_t)zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t);
1394 write = zi->ci.pos_in_buffered_data;
1400 if (zi->disk_size > 0)
1402 zipGetDiskSizeAvailable((zipFile)zi, &size_available);
1404 if (size_available == 0)
1406 err = zipGoToNextDisk((zipFile)zi);
1411 if (size_available < (uint64_t)max_write)
1412 max_write = (uint32_t)size_available;
1415 written = ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write);
1416 if (written != max_write)
1422 total_written += written;
1427 zi->ci.total_compressed += zi->ci.pos_in_buffered_data;
1430 if (zi->ci.compression_method == Z_BZIP2ED)
1432 zi->ci.total_uncompressed += zi->ci.bstream.total_in_lo32;
1433 zi->ci.bstream.total_in_lo32 = 0;
1434 zi->ci.bstream.total_in_hi32 = 0;
1439 zi->ci.total_uncompressed += zi->ci.stream.total_in;
1440 zi->ci.stream.total_in = 0;
1443 zi->ci.pos_in_buffered_data = 0;
1448 extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len)
1450 zip64_internal *zi = NULL;
1454 return ZIP_PARAMERROR;
1455 zi = (zip64_internal*)file;
1457 if (zi->in_opened_file_inzip == 0)
1458 return ZIP_PARAMERROR;
1460 zi->ci.crc32 = (uint32_t)crc32(zi->ci.crc32, buf, len);
1463 if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw))
1465 zi->ci.bstream.next_in = (void*)buf;
1466 zi->ci.bstream.avail_in = len;
1469 while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0))
1471 if (zi->ci.bstream.avail_out == 0)
1473 err = zipFlushWriteBuffer(zi);
1475 zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
1476 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1480 uint32_t total_out_before_lo = zi->ci.bstream.total_out_lo32;
1481 uint32_t total_out_before_hi = zi->ci.bstream.total_out_hi32;
1483 err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
1485 zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before_lo);
1489 if (err == BZ_RUN_OK)
1495 zi->ci.stream.next_in = (uint8_t*)buf;
1496 zi->ci.stream.avail_in = len;
1498 while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0))
1500 if (zi->ci.stream.avail_out == 0)
1502 err = zipFlushWriteBuffer(zi);
1504 zi->ci.stream.avail_out = Z_BUFSIZE;
1505 zi->ci.stream.next_out = zi->ci.buffered_data;
1511 if ((zi->ci.compression_method == Z_DEFLATED) && (!zi->ci.raw))
1513 #ifdef HAVE_APPLE_COMPRESSION
1514 uLong total_out_before = zi->ci.stream.total_out;
1516 zi->ci.astream.src_ptr = zi->ci.stream.next_in;
1517 zi->ci.astream.src_size = zi->ci.stream.avail_in;
1518 zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
1519 zi->ci.astream.dst_size = zi->ci.stream.avail_out;
1521 compression_status status = 0;
1522 compression_stream_flags flags = 0;
1524 status = compression_stream_process(&zi->ci.astream, flags);
1526 uLong total_out_after = len - zi->ci.astream.src_size;
1528 zi->ci.stream.next_in = zi->ci.astream.src_ptr;
1529 zi->ci.stream.avail_in = zi->ci.astream.src_size;
1530 zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
1531 zi->ci.stream.avail_out = zi->ci.astream.dst_size;
1532 zi->ci.stream.total_in += total_out_after;
1533 //zi->ci.stream.total_out += copy_this;
1534 zi->ci.pos_in_buffered_data += total_out_after;
1536 if (status == COMPRESSION_STATUS_ERROR)
1537 err = ZIP_INTERNALERROR;
1539 uint32_t total_out_before = (uint32_t)zi->ci.stream.total_out;
1540 err = deflate(&zi->ci.stream, Z_NO_FLUSH);
1541 zi->ci.pos_in_buffered_data += (uint32_t)(zi->ci.stream.total_out - total_out_before);
1546 uint32_t copy_this = 0;
1548 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1549 copy_this = zi->ci.stream.avail_in;
1551 copy_this = zi->ci.stream.avail_out;
1553 for (i = 0; i < copy_this; i++)
1554 *(((char*)zi->ci.stream.next_out)+i) =
1555 *(((const char*)zi->ci.stream.next_in)+i);
1557 zi->ci.stream.avail_in -= copy_this;
1558 zi->ci.stream.avail_out -= copy_this;
1559 zi->ci.stream.next_in += copy_this;
1560 zi->ci.stream.next_out += copy_this;
1561 zi->ci.stream.total_in += copy_this;
1562 zi->ci.stream.total_out += copy_this;
1563 zi->ci.pos_in_buffered_data += copy_this;
1571 extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32)
1573 zip64_internal *zi = NULL;
1574 uint16_t extra_data_size = 0;
1576 unsigned char *extra_info = NULL;
1580 return ZIP_PARAMERROR;
1581 zi = (zip64_internal*)file;
1583 if (zi->in_opened_file_inzip == 0)
1584 return ZIP_PARAMERROR;
1585 zi->ci.stream.avail_in = 0;
1589 if (zi->ci.compression_method == Z_DEFLATED)
1591 while (err == ZIP_OK)
1593 uint32_t total_out_before = 0;
1595 if (zi->ci.stream.avail_out == 0)
1597 err = zipFlushWriteBuffer(zi);
1599 zi->ci.stream.avail_out = Z_BUFSIZE;
1600 zi->ci.stream.next_out = zi->ci.buffered_data;
1606 #ifdef HAVE_APPLE_COMPRESSION
1607 total_out_before = zi->ci.stream.total_out;
1609 zi->ci.astream.src_ptr = zi->ci.stream.next_in;
1610 zi->ci.astream.src_size = zi->ci.stream.avail_in;
1611 zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
1612 zi->ci.astream.dst_size = zi->ci.stream.avail_out;
1614 compression_status status = 0;
1615 status = compression_stream_process(&zi->ci.astream, COMPRESSION_STREAM_FINALIZE);
1617 uint32_t total_out_after = Z_BUFSIZE - zi->ci.astream.dst_size;
1619 zi->ci.stream.next_in = zi->ci.astream.src_ptr;
1620 zi->ci.stream.avail_in = zi->ci.astream.src_size;
1621 zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
1622 zi->ci.stream.avail_out = zi->ci.astream.dst_size;
1623 //zi->ci.stream.total_in += total_out_after;
1624 //zi->ci.stream.total_out += copy_this;
1625 zi->ci.pos_in_buffered_data += total_out_after;
1627 if (status == COMPRESSION_STATUS_ERROR)
1629 err = ZIP_INTERNALERROR;
1631 else if (status == COMPRESSION_STATUS_END)
1636 total_out_before = (uint32_t)zi->ci.stream.total_out;
1637 err = deflate(&zi->ci.stream, Z_FINISH);
1638 zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.stream.total_out - total_out_before);
1642 else if (zi->ci.compression_method == Z_BZIP2ED)
1646 while (err == BZ_FINISH_OK)
1648 uint32_t total_out_before = 0;
1650 if (zi->ci.bstream.avail_out == 0)
1652 err = zipFlushWriteBuffer(zi);
1654 zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
1655 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1658 total_out_before = zi->ci.bstream.total_out_lo32;
1659 err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
1660 if (err == BZ_STREAM_END)
1662 zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before);
1665 if (err == BZ_FINISH_OK)
1671 if (err == Z_STREAM_END)
1672 err = ZIP_OK; /* this is normal */
1674 if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK))
1676 err = zipFlushWriteBuffer(zi);
1680 if (zi->ci.method == AES_METHOD)
1682 unsigned char authcode[AES_AUTHCODESIZE];
1684 fcrypt_end(authcode, &zi->ci.aes_ctx);
1686 if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)
1693 if (zi->ci.compression_method == Z_DEFLATED)
1696 #ifdef HAVE_APPLE_COMPRESSION
1697 tmp_err = compression_stream_destroy(&zi->ci.astream);
1699 tmp_err = deflateEnd(&zi->ci.stream);
1703 zi->ci.stream_initialised = 0;
1706 else if (zi->ci.compression_method == Z_BZIP2ED)
1708 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
1711 zi->ci.stream_initialised = 0;
1715 crc32 = zi->ci.crc32;
1716 uncompressed_size = zi->ci.total_uncompressed;
1719 /* Write data descriptor */
1721 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DATADESCRIPTORMAGIC, 4);
1723 err = zipWriteValue(&zi->z_filefunc, zi->filestream, crc32, 4);
1727 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.total_compressed, 8);
1729 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)zi->ci.total_compressed, 4);
1734 err = zipWriteValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
1736 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)uncompressed_size, 4);
1739 /* Update crc and sizes to central directory */
1740 zipWriteValueToMemory(zi->ci.central_header + 16, crc32, 4); /* crc */
1741 if (zi->ci.total_compressed >= UINT32_MAX)
1742 zipWriteValueToMemory(zi->ci.central_header + 20, UINT32_MAX, 4); /* compr size */
1744 zipWriteValueToMemory(zi->ci.central_header + 20, zi->ci.total_compressed, 4); /* compr size */
1745 if (uncompressed_size >= UINT32_MAX)
1746 zipWriteValueToMemory(zi->ci.central_header + 24, UINT32_MAX, 4); /* uncompr size */
1748 zipWriteValueToMemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */
1749 if (zi->ci.stream.data_type == Z_ASCII)
1750 zipWriteValueToMemory(zi->ci.central_header + 36, (uint16_t)Z_ASCII, 2); /* internal file attrib */
1752 /* Add ZIP64 extra info field for uncompressed size */
1753 if (uncompressed_size >= UINT32_MAX)
1754 extra_data_size += 8;
1755 /* Add ZIP64 extra info field for compressed size */
1756 if (zi->ci.total_compressed >= UINT32_MAX)
1757 extra_data_size += 8;
1758 /* Add ZIP64 extra info field for relative offset to local file header of current file */
1759 if (zi->ci.pos_local_header >= UINT32_MAX)
1760 extra_data_size += 8;
1762 /* Add ZIP64 extra info header to central directory */
1763 if (extra_data_size > 0)
1765 if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
1766 return ZIP_BADZIPFILE;
1768 extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
1770 zipWriteValueToMemoryAndMove(&extra_info, 0x0001, 2);
1771 zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
1773 if (uncompressed_size >= UINT32_MAX)
1774 zipWriteValueToMemoryAndMove(&extra_info, uncompressed_size, 8);
1775 if (zi->ci.total_compressed >= UINT32_MAX)
1776 zipWriteValueToMemoryAndMove(&extra_info, zi->ci.total_compressed, 8);
1777 if (zi->ci.pos_local_header >= UINT32_MAX)
1778 zipWriteValueToMemoryAndMove(&extra_info, zi->ci.pos_local_header, 8);
1780 zi->ci.size_centralextrafree -= extra_data_size + 4;
1781 zi->ci.size_centralheader += extra_data_size + 4;
1782 zi->ci.size_centralextra += extra_data_size + 4;
1784 zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
1788 /* Write AES extra info header to central directory */
1789 if (zi->ci.method == AES_METHOD)
1791 extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
1792 extra_data_size = 7;
1794 if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
1795 return ZIP_BADZIPFILE;
1797 zipWriteValueToMemoryAndMove(&extra_info, 0x9901, 2);
1798 zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
1799 zipWriteValueToMemoryAndMove(&extra_info, AES_VERSION, 2);
1800 zipWriteValueToMemoryAndMove(&extra_info, 'A', 1);
1801 zipWriteValueToMemoryAndMove(&extra_info, 'E', 1);
1802 zipWriteValueToMemoryAndMove(&extra_info, AES_ENCRYPTIONMODE, 1);
1803 zipWriteValueToMemoryAndMove(&extra_info, zi->ci.compression_method, 2);
1805 zi->ci.size_centralextrafree -= extra_data_size + 4;
1806 zi->ci.size_centralheader += extra_data_size + 4;
1807 zi->ci.size_centralextra += extra_data_size + 4;
1809 zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
1812 /* Restore comment to correct position */
1813 for (i = 0; i < zi->ci.size_comment; i++)
1814 zi->ci.central_header[zi->ci.size_centralheader+i] =
1815 zi->ci.central_header[zi->ci.size_centralheader+zi->ci.size_centralextrafree+i];
1816 zi->ci.size_centralheader += zi->ci.size_comment;
1819 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, zi->ci.size_centralheader);
1821 free(zi->ci.central_header);
1824 zi->in_opened_file_inzip = 0;
1829 extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32)
1831 return zipCloseFileInZipRaw64(file, uncompressed_size, crc32);
1834 extern int ZEXPORT zipCloseFileInZip(zipFile file)
1836 return zipCloseFileInZipRaw(file, 0, 0);
1839 extern int ZEXPORT zipClose(zipFile file, const char *global_comment)
1841 return zipClose_64(file, global_comment);
1844 extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment)
1846 return zipClose2_64(file, global_comment, VERSIONMADEBY);
1849 extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby)
1851 zip64_internal *zi = NULL;
1852 uint32_t size_centraldir = 0;
1853 uint16_t size_global_comment = 0;
1854 uint64_t centraldir_pos_inzip = 0;
1856 uint64_t cd_pos = 0;
1861 return ZIP_PARAMERROR;
1862 zi = (zip64_internal*)file;
1864 if (zi->in_opened_file_inzip == 1)
1865 err = zipCloseFileInZip(file);
1867 #ifndef NO_ADDFILEINEXISTINGZIP
1868 if (global_comment == NULL)
1869 global_comment = zi->globalcomment;
1872 if (zi->filestream != zi->filestream_with_CD)
1874 if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)
1877 if (zi->disk_size > 0)
1878 zi->number_disk_with_CD = zi->number_disk + 1;
1879 zi->filestream = zi->filestream_with_CD;
1882 centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
1886 linkedlist_datablock_internal *ldi = zi->central_dir.first_block;
1889 if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0))
1891 write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block);
1892 if (write != ldi->filled_in_this_block)
1896 size_centraldir += ldi->filled_in_this_block;
1897 ldi = ldi->next_datablock;
1901 free_linkedlist(&(zi->central_dir));
1903 pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1905 /* Write the ZIP64 central directory header */
1906 if (pos >= UINT32_MAX || zi->number_entry > UINT32_MAX)
1908 uint64_t zip64_eocd_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
1909 uint32_t zip64_datasize = 44;
1911 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDHEADERMAGIC, 4);
1913 /* Size of this 'zip64 end of central directory' */
1915 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)zip64_datasize, 8);
1916 /* Version made by */
1918 err = zipWriteValue(&zi->z_filefunc, zi->filestream, version_madeby, 2);
1919 /* version needed */
1921 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2);
1922 /* Number of this disk */
1924 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
1925 /* Number of the disk with the start of the central directory */
1927 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
1928 /* Total number of entries in the central dir on this disk */
1930 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1931 /* Total number of entries in the central dir */
1933 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1934 /* Size of the central directory */
1936 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)size_centraldir, 8);
1940 /* Offset of start of central directory with respect to the starting disk number */
1941 cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1942 err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
1945 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDLOCHEADERMAGIC, 4);
1947 /* Number of the disk with the start of the central directory */
1949 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
1950 /* Relative offset to the Zip64EndOfCentralDirectory */
1953 cd_pos = zip64_eocd_pos_inzip - zi->add_position_when_writting_offset;
1954 err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
1956 /* Number of the disk with the start of the central directory */
1958 err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD + 1, 4);
1961 /* Write the central directory header */
1965 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ENDHEADERMAGIC, 4);
1966 /* Number of this disk */
1968 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
1969 /* Number of the disk with the start of the central directory */
1971 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
1972 /* Total number of entries in the central dir on this disk */
1975 if (zi->number_entry >= UINT16_MAX)
1976 err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
1978 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
1980 /* Total number of entries in the central dir */
1983 if (zi->number_entry >= UINT16_MAX)
1984 err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
1986 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
1988 /* Size of the central directory */
1990 err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_centraldir, 4);
1991 /* Offset of start of central directory with respect to the starting disk number */
1994 cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1995 if (pos >= UINT32_MAX)
1996 err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT32_MAX, 4);
1998 err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)cd_pos, 4);
2001 /* Write global comment */
2003 if (global_comment != NULL)
2004 size_global_comment = (uint16_t)strlen(global_comment);
2006 err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_global_comment, 2);
2007 if (err == ZIP_OK && size_global_comment > 0)
2009 if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment)
2013 if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK))
2016 #ifndef NO_ADDFILEINEXISTINGZIP
2017 TRYFREE(zi->globalcomment);