Fossil SCM

Source Blame History 2246 lines
7ef7284… drh 1 /* zip.c -- IO on .zip files using zlib
6ea30fb… florian 2 part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html )
7ef7284… drh 3
6ea30fb… florian 4 Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html )
7ef7284… drh 5
7ef7284… drh 6 Modifications for Zip64 support
6ea30fb… florian 7 Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com )
7ef7284… drh 8
7ef7284… drh 9 For more info read MiniZip_info.txt
7ef7284… drh 10
7ef7284… drh 11 Changes
7ef7284… drh 12 Oct-2009 - Mathias Svensson - Remove old C style function prototypes
7ef7284… drh 13 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
7ef7284… drh 14 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
7ef7284… drh 15 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
f1f1d6c… drh 16 It is used when recreating zip archive with RAW when deleting items from a zip.
e38d5e1… jan.nijtmans 17 ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
7ef7284… drh 18 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
7ef7284… drh 19 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
7ef7284… drh 20
7ef7284… drh 21 */
7ef7284… drh 22
7ef7284… drh 23
7ef7284… drh 24 #include <stdio.h>
7ef7284… drh 25 #include <stdlib.h>
7ef7284… drh 26 #include <string.h>
7ef7284… drh 27 #include <time.h>
6ea30fb… florian 28 #ifndef ZLIB_CONST
6ea30fb… florian 29 # define ZLIB_CONST
6ea30fb… florian 30 #endif
6ea30fb… florian 31 #ifdef ZLIB_DLL
6ea30fb… florian 32 # undef ZLIB_DLL
6ea30fb… florian 33 #endif
7ef7284… drh 34 #include "zlib.h"
7ef7284… drh 35 #include "zip.h"
7ef7284… drh 36
7ef7284… drh 37 #ifdef STDC
7ef7284… drh 38 # include <stddef.h>
7ef7284… drh 39 #endif
7ef7284… drh 40 #ifdef NO_ERRNO_H
7ef7284… drh 41 extern int errno;
7ef7284… drh 42 #else
7ef7284… drh 43 # include <errno.h>
7ef7284… drh 44 #endif
7ef7284… drh 45
7ef7284… drh 46
7ef7284… drh 47 #ifndef local
7ef7284… drh 48 # define local static
7ef7284… drh 49 #endif
7ef7284… drh 50 /* compile with -Dlocal if your debugger can't find static symbols */
7ef7284… drh 51
7ef7284… drh 52 #ifndef VERSIONMADEBY
f1f1d6c… drh 53 # define VERSIONMADEBY (0x0) /* platform dependent */
7ef7284… drh 54 #endif
7ef7284… drh 55
7ef7284… drh 56 #ifndef Z_BUFSIZE
6ea30fb… florian 57 #define Z_BUFSIZE (64*1024) /* (16384) */
7ef7284… drh 58 #endif
7ef7284… drh 59
7ef7284… drh 60 #ifndef Z_MAXFILENAMEINZIP
7ef7284… drh 61 #define Z_MAXFILENAMEINZIP (256)
7ef7284… drh 62 #endif
7ef7284… drh 63
7ef7284… drh 64 #ifndef ALLOC
7ef7284… drh 65 # define ALLOC(size) (malloc(size))
7ef7284… drh 66 #endif
7ef7284… drh 67
7ef7284… drh 68 /*
7ef7284… drh 69 #define SIZECENTRALDIRITEM (0x2e)
7ef7284… drh 70 #define SIZEZIPLOCALHEADER (0x1e)
7ef7284… drh 71 */
7ef7284… drh 72
7ef7284… drh 73 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
7ef7284… drh 74
7ef7284… drh 75
6ea30fb… florian 76 /* NOT sure that this work on ALL platform */
7ef7284… drh 77 #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
7ef7284… drh 78
7ef7284… drh 79 #ifndef SEEK_CUR
7ef7284… drh 80 #define SEEK_CUR 1
7ef7284… drh 81 #endif
7ef7284… drh 82
7ef7284… drh 83 #ifndef SEEK_END
7ef7284… drh 84 #define SEEK_END 2
7ef7284… drh 85 #endif
7ef7284… drh 86
7ef7284… drh 87 #ifndef SEEK_SET
7ef7284… drh 88 #define SEEK_SET 0
7ef7284… drh 89 #endif
7ef7284… drh 90
7ef7284… drh 91 #ifndef DEF_MEM_LEVEL
7ef7284… drh 92 #if MAX_MEM_LEVEL >= 8
7ef7284… drh 93 # define DEF_MEM_LEVEL 8
7ef7284… drh 94 #else
7ef7284… drh 95 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
7ef7284… drh 96 #endif
7ef7284… drh 97 #endif
6ea30fb… florian 98 const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - https://www.winimage.com/zLibDll/minizip.html";
7ef7284… drh 99
7ef7284… drh 100
7ef7284… drh 101 #define SIZEDATA_INDATABLOCK (4096-(4*4))
7ef7284… drh 102
7ef7284… drh 103 #define LOCALHEADERMAGIC (0x04034b50)
7ef7284… drh 104 #define CENTRALHEADERMAGIC (0x02014b50)
7ef7284… drh 105 #define ENDHEADERMAGIC (0x06054b50)
7ef7284… drh 106 #define ZIP64ENDHEADERMAGIC (0x6064b50)
7ef7284… drh 107 #define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
7ef7284… drh 108
7ef7284… drh 109 #define FLAG_LOCALHEADER_OFFSET (0x06)
7ef7284… drh 110 #define CRC_LOCALHEADER_OFFSET (0x0e)
7ef7284… drh 111
7ef7284… drh 112 #define SIZECENTRALHEADER (0x2e) /* 46 */
7ef7284… drh 113
7ef7284… drh 114 typedef struct linkedlist_datablock_internal_s
7ef7284… drh 115 {
7ef7284… drh 116 struct linkedlist_datablock_internal_s* next_datablock;
7ef7284… drh 117 uLong avail_in_this_block;
7ef7284… drh 118 uLong filled_in_this_block;
e38d5e1… jan.nijtmans 119 uLong unused; /* for future use and alignment */
7ef7284… drh 120 unsigned char data[SIZEDATA_INDATABLOCK];
7ef7284… drh 121 } linkedlist_datablock_internal;
7ef7284… drh 122
7ef7284… drh 123 typedef struct linkedlist_data_s
7ef7284… drh 124 {
7ef7284… drh 125 linkedlist_datablock_internal* first_block;
7ef7284… drh 126 linkedlist_datablock_internal* last_block;
7ef7284… drh 127 } linkedlist_data;
6ea30fb… florian 128
6ea30fb… florian 129
6ea30fb… florian 130 /* zipAlreadyThere() set functions for a set of zero-terminated strings, and
6ea30fb… florian 131 // a block_t type for reading the central directory datablocks. */
6ea30fb… florian 132 typedef char *set_key_t;
6ea30fb… florian 133 #define set_cmp(a, b) strcmp(a, b)
6ea30fb… florian 134 #define set_drop(s, k) set_free(s, k)
6ea30fb… florian 135 #include "skipset.h"
6ea30fb… florian 136 typedef struct {
6ea30fb… florian 137 unsigned char *next; /* next byte in datablock data */
6ea30fb… florian 138 size_t left; /* number of bytes left in data (at least) */
6ea30fb… florian 139 linkedlist_datablock_internal *node; /* current datablock */
6ea30fb… florian 140 } block_t;
f1f1d6c… drh 141
f1f1d6c… drh 142
7ef7284… drh 143 typedef struct
7ef7284… drh 144 {
7ef7284… drh 145 z_stream stream; /* zLib stream structure for inflate */
7ef7284… drh 146 #ifdef HAVE_BZIP2
7ef7284… drh 147 bz_stream bstream; /* bzLib stream structure for bziped */
7ef7284… drh 148 #endif
7ef7284… drh 149
7ef7284… drh 150 int stream_initialised; /* 1 is stream is initialised */
7ef7284… drh 151 uInt pos_in_buffered_data; /* last written byte in buffered_data */
7ef7284… drh 152
7ef7284… drh 153 ZPOS64_T pos_local_header; /* offset of the local header of the file
f1f1d6c… drh 154 currently writing */
7ef7284… drh 155 char* central_header; /* central header data for the current file */
7ef7284… drh 156 uLong size_centralExtra;
7ef7284… drh 157 uLong size_centralheader; /* size of the central header for cur file */
7ef7284… drh 158 uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
7ef7284… drh 159 uLong flag; /* flag of the file currently writing */
7ef7284… drh 160
f1f1d6c… drh 161 int method; /* compression method of file currently wr.*/
7ef7284… drh 162 int raw; /* 1 for directly writing raw data */
7ef7284… drh 163 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
7ef7284… drh 164 uLong dosDate;
7ef7284… drh 165 uLong crc32;
7ef7284… drh 166 int encrypt;
f1f1d6c… drh 167 int zip64; /* Add ZIP64 extended information in the extra field */
7ef7284… drh 168 ZPOS64_T pos_zip64extrainfo;
7ef7284… drh 169 ZPOS64_T totalCompressedData;
7ef7284… drh 170 ZPOS64_T totalUncompressedData;
7ef7284… drh 171 #ifndef NOCRYPT
7ef7284… drh 172 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
bb4776e… jan.nijtmans 173 const z_crc_t* pcrc_32_tab;
adb9e8e… drh 174 unsigned crypt_header_size;
7ef7284… drh 175 #endif
7ef7284… drh 176 } curfile64_info;
7ef7284… drh 177
7ef7284… drh 178 typedef struct
7ef7284… drh 179 {
7ef7284… drh 180 zlib_filefunc64_32_def z_filefunc;
f1f1d6c… drh 181 voidpf filestream; /* io structure of the zipfile */
7ef7284… drh 182 linkedlist_data central_dir;/* datablock with central dir in construction*/
7ef7284… drh 183 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
f1f1d6c… drh 184 curfile64_info ci; /* info on the file currently writing */
7ef7284… drh 185
7ef7284… drh 186 ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
e38d5e1… jan.nijtmans 187 ZPOS64_T add_position_when_writing_offset;
7ef7284… drh 188 ZPOS64_T number_entry;
7ef7284… drh 189
7ef7284… drh 190 #ifndef NO_ADDFILEINEXISTINGZIP
7ef7284… drh 191 char *globalcomment;
7ef7284… drh 192 #endif
6ea30fb… florian 193
6ea30fb… florian 194 /* Support for zipAlreadyThere(). */
6ea30fb… florian 195 set_t set; /* set for detecting name collisions */
6ea30fb… florian 196 block_t block; /* block for reading the central directory */
f1f1d6c… drh 197
7ef7284… drh 198 } zip64_internal;
7ef7284… drh 199
7ef7284… drh 200
7ef7284… drh 201 #ifndef NOCRYPT
7ef7284… drh 202 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
7ef7284… drh 203 #include "crypt.h"
7ef7284… drh 204 #endif
7ef7284… drh 205
f1f1d6c… drh 206 local linkedlist_datablock_internal* allocate_new_datablock(void) {
7ef7284… drh 207 linkedlist_datablock_internal* ldi;
7ef7284… drh 208 ldi = (linkedlist_datablock_internal*)
7ef7284… drh 209 ALLOC(sizeof(linkedlist_datablock_internal));
7ef7284… drh 210 if (ldi!=NULL)
7ef7284… drh 211 {
7ef7284… drh 212 ldi->next_datablock = NULL ;
7ef7284… drh 213 ldi->filled_in_this_block = 0 ;
7ef7284… drh 214 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
7ef7284… drh 215 }
7ef7284… drh 216 return ldi;
7ef7284… drh 217 }
7ef7284… drh 218
f1f1d6c… drh 219 local void free_datablock(linkedlist_datablock_internal* ldi) {
7ef7284… drh 220 while (ldi!=NULL)
7ef7284… drh 221 {
7ef7284… drh 222 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
f1f1d6c… drh 223 free(ldi);
7ef7284… drh 224 ldi = ldinext;
7ef7284… drh 225 }
7ef7284… drh 226 }
7ef7284… drh 227
f1f1d6c… drh 228 local void init_linkedlist(linkedlist_data* ll) {
7ef7284… drh 229 ll->first_block = ll->last_block = NULL;
7ef7284… drh 230 }
7ef7284… drh 231
f1f1d6c… drh 232 local void free_linkedlist(linkedlist_data* ll) {
7ef7284… drh 233 free_datablock(ll->first_block);
7ef7284… drh 234 ll->first_block = ll->last_block = NULL;
7ef7284… drh 235 }
7ef7284… drh 236
7ef7284… drh 237
f1f1d6c… drh 238 local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) {
7ef7284… drh 239 linkedlist_datablock_internal* ldi;
7ef7284… drh 240 const unsigned char* from_copy;
7ef7284… drh 241
7ef7284… drh 242 if (ll==NULL)
7ef7284… drh 243 return ZIP_INTERNALERROR;
7ef7284… drh 244
7ef7284… drh 245 if (ll->last_block == NULL)
7ef7284… drh 246 {
7ef7284… drh 247 ll->first_block = ll->last_block = allocate_new_datablock();
7ef7284… drh 248 if (ll->first_block == NULL)
7ef7284… drh 249 return ZIP_INTERNALERROR;
7ef7284… drh 250 }
7ef7284… drh 251
7ef7284… drh 252 ldi = ll->last_block;
f1f1d6c… drh 253 from_copy = (const unsigned char*)buf;
7ef7284… drh 254
7ef7284… drh 255 while (len>0)
7ef7284… drh 256 {
7ef7284… drh 257 uInt copy_this;
7ef7284… drh 258 uInt i;
7ef7284… drh 259 unsigned char* to_copy;
7ef7284… drh 260
7ef7284… drh 261 if (ldi->avail_in_this_block==0)
7ef7284… drh 262 {
7ef7284… drh 263 ldi->next_datablock = allocate_new_datablock();
7ef7284… drh 264 if (ldi->next_datablock == NULL)
7ef7284… drh 265 return ZIP_INTERNALERROR;
7ef7284… drh 266 ldi = ldi->next_datablock ;
7ef7284… drh 267 ll->last_block = ldi;
7ef7284… drh 268 }
7ef7284… drh 269
7ef7284… drh 270 if (ldi->avail_in_this_block < len)
7ef7284… drh 271 copy_this = (uInt)ldi->avail_in_this_block;
7ef7284… drh 272 else
7ef7284… drh 273 copy_this = (uInt)len;
7ef7284… drh 274
7ef7284… drh 275 to_copy = &(ldi->data[ldi->filled_in_this_block]);
7ef7284… drh 276
7ef7284… drh 277 for (i=0;i<copy_this;i++)
7ef7284… drh 278 *(to_copy+i)=*(from_copy+i);
7ef7284… drh 279
7ef7284… drh 280 ldi->filled_in_this_block += copy_this;
7ef7284… drh 281 ldi->avail_in_this_block -= copy_this;
7ef7284… drh 282 from_copy += copy_this ;
7ef7284… drh 283 len -= copy_this;
7ef7284… drh 284 }
7ef7284… drh 285 return ZIP_OK;
7ef7284… drh 286 }
7ef7284… drh 287
6ea30fb… florian 288 /* zipAlreadyThere() operations. "set" in the zip internal structure keeps the
6ea30fb… florian 289 // set of names that are in the under-construction central directory so far. A
6ea30fb… florian 290 // skipset provides ~O(log n) time insertion and searching. Central directory
6ea30fb… florian 291 // records, stored in a linked list of allocated memory datablocks, is read
6ea30fb… florian 292 // through "block" in the zip internal structure.
6ea30fb… florian 293
6ea30fb… florian 294 // The block_*() functions support extracting the central directory file names
6ea30fb… florian 295 // from the datablocks. They are designed to support a growing directory by
6ea30fb… florian 296 // automatically continuing once more data has been appended to the linked
6ea30fb… florian 297 // datablocks.
6ea30fb… florian 298
6ea30fb… florian 299 // Initialize *block to the head of list. This should only be called once the
6ea30fb… florian 300 // list has at least some data in it, i.e. list->first_block is not NULL. */
6ea30fb… florian 301 local void block_init(block_t *block, linkedlist_data *list) {
6ea30fb… florian 302 block->node = list->first_block;
6ea30fb… florian 303 block->next = block->node->data;
6ea30fb… florian 304 block->left = block->node->filled_in_this_block;
6ea30fb… florian 305 }
6ea30fb… florian 306
6ea30fb… florian 307 /* Mark *block as bad, with all subsequent reads returning end, even if more
6ea30fb… florian 308 // data is added to the datablocks. This is invoked if the central directory is
6ea30fb… florian 309 // invalid, so there is no longer any point in attempting to interpret it. */
6ea30fb… florian 310 local void block_stop(block_t *block) {
6ea30fb… florian 311 block->left = 0;
6ea30fb… florian 312 block->next = NULL;
6ea30fb… florian 313 }
6ea30fb… florian 314
6ea30fb… florian 315 /* Return true if *block has reached the end of the data in the datablocks. */
6ea30fb… florian 316 local int block_end(block_t *block) {
6ea30fb… florian 317 linkedlist_datablock_internal *node = block->node;
6ea30fb… florian 318 if (node == NULL)
6ea30fb… florian 319 /* This block was previously terminated with extreme prejudice. */
6ea30fb… florian 320 return 1;
6ea30fb… florian 321 if (block->next < node->data + node->filled_in_this_block)
6ea30fb… florian 322 /* There are more bytes to read in the current datablock. */
6ea30fb… florian 323 return 0;
6ea30fb… florian 324 while (node->next_datablock != NULL) {
6ea30fb… florian 325 if (node->filled_in_this_block != 0)
6ea30fb… florian 326 /* There are some bytes in a later datablock. */
6ea30fb… florian 327 return 0;
6ea30fb… florian 328 node = node->next_datablock;
6ea30fb… florian 329 }
6ea30fb… florian 330 /* Reached the end of the list of datablocks. There's nothing. */
6ea30fb… florian 331 return 1;
6ea30fb… florian 332 }
6ea30fb… florian 333
6ea30fb… florian 334 /* Return one byte from *block, or -1 if the end is reached. */
6ea30fb… florian 335 local int block_get(block_t *block) {
6ea30fb… florian 336 while (block->left == 0) {
6ea30fb… florian 337 if (block->node == NULL)
6ea30fb… florian 338 /* We've been marked bad. Return end. */
6ea30fb… florian 339 return -1;
6ea30fb… florian 340 /* Update left in case more was filled in since we were last here. */
6ea30fb… florian 341 block->left = block->node->filled_in_this_block -
6ea30fb… florian 342 (size_t)(block->next - block->node->data);
6ea30fb… florian 343 if (block->left != 0)
6ea30fb… florian 344 /* There was indeed more data appended in the current datablock. */
6ea30fb… florian 345 break;
6ea30fb… florian 346 if (block->node->next_datablock == NULL)
6ea30fb… florian 347 /* No more data here, and there is no next datablock. At the end. */
6ea30fb… florian 348 return -1;
6ea30fb… florian 349 /* Try the next datablock for more data. */
6ea30fb… florian 350 block->node = block->node->next_datablock;
6ea30fb… florian 351 block->next = block->node->data;
6ea30fb… florian 352 block->left = block->node->filled_in_this_block;
6ea30fb… florian 353 }
6ea30fb… florian 354 /* We have a byte to return. */
6ea30fb… florian 355 block->left--;
6ea30fb… florian 356 return *block->next++;
6ea30fb… florian 357 }
6ea30fb… florian 358
6ea30fb… florian 359 /* Return a 16-bit unsigned little-endian value from block, or a negative value
6ea30fb… florian 360 // if the end is reached. */
6ea30fb… florian 361 local long block_get2(block_t *block) {
6ea30fb… florian 362 int low = block_get(block);
6ea30fb… florian 363 int high = block_get(block);
6ea30fb… florian 364 return low < 0 || high < 0 ? -1 : low | ((long)high << 8);
6ea30fb… florian 365 }
6ea30fb… florian 366
6ea30fb… florian 367 /* Read up to len bytes from block into buf. Return the number of bytes read. */
6ea30fb… florian 368 local size_t block_read(block_t *block, unsigned char *buf, size_t len) {
6ea30fb… florian 369 size_t need = len;
6ea30fb… florian 370 while (need) {
6ea30fb… florian 371 if (block->left == 0) {
6ea30fb… florian 372 /* Get a byte to update and step through the linked list as needed. */
6ea30fb… florian 373 int got = block_get(block);
6ea30fb… florian 374 if (got == -1)
6ea30fb… florian 375 /* Reached the end. */
6ea30fb… florian 376 break;
6ea30fb… florian 377 *buf++ = (unsigned char)got;
6ea30fb… florian 378 need--;
6ea30fb… florian 379 continue;
6ea30fb… florian 380 }
6ea30fb… florian 381 size_t take = need > block->left ? block->left : need;
6ea30fb… florian 382 memcpy(buf, block->next, take);
6ea30fb… florian 383 block->next += take;
6ea30fb… florian 384 block->left -= take;
6ea30fb… florian 385 buf += take;
6ea30fb… florian 386 need -= take;
6ea30fb… florian 387 }
6ea30fb… florian 388 return len - need; /* return the number of bytes copied */
6ea30fb… florian 389 }
6ea30fb… florian 390
6ea30fb… florian 391 /* Skip n bytes in block. Return 0 on success or -1 if there are less than n
6ea30fb… florian 392 // bytes to the end. */
6ea30fb… florian 393 local int block_skip(block_t *block, size_t n) {
6ea30fb… florian 394 while (n > block->left) {
6ea30fb… florian 395 n -= block->left;
6ea30fb… florian 396 block->next += block->left;
6ea30fb… florian 397 block->left = 0;
6ea30fb… florian 398 if (block_get(block) == -1)
6ea30fb… florian 399 return -1;
6ea30fb… florian 400 n--;
6ea30fb… florian 401 }
6ea30fb… florian 402 block->next += n;
6ea30fb… florian 403 block->left -= n;
6ea30fb… florian 404 return 0;
6ea30fb… florian 405 }
6ea30fb… florian 406
6ea30fb… florian 407 /* Process the next central directory record at *block. Return the allocated,
6ea30fb… florian 408 // zero-terminated file name, or NULL for end of input or invalid data. If
6ea30fb… florian 409 // invalid, *block is marked bad. This uses *set for the allocation of memory. */
6ea30fb… florian 410 local char *block_central_name(block_t *block, set_t *set) {
6ea30fb… florian 411 char *name = NULL;
6ea30fb… florian 412 for (;;) {
6ea30fb… florian 413 if (block_end(block))
6ea30fb… florian 414 /* At the end of the central directory (so far). */
6ea30fb… florian 415 return NULL;
6ea30fb… florian 416
6ea30fb… florian 417 /* Check for a central directory record signature. */
6ea30fb… florian 418 if (block_get2(block) != (CENTRALHEADERMAGIC & 0xffff) ||
6ea30fb… florian 419 block_get2(block) != (CENTRALHEADERMAGIC >> 16))
6ea30fb… florian 420 /* Incorrect signature. */
6ea30fb… florian 421 break;
6ea30fb… florian 422
6ea30fb… florian 423 /* Go through the remaining fixed-length portion of the record,
6ea30fb… florian 424 // extracting the lengths of the three variable-length fields. */
6ea30fb… florian 425 block_skip(block, 24);
6ea30fb… florian 426 unsigned flen = (unsigned)block_get2(block); /* file name length */
6ea30fb… florian 427 unsigned xlen = (unsigned)block_get2(block); /* extra length */
6ea30fb… florian 428 unsigned clen = (unsigned)block_get2(block); /* comment length */
6ea30fb… florian 429 if (block_skip(block, 12) == -1)
6ea30fb… florian 430 /* Premature end of the record. */
6ea30fb… florian 431 break;
6ea30fb… florian 432
6ea30fb… florian 433 /* Extract the name and skip over the extra and comment fields. */
6ea30fb… florian 434 name = set_alloc(set, NULL, flen + 1);
6ea30fb… florian 435 if (block_read(block, (unsigned char *)name, flen) < flen ||
6ea30fb… florian 436 block_skip(block, xlen + clen) == -1)
6ea30fb… florian 437 /* Premature end of the record. */
6ea30fb… florian 438 break;
6ea30fb… florian 439
6ea30fb… florian 440 /* Check for embedded nuls in the name. */
6ea30fb… florian 441 if (memchr(name, 0, flen) != NULL) {
6ea30fb… florian 442 /* This name can never match the zero-terminated name provided to
6ea30fb… florian 443 // zipAlreadyThere(), so we discard it and go back to get another
6ea30fb… florian 444 // name. (Who the heck is putting nuls inside their zip file entry
6ea30fb… florian 445 // names anyway?) */
6ea30fb… florian 446 set_free(set, name);
6ea30fb… florian 447 continue;
6ea30fb… florian 448 }
6ea30fb… florian 449
6ea30fb… florian 450 /* All good. Return the zero-terminated file name. */
6ea30fb… florian 451 name[flen] = 0;
6ea30fb… florian 452 return name;
6ea30fb… florian 453 }
6ea30fb… florian 454
6ea30fb… florian 455 /* Invalid signature or premature end of the central directory record.
6ea30fb… florian 456 // Abandon trying to process the central directory. */
6ea30fb… florian 457 set_free(set, name);
6ea30fb… florian 458 block_stop(block);
6ea30fb… florian 459 return NULL;
6ea30fb… florian 460 }
6ea30fb… florian 461
6ea30fb… florian 462 /* Return 0 if name is not in the central directory so far, 1 if it is, -1 if
6ea30fb… florian 463 // the central directory is invalid, -2 if out of memory, or ZIP_PARAMERROR if
6ea30fb… florian 464 // file is NULL. */
6ea30fb… florian 465 extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) {
6ea30fb… florian 466 zip64_internal *zip = file;
6ea30fb… florian 467 if (zip == NULL)
6ea30fb… florian 468 return ZIP_PARAMERROR;
6ea30fb… florian 469 if (zip->central_dir.first_block == NULL)
6ea30fb… florian 470 /* No central directory yet, so no, name isn't there. */
6ea30fb… florian 471 return 0;
6ea30fb… florian 472 if (setjmp(zip->set.env)) {
6ea30fb… florian 473 /* Memory allocation failure. */
6ea30fb… florian 474 set_end(&zip->set);
6ea30fb… florian 475 return -2;
6ea30fb… florian 476 }
6ea30fb… florian 477 if (!set_ok(&zip->set)) {
6ea30fb… florian 478 /* This is the first time here with some central directory content. We
6ea30fb… florian 479 // construct this set of names only on demand. Prepare set and block. */
6ea30fb… florian 480 set_start(&zip->set);
6ea30fb… florian 481 block_init(&zip->block, &zip->central_dir);
6ea30fb… florian 482 }
6ea30fb… florian 483
6ea30fb… florian 484 /* Update the set of names from the current central directory contents.
6ea30fb… florian 485 // This reads any new central directory records since the last time we were
6ea30fb… florian 486 // here. */
6ea30fb… florian 487 for (;;) {
6ea30fb… florian 488 char *there = block_central_name(&zip->block, &zip->set);
6ea30fb… florian 489 if (there == NULL) {
6ea30fb… florian 490 if (zip->block.next == NULL)
6ea30fb… florian 491 /* The central directory is invalid. */
6ea30fb… florian 492 return -1;
6ea30fb… florian 493 break;
6ea30fb… florian 494 }
6ea30fb… florian 495
6ea30fb… florian 496 /* Add there to the set. */
6ea30fb… florian 497 if (set_insert(&zip->set, there))
6ea30fb… florian 498 /* There's already a duplicate in the central directory! We'll just
6ea30fb… florian 499 // let this be and carry on. */
6ea30fb… florian 500 set_free(&zip->set, there);
6ea30fb… florian 501 }
6ea30fb… florian 502
6ea30fb… florian 503 /* Return true if name is in the central directory. */
6ea30fb… florian 504 size_t len = strlen(name);
6ea30fb… florian 505 char *copy = set_alloc(&zip->set, NULL, len + 1);
6ea30fb… florian 506 memcpy(copy, name, len + 1);
6ea30fb… florian 507 int found = set_found(&zip->set, copy);
6ea30fb… florian 508 set_free(&zip->set, copy);
6ea30fb… florian 509 return found;
6ea30fb… florian 510 }
7ef7284… drh 511
7ef7284… drh 512
7ef7284… drh 513 /****************************************************************************/
7ef7284… drh 514
7ef7284… drh 515 #ifndef NO_ADDFILEINEXISTINGZIP
7ef7284… drh 516 /* ===========================================================================
7ef7284… drh 517 Inputs a long in LSB order to the given file
7ef7284… drh 518 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
7ef7284… drh 519 */
7ef7284… drh 520
f1f1d6c… drh 521 local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) {
7ef7284… drh 522 unsigned char buf[8];
7ef7284… drh 523 int n;
7ef7284… drh 524 for (n = 0; n < nbByte; n++)
7ef7284… drh 525 {
7ef7284… drh 526 buf[n] = (unsigned char)(x & 0xff);
7ef7284… drh 527 x >>= 8;
7ef7284… drh 528 }
7ef7284… drh 529 if (x != 0)
7ef7284… drh 530 { /* data overflow - hack for ZIP64 (X Roche) */
7ef7284… drh 531 for (n = 0; n < nbByte; n++)
7ef7284… drh 532 {
7ef7284… drh 533 buf[n] = 0xff;
7ef7284… drh 534 }
7ef7284… drh 535 }
7ef7284… drh 536
adb9e8e… drh 537 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte)
7ef7284… drh 538 return ZIP_ERRNO;
7ef7284… drh 539 else
7ef7284… drh 540 return ZIP_OK;
7ef7284… drh 541 }
7ef7284… drh 542
f1f1d6c… drh 543 local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) {
7ef7284… drh 544 unsigned char* buf=(unsigned char*)dest;
7ef7284… drh 545 int n;
7ef7284… drh 546 for (n = 0; n < nbByte; n++) {
7ef7284… drh 547 buf[n] = (unsigned char)(x & 0xff);
7ef7284… drh 548 x >>= 8;
7ef7284… drh 549 }
7ef7284… drh 550
7ef7284… drh 551 if (x != 0)
7ef7284… drh 552 { /* data overflow - hack for ZIP64 */
7ef7284… drh 553 for (n = 0; n < nbByte; n++)
7ef7284… drh 554 {
7ef7284… drh 555 buf[n] = 0xff;
7ef7284… drh 556 }
7ef7284… drh 557 }
7ef7284… drh 558 }
7ef7284… drh 559
7ef7284… drh 560 /****************************************************************************/
7ef7284… drh 561
7ef7284… drh 562
f1f1d6c… drh 563 local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) {
7ef7284… drh 564 uLong year = (uLong)ptm->tm_year;
7ef7284… drh 565 if (year>=1980)
7ef7284… drh 566 year-=1980;
7ef7284… drh 567 else if (year>=80)
7ef7284… drh 568 year-=80;
7ef7284… drh 569 return
adb9e8e… drh 570 (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon+1)) + (512 * year)) << 16) |
adb9e8e… drh 571 (((uLong)ptm->tm_sec/2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
7ef7284… drh 572 }
7ef7284… drh 573
7ef7284… drh 574
7ef7284… drh 575 /****************************************************************************/
7ef7284… drh 576
f1f1d6c… drh 577 local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) {
7ef7284… drh 578 unsigned char c;
7ef7284… drh 579 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
7ef7284… drh 580 if (err==1)
7ef7284… drh 581 {
7ef7284… drh 582 *pi = (int)c;
7ef7284… drh 583 return ZIP_OK;
7ef7284… drh 584 }
7ef7284… drh 585 else
7ef7284… drh 586 {
7ef7284… drh 587 if (ZERROR64(*pzlib_filefunc_def,filestream))
7ef7284… drh 588 return ZIP_ERRNO;
7ef7284… drh 589 else
7ef7284… drh 590 return ZIP_EOF;
7ef7284… drh 591 }
7ef7284… drh 592 }
7ef7284… drh 593
7ef7284… drh 594
7ef7284… drh 595 /* ===========================================================================
7ef7284… drh 596 Reads a long in LSB order from the given gz_stream. Sets
7ef7284… drh 597 */
f1f1d6c… drh 598 local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) {
7ef7284… drh 599 uLong x ;
7ef7284… drh 600 int i = 0;
7ef7284… drh 601 int err;
7ef7284… drh 602
7ef7284… drh 603 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 604 x = (uLong)i;
7ef7284… drh 605
7ef7284… drh 606 if (err==ZIP_OK)
7ef7284… drh 607 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 608 x += ((uLong)i)<<8;
7ef7284… drh 609
7ef7284… drh 610 if (err==ZIP_OK)
7ef7284… drh 611 *pX = x;
7ef7284… drh 612 else
7ef7284… drh 613 *pX = 0;
7ef7284… drh 614 return err;
7ef7284… drh 615 }
7ef7284… drh 616
f1f1d6c… drh 617 local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) {
7ef7284… drh 618 uLong x ;
7ef7284… drh 619 int i = 0;
7ef7284… drh 620 int err;
7ef7284… drh 621
7ef7284… drh 622 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 623 x = (uLong)i;
7ef7284… drh 624
7ef7284… drh 625 if (err==ZIP_OK)
7ef7284… drh 626 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 627 x += ((uLong)i)<<8;
7ef7284… drh 628
7ef7284… drh 629 if (err==ZIP_OK)
7ef7284… drh 630 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 631 x += ((uLong)i)<<16;
7ef7284… drh 632
7ef7284… drh 633 if (err==ZIP_OK)
7ef7284… drh 634 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 635 x += ((uLong)i)<<24;
7ef7284… drh 636
7ef7284… drh 637 if (err==ZIP_OK)
7ef7284… drh 638 *pX = x;
7ef7284… drh 639 else
7ef7284… drh 640 *pX = 0;
7ef7284… drh 641 return err;
7ef7284… drh 642 }
7ef7284… drh 643
7ef7284… drh 644
f1f1d6c… drh 645 local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) {
7ef7284… drh 646 ZPOS64_T x;
7ef7284… drh 647 int i = 0;
7ef7284… drh 648 int err;
7ef7284… drh 649
7ef7284… drh 650 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 651 x = (ZPOS64_T)i;
7ef7284… drh 652
7ef7284… drh 653 if (err==ZIP_OK)
7ef7284… drh 654 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 655 x += ((ZPOS64_T)i)<<8;
7ef7284… drh 656
7ef7284… drh 657 if (err==ZIP_OK)
7ef7284… drh 658 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 659 x += ((ZPOS64_T)i)<<16;
7ef7284… drh 660
7ef7284… drh 661 if (err==ZIP_OK)
7ef7284… drh 662 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 663 x += ((ZPOS64_T)i)<<24;
7ef7284… drh 664
7ef7284… drh 665 if (err==ZIP_OK)
7ef7284… drh 666 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 667 x += ((ZPOS64_T)i)<<32;
7ef7284… drh 668
7ef7284… drh 669 if (err==ZIP_OK)
7ef7284… drh 670 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 671 x += ((ZPOS64_T)i)<<40;
7ef7284… drh 672
7ef7284… drh 673 if (err==ZIP_OK)
7ef7284… drh 674 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 675 x += ((ZPOS64_T)i)<<48;
7ef7284… drh 676
7ef7284… drh 677 if (err==ZIP_OK)
7ef7284… drh 678 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
7ef7284… drh 679 x += ((ZPOS64_T)i)<<56;
7ef7284… drh 680
7ef7284… drh 681 if (err==ZIP_OK)
7ef7284… drh 682 *pX = x;
7ef7284… drh 683 else
7ef7284… drh 684 *pX = 0;
7ef7284… drh 685
7ef7284… drh 686 return err;
7ef7284… drh 687 }
7ef7284… drh 688
7ef7284… drh 689 #ifndef BUFREADCOMMENT
7ef7284… drh 690 #define BUFREADCOMMENT (0x400)
7ef7284… drh 691 #endif
7ef7284… drh 692 /*
7ef7284… drh 693 Locate the Central directory of a zipfile (at the end, just before
7ef7284… drh 694 the global comment)
7ef7284… drh 695 */
f1f1d6c… drh 696 local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
7ef7284… drh 697 unsigned char* buf;
7ef7284… drh 698 ZPOS64_T uSizeFile;
7ef7284… drh 699 ZPOS64_T uBackRead;
7ef7284… drh 700 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
7ef7284… drh 701 ZPOS64_T uPosFound=0;
7ef7284… drh 702
7ef7284… drh 703 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
7ef7284… drh 704 return 0;
7ef7284… drh 705
7ef7284… drh 706
7ef7284… drh 707 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
7ef7284… drh 708
7ef7284… drh 709 if (uMaxBack>uSizeFile)
7ef7284… drh 710 uMaxBack = uSizeFile;
7ef7284… drh 711
7ef7284… drh 712 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
7ef7284… drh 713 if (buf==NULL)
7ef7284… drh 714 return 0;
7ef7284… drh 715
7ef7284… drh 716 uBackRead = 4;
7ef7284… drh 717 while (uBackRead<uMaxBack)
7ef7284… drh 718 {
7ef7284… drh 719 uLong uReadSize;
7ef7284… drh 720 ZPOS64_T uReadPos ;
7ef7284… drh 721 int i;
7ef7284… drh 722 if (uBackRead+BUFREADCOMMENT>uMaxBack)
7ef7284… drh 723 uBackRead = uMaxBack;
7ef7284… drh 724 else
7ef7284… drh 725 uBackRead+=BUFREADCOMMENT;
7ef7284… drh 726 uReadPos = uSizeFile-uBackRead ;
7ef7284… drh 727
7ef7284… drh 728 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
7ef7284… drh 729 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
7ef7284… drh 730 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 731 break;
7ef7284… drh 732
7ef7284… drh 733 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
7ef7284… drh 734 break;
7ef7284… drh 735
7ef7284… drh 736 for (i=(int)uReadSize-3; (i--)>0;)
7ef7284… drh 737 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
7ef7284… drh 738 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
7ef7284… drh 739 {
adb9e8e… drh 740 uPosFound = uReadPos+(unsigned)i;
7ef7284… drh 741 break;
7ef7284… drh 742 }
7ef7284… drh 743
adb9e8e… drh 744 if (uPosFound!=0)
adb9e8e… drh 745 break;
7ef7284… drh 746 }
f1f1d6c… drh 747 free(buf);
7ef7284… drh 748 return uPosFound;
7ef7284… drh 749 }
7ef7284… drh 750
7ef7284… drh 751 /*
7ef7284… drh 752 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
7ef7284… drh 753 the global comment)
7ef7284… drh 754 */
f1f1d6c… drh 755 local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
7ef7284… drh 756 unsigned char* buf;
7ef7284… drh 757 ZPOS64_T uSizeFile;
7ef7284… drh 758 ZPOS64_T uBackRead;
7ef7284… drh 759 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
7ef7284… drh 760 ZPOS64_T uPosFound=0;
7ef7284… drh 761 uLong uL;
7ef7284… drh 762 ZPOS64_T relativeOffset;
7ef7284… drh 763
7ef7284… drh 764 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
7ef7284… drh 765 return 0;
7ef7284… drh 766
7ef7284… drh 767 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
7ef7284… drh 768
7ef7284… drh 769 if (uMaxBack>uSizeFile)
7ef7284… drh 770 uMaxBack = uSizeFile;
7ef7284… drh 771
7ef7284… drh 772 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
7ef7284… drh 773 if (buf==NULL)
7ef7284… drh 774 return 0;
7ef7284… drh 775
7ef7284… drh 776 uBackRead = 4;
7ef7284… drh 777 while (uBackRead<uMaxBack)
7ef7284… drh 778 {
7ef7284… drh 779 uLong uReadSize;
7ef7284… drh 780 ZPOS64_T uReadPos;
7ef7284… drh 781 int i;
7ef7284… drh 782 if (uBackRead+BUFREADCOMMENT>uMaxBack)
7ef7284… drh 783 uBackRead = uMaxBack;
7ef7284… drh 784 else
7ef7284… drh 785 uBackRead+=BUFREADCOMMENT;
7ef7284… drh 786 uReadPos = uSizeFile-uBackRead ;
7ef7284… drh 787
7ef7284… drh 788 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
7ef7284… drh 789 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
7ef7284… drh 790 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 791 break;
7ef7284… drh 792
7ef7284… drh 793 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
7ef7284… drh 794 break;
7ef7284… drh 795
7ef7284… drh 796 for (i=(int)uReadSize-3; (i--)>0;)
7ef7284… drh 797 {
6ea30fb… florian 798 /* Signature "0x07064b50" Zip64 end of central directory locator */
7ef7284… drh 799 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
7ef7284… drh 800 {
adb9e8e… drh 801 uPosFound = uReadPos+(unsigned)i;
7ef7284… drh 802 break;
7ef7284… drh 803 }
7ef7284… drh 804 }
7ef7284… drh 805
7ef7284… drh 806 if (uPosFound!=0)
7ef7284… drh 807 break;
7ef7284… drh 808 }
7ef7284… drh 809
f1f1d6c… drh 810 free(buf);
7ef7284… drh 811 if (uPosFound == 0)
7ef7284… drh 812 return 0;
7ef7284… drh 813
7ef7284… drh 814 /* Zip64 end of central directory locator */
7ef7284… drh 815 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 816 return 0;
7ef7284… drh 817
7ef7284… drh 818 /* the signature, already checked */
7ef7284… drh 819 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
7ef7284… drh 820 return 0;
7ef7284… drh 821
64ce68d… drh 822 /* number of the disk with the start of the zip64 end of central directory */
7ef7284… drh 823 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
7ef7284… drh 824 return 0;
7ef7284… drh 825 if (uL != 0)
7ef7284… drh 826 return 0;
7ef7284… drh 827
7ef7284… drh 828 /* relative offset of the zip64 end of central directory record */
7ef7284… drh 829 if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
7ef7284… drh 830 return 0;
7ef7284… drh 831
7ef7284… drh 832 /* total number of disks */
7ef7284… drh 833 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
7ef7284… drh 834 return 0;
7ef7284… drh 835 if (uL != 1)
7ef7284… drh 836 return 0;
7ef7284… drh 837
7ef7284… drh 838 /* Goto Zip64 end of central directory record */
7ef7284… drh 839 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 840 return 0;
7ef7284… drh 841
7ef7284… drh 842 /* the signature */
7ef7284… drh 843 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
7ef7284… drh 844 return 0;
7ef7284… drh 845
6ea30fb… florian 846 if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */
7ef7284… drh 847 return 0;
7ef7284… drh 848
7ef7284… drh 849 return relativeOffset;
7ef7284… drh 850 }
7ef7284… drh 851
f1f1d6c… drh 852 local int LoadCentralDirectoryRecord(zip64_internal* pziinit) {
7ef7284… drh 853 int err=ZIP_OK;
7ef7284… drh 854 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
7ef7284… drh 855
7ef7284… drh 856 ZPOS64_T size_central_dir; /* size of the central directory */
7ef7284… drh 857 ZPOS64_T offset_central_dir; /* offset of start of central directory */
7ef7284… drh 858 ZPOS64_T central_pos;
7ef7284… drh 859 uLong uL;
7ef7284… drh 860
64ce68d… drh 861 uLong number_disk; /* number of the current disk, used for
f1f1d6c… drh 862 spanning ZIP, unsupported, always 0*/
64ce68d… drh 863 uLong number_disk_with_CD; /* number of the disk with central dir, used
f1f1d6c… drh 864 for spanning ZIP, unsupported, always 0*/
7ef7284… drh 865 ZPOS64_T number_entry;
7ef7284… drh 866 ZPOS64_T number_entry_CD; /* total number of entries in
7ef7284… drh 867 the central dir
7ef7284… drh 868 (same than number_entry on nospan) */
7ef7284… drh 869 uLong VersionMadeBy;
7ef7284… drh 870 uLong VersionNeeded;
7ef7284… drh 871 uLong size_comment;
7ef7284… drh 872
7ef7284… drh 873 int hasZIP64Record = 0;
7ef7284… drh 874
6ea30fb… florian 875 /* check first if we find a ZIP64 record */
7ef7284… drh 876 central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
7ef7284… drh 877 if(central_pos > 0)
7ef7284… drh 878 {
7ef7284… drh 879 hasZIP64Record = 1;
7ef7284… drh 880 }
7ef7284… drh 881 else if(central_pos == 0)
7ef7284… drh 882 {
7ef7284… drh 883 central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
7ef7284… drh 884 }
7ef7284… drh 885
7ef7284… drh 886 /* disable to allow appending to empty ZIP archive
7ef7284… drh 887 if (central_pos==0)
7ef7284… drh 888 err=ZIP_ERRNO;
7ef7284… drh 889 */
7ef7284… drh 890
7ef7284… drh 891 if(hasZIP64Record)
7ef7284… drh 892 {
7ef7284… drh 893 ZPOS64_T sizeEndOfCentralDirectory;
7ef7284… drh 894 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
7ef7284… drh 895 err=ZIP_ERRNO;
7ef7284… drh 896
7ef7284… drh 897 /* the signature, already checked */
7ef7284… drh 898 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
7ef7284… drh 899 err=ZIP_ERRNO;
7ef7284… drh 900
7ef7284… drh 901 /* size of zip64 end of central directory record */
7ef7284… drh 902 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
7ef7284… drh 903 err=ZIP_ERRNO;
7ef7284… drh 904
7ef7284… drh 905 /* version made by */
7ef7284… drh 906 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
7ef7284… drh 907 err=ZIP_ERRNO;
7ef7284… drh 908
7ef7284… drh 909 /* version needed to extract */
7ef7284… drh 910 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
7ef7284… drh 911 err=ZIP_ERRNO;
7ef7284… drh 912
7ef7284… drh 913 /* number of this disk */
7ef7284… drh 914 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
7ef7284… drh 915 err=ZIP_ERRNO;
7ef7284… drh 916
7ef7284… drh 917 /* number of the disk with the start of the central directory */
7ef7284… drh 918 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
7ef7284… drh 919 err=ZIP_ERRNO;
7ef7284… drh 920
7ef7284… drh 921 /* total number of entries in the central directory on this disk */
7ef7284… drh 922 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
7ef7284… drh 923 err=ZIP_ERRNO;
7ef7284… drh 924
7ef7284… drh 925 /* total number of entries in the central directory */
7ef7284… drh 926 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
7ef7284… drh 927 err=ZIP_ERRNO;
7ef7284… drh 928
7ef7284… drh 929 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
7ef7284… drh 930 err=ZIP_BADZIPFILE;
7ef7284… drh 931
7ef7284… drh 932 /* size of the central directory */
7ef7284… drh 933 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
7ef7284… drh 934 err=ZIP_ERRNO;
7ef7284… drh 935
7ef7284… drh 936 /* offset of start of central directory with respect to the
7ef7284… drh 937 starting disk number */
7ef7284… drh 938 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
7ef7284… drh 939 err=ZIP_ERRNO;
7ef7284… drh 940
6ea30fb… florian 941 /* TODO..
6ea30fb… florian 942 // read the comment from the standard central header. */
7ef7284… drh 943 size_comment = 0;
7ef7284… drh 944 }
7ef7284… drh 945 else
7ef7284… drh 946 {
6ea30fb… florian 947 /* Read End of central Directory info */
7ef7284… drh 948 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 949 err=ZIP_ERRNO;
7ef7284… drh 950
7ef7284… drh 951 /* the signature, already checked */
7ef7284… drh 952 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
7ef7284… drh 953 err=ZIP_ERRNO;
7ef7284… drh 954
7ef7284… drh 955 /* number of this disk */
7ef7284… drh 956 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
7ef7284… drh 957 err=ZIP_ERRNO;
7ef7284… drh 958
7ef7284… drh 959 /* number of the disk with the start of the central directory */
7ef7284… drh 960 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
7ef7284… drh 961 err=ZIP_ERRNO;
7ef7284… drh 962
7ef7284… drh 963 /* total number of entries in the central dir on this disk */
7ef7284… drh 964 number_entry = 0;
7ef7284… drh 965 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
7ef7284… drh 966 err=ZIP_ERRNO;
7ef7284… drh 967 else
7ef7284… drh 968 number_entry = uL;
7ef7284… drh 969
7ef7284… drh 970 /* total number of entries in the central dir */
7ef7284… drh 971 number_entry_CD = 0;
7ef7284… drh 972 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
7ef7284… drh 973 err=ZIP_ERRNO;
7ef7284… drh 974 else
7ef7284… drh 975 number_entry_CD = uL;
7ef7284… drh 976
7ef7284… drh 977 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
7ef7284… drh 978 err=ZIP_BADZIPFILE;
7ef7284… drh 979
7ef7284… drh 980 /* size of the central directory */
7ef7284… drh 981 size_central_dir = 0;
7ef7284… drh 982 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
7ef7284… drh 983 err=ZIP_ERRNO;
7ef7284… drh 984 else
7ef7284… drh 985 size_central_dir = uL;
7ef7284… drh 986
7ef7284… drh 987 /* offset of start of central directory with respect to the starting disk number */
7ef7284… drh 988 offset_central_dir = 0;
7ef7284… drh 989 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
7ef7284… drh 990 err=ZIP_ERRNO;
7ef7284… drh 991 else
7ef7284… drh 992 offset_central_dir = uL;
7ef7284… drh 993
7ef7284… drh 994
7ef7284… drh 995 /* zipfile global comment length */
7ef7284… drh 996 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
7ef7284… drh 997 err=ZIP_ERRNO;
7ef7284… drh 998 }
7ef7284… drh 999
7ef7284… drh 1000 if ((central_pos<offset_central_dir+size_central_dir) &&
7ef7284… drh 1001 (err==ZIP_OK))
7ef7284… drh 1002 err=ZIP_BADZIPFILE;
7ef7284… drh 1003
7ef7284… drh 1004 if (err!=ZIP_OK)
7ef7284… drh 1005 {
7ef7284… drh 1006 ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
7ef7284… drh 1007 return ZIP_ERRNO;
7ef7284… drh 1008 }
7ef7284… drh 1009
7ef7284… drh 1010 if (size_comment>0)
7ef7284… drh 1011 {
7ef7284… drh 1012 pziinit->globalcomment = (char*)ALLOC(size_comment+1);
7ef7284… drh 1013 if (pziinit->globalcomment)
7ef7284… drh 1014 {
7ef7284… drh 1015 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
7ef7284… drh 1016 pziinit->globalcomment[size_comment]=0;
7ef7284… drh 1017 }
7ef7284… drh 1018 }
7ef7284… drh 1019
7ef7284… drh 1020 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
e38d5e1… jan.nijtmans 1021 pziinit->add_position_when_writing_offset = byte_before_the_zipfile;
7ef7284… drh 1022
7ef7284… drh 1023 {
7ef7284… drh 1024 ZPOS64_T size_central_dir_to_read = size_central_dir;
7ef7284… drh 1025 size_t buf_size = SIZEDATA_INDATABLOCK;
7ef7284… drh 1026 void* buf_read = (void*)ALLOC(buf_size);
7ef7284… drh 1027 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
7ef7284… drh 1028 err=ZIP_ERRNO;
7ef7284… drh 1029
7ef7284… drh 1030 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
7ef7284… drh 1031 {
7ef7284… drh 1032 ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
7ef7284… drh 1033 if (read_this > size_central_dir_to_read)
7ef7284… drh 1034 read_this = size_central_dir_to_read;
7ef7284… drh 1035
7ef7284… drh 1036 if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
7ef7284… drh 1037 err=ZIP_ERRNO;
7ef7284… drh 1038
7ef7284… drh 1039 if (err==ZIP_OK)
7ef7284… drh 1040 err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
7ef7284… drh 1041
7ef7284… drh 1042 size_central_dir_to_read-=read_this;
7ef7284… drh 1043 }
f1f1d6c… drh 1044 free(buf_read);
7ef7284… drh 1045 }
7ef7284… drh 1046 pziinit->begin_pos = byte_before_the_zipfile;
7ef7284… drh 1047 pziinit->number_entry = number_entry_CD;
7ef7284… drh 1048
7ef7284… drh 1049 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
7ef7284… drh 1050 err=ZIP_ERRNO;
7ef7284… drh 1051
7ef7284… drh 1052 return err;
7ef7284… drh 1053 }
7ef7284… drh 1054
7ef7284… drh 1055
7ef7284… drh 1056 #endif /* !NO_ADDFILEINEXISTINGZIP*/
7ef7284… drh 1057
7ef7284… drh 1058
7ef7284… drh 1059 /************************************************************/
f1f1d6c… drh 1060 extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) {
7ef7284… drh 1061 zip64_internal ziinit;
7ef7284… drh 1062 zip64_internal* zi;
7ef7284… drh 1063 int err=ZIP_OK;
7ef7284… drh 1064
7ef7284… drh 1065 ziinit.z_filefunc.zseek32_file = NULL;
7ef7284… drh 1066 ziinit.z_filefunc.ztell32_file = NULL;
7ef7284… drh 1067 if (pzlib_filefunc64_32_def==NULL)
7ef7284… drh 1068 fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
7ef7284… drh 1069 else
7ef7284… drh 1070 ziinit.z_filefunc = *pzlib_filefunc64_32_def;
7ef7284… drh 1071
7ef7284… drh 1072 ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
7ef7284… drh 1073 pathname,
7ef7284… drh 1074 (append == APPEND_STATUS_CREATE) ?
7ef7284… drh 1075 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
7ef7284… drh 1076 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
7ef7284… drh 1077
7ef7284… drh 1078 if (ziinit.filestream == NULL)
7ef7284… drh 1079 return NULL;
7ef7284… drh 1080
7ef7284… drh 1081 if (append == APPEND_STATUS_CREATEAFTER)
7ef7284… drh 1082 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
7ef7284… drh 1083
7ef7284… drh 1084 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
7ef7284… drh 1085 ziinit.in_opened_file_inzip = 0;
7ef7284… drh 1086 ziinit.ci.stream_initialised = 0;
7ef7284… drh 1087 ziinit.number_entry = 0;
e38d5e1… jan.nijtmans 1088 ziinit.add_position_when_writing_offset = 0;
7ef7284… drh 1089 init_linkedlist(&(ziinit.central_dir));
6ea30fb… florian 1090 memset(&ziinit.set, 0, sizeof(set_t)); /* make sure set appears dormant */
7ef7284… drh 1091
7ef7284… drh 1092
7ef7284… drh 1093
7ef7284… drh 1094 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
7ef7284… drh 1095 if (zi==NULL)
7ef7284… drh 1096 {
7ef7284… drh 1097 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
7ef7284… drh 1098 return NULL;
7ef7284… drh 1099 }
7ef7284… drh 1100
7ef7284… drh 1101 /* now we add file in a zipfile */
7ef7284… drh 1102 # ifndef NO_ADDFILEINEXISTINGZIP
7ef7284… drh 1103 ziinit.globalcomment = NULL;
7ef7284… drh 1104 if (append == APPEND_STATUS_ADDINZIP)
7ef7284… drh 1105 {
6ea30fb… florian 1106 /* Read and Cache Central Directory Records */
7ef7284… drh 1107 err = LoadCentralDirectoryRecord(&ziinit);
7ef7284… drh 1108 }
7ef7284… drh 1109
7ef7284… drh 1110 if (globalcomment)
7ef7284… drh 1111 {
7ef7284… drh 1112 *globalcomment = ziinit.globalcomment;
7ef7284… drh 1113 }
7ef7284… drh 1114 # endif /* !NO_ADDFILEINEXISTINGZIP*/
7ef7284… drh 1115
7ef7284… drh 1116 if (err != ZIP_OK)
7ef7284… drh 1117 {
7ef7284… drh 1118 # ifndef NO_ADDFILEINEXISTINGZIP
f1f1d6c… drh 1119 free(ziinit.globalcomment);
7ef7284… drh 1120 # endif /* !NO_ADDFILEINEXISTINGZIP*/
f1f1d6c… drh 1121 free(zi);
7ef7284… drh 1122 return NULL;
7ef7284… drh 1123 }
7ef7284… drh 1124 else
7ef7284… drh 1125 {
7ef7284… drh 1126 *zi = ziinit;
7ef7284… drh 1127 return (zipFile)zi;
7ef7284… drh 1128 }
7ef7284… drh 1129 }
7ef7284… drh 1130
f1f1d6c… drh 1131 extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) {
7ef7284… drh 1132 if (pzlib_filefunc32_def != NULL)
7ef7284… drh 1133 {
7ef7284… drh 1134 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
7ef7284… drh 1135 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
7ef7284… drh 1136 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
7ef7284… drh 1137 }
7ef7284… drh 1138 else
7ef7284… drh 1139 return zipOpen3(pathname, append, globalcomment, NULL);
7ef7284… drh 1140 }
7ef7284… drh 1141
f1f1d6c… drh 1142 extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) {
7ef7284… drh 1143 if (pzlib_filefunc_def != NULL)
7ef7284… drh 1144 {
7ef7284… drh 1145 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
7ef7284… drh 1146 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
6ea30fb… florian 1147 zlib_filefunc64_32_def_fill.zopen32_file = NULL;
7ef7284… drh 1148 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
7ef7284… drh 1149 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
7ef7284… drh 1150 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
7ef7284… drh 1151 }
7ef7284… drh 1152 else
7ef7284… drh 1153 return zipOpen3(pathname, append, globalcomment, NULL);
7ef7284… drh 1154 }
7ef7284… drh 1155
7ef7284… drh 1156
7ef7284… drh 1157
f1f1d6c… drh 1158 extern zipFile ZEXPORT zipOpen(const char* pathname, int append) {
7ef7284… drh 1159 return zipOpen3((const void*)pathname,append,NULL,NULL);
7ef7284… drh 1160 }
7ef7284… drh 1161
f1f1d6c… drh 1162 extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) {
7ef7284… drh 1163 return zipOpen3(pathname,append,NULL,NULL);
7ef7284… drh 1164 }
7ef7284… drh 1165
f1f1d6c… drh 1166 local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) {
7ef7284… drh 1167 /* write the local header */
7ef7284… drh 1168 int err;
7ef7284… drh 1169 uInt size_filename = (uInt)strlen(filename);
7ef7284… drh 1170 uInt size_extrafield = size_extrafield_local;
7ef7284… drh 1171
7ef7284… drh 1172 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
7ef7284… drh 1173
7ef7284… drh 1174 if (err==ZIP_OK)
7ef7284… drh 1175 {
7ef7284… drh 1176 if(zi->ci.zip64)
7ef7284… drh 1177 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
7ef7284… drh 1178 else
7ef7284… drh 1179 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
7ef7284… drh 1180 }
7ef7284… drh 1181
7ef7284… drh 1182 if (err==ZIP_OK)
7ef7284… drh 1183 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
7ef7284… drh 1184
7ef7284… drh 1185 if (err==ZIP_OK)
7ef7284… drh 1186 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
7ef7284… drh 1187
7ef7284… drh 1188 if (err==ZIP_OK)
7ef7284… drh 1189 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
7ef7284… drh 1190
6ea30fb… florian 1191 /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */
7ef7284… drh 1192 if (err==ZIP_OK)
7ef7284… drh 1193 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
7ef7284… drh 1194 if (err==ZIP_OK)
7ef7284… drh 1195 {
7ef7284… drh 1196 if(zi->ci.zip64)
7ef7284… drh 1197 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
7ef7284… drh 1198 else
7ef7284… drh 1199 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
7ef7284… drh 1200 }
7ef7284… drh 1201 if (err==ZIP_OK)
7ef7284… drh 1202 {
7ef7284… drh 1203 if(zi->ci.zip64)
7ef7284… drh 1204 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
7ef7284… drh 1205 else
7ef7284… drh 1206 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
7ef7284… drh 1207 }
7ef7284… drh 1208
7ef7284… drh 1209 if (err==ZIP_OK)
7ef7284… drh 1210 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
7ef7284… drh 1211
7ef7284… drh 1212 if(zi->ci.zip64)
7ef7284… drh 1213 {
7ef7284… drh 1214 size_extrafield += 20;
7ef7284… drh 1215 }
7ef7284… drh 1216
7ef7284… drh 1217 if (err==ZIP_OK)
7ef7284… drh 1218 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
7ef7284… drh 1219
7ef7284… drh 1220 if ((err==ZIP_OK) && (size_filename > 0))
7ef7284… drh 1221 {
7ef7284… drh 1222 if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
7ef7284… drh 1223 err = ZIP_ERRNO;
7ef7284… drh 1224 }
7ef7284… drh 1225
7ef7284… drh 1226 if ((err==ZIP_OK) && (size_extrafield_local > 0))
7ef7284… drh 1227 {
7ef7284… drh 1228 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
7ef7284… drh 1229 err = ZIP_ERRNO;
7ef7284… drh 1230 }
7ef7284… drh 1231
7ef7284… drh 1232
7ef7284… drh 1233 if ((err==ZIP_OK) && (zi->ci.zip64))
7ef7284… drh 1234 {
6ea30fb… florian 1235 /* write the Zip64 extended info */
7ef7284… drh 1236 short HeaderID = 1;
7ef7284… drh 1237 short DataSize = 16;
7ef7284… drh 1238 ZPOS64_T CompressedSize = 0;
7ef7284… drh 1239 ZPOS64_T UncompressedSize = 0;
7ef7284… drh 1240
6ea30fb… florian 1241 /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */
7ef7284… drh 1242 zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
7ef7284… drh 1243
adb9e8e… drh 1244 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2);
adb9e8e… drh 1245 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2);
7ef7284… drh 1246
7ef7284… drh 1247 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
7ef7284… drh 1248 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
7ef7284… drh 1249 }
7ef7284… drh 1250
7ef7284… drh 1251 return err;
6ea30fb… florian 1252 }
6ea30fb… florian 1253
6ea30fb… florian 1254 /* Return the length of the UTF-8 code at str[0..len-1] in [1..4], or negative
6ea30fb… florian 1255 if there is no valid UTF-8 code there. If negative, it is minus the number
6ea30fb… florian 1256 of bytes examined in order to determine it was bad. Or if minus the return
6ea30fb… florian 1257 code is one less than len, then at least one more byte than provided would
6ea30fb… florian 1258 be needed to complete the code. */
6ea30fb… florian 1259 local int utf8len(unsigned char const *str, size_t len) {
6ea30fb… florian 1260 return
6ea30fb… florian 1261 len == 0 ? -1 : /* empty input */
6ea30fb… florian 1262 str[0] < 0x80 ? 1 : /* good one-byte */
6ea30fb… florian 1263 str[0] < 0xc0 ? -1 : /* bad first byte */
6ea30fb… florian 1264 len < 2 || (str[1] >> 6) != 2 ? -2 : /* missing or bad 2nd byte */
6ea30fb… florian 1265 str[0] < 0xc2 ? -2 : /* overlong code */
6ea30fb… florian 1266 str[0] < 0xe0 ? 2 : /* good two-byte */
6ea30fb… florian 1267 len < 3 || (str[2] >> 6) != 2 ? -3 : /* missing or bad 3rd byte */
6ea30fb… florian 1268 str[0] == 0xe0 && str[1] < 0xa0 ? -3 : /* overlong code */
6ea30fb… florian 1269 str[0] < 0xf0 ? 3 : /* good three-byte */
6ea30fb… florian 1270 len < 4 || (str[3] >> 6) != 2 ? -4 : /* missing or bad 4th byte */
6ea30fb… florian 1271 str[0] == 0xf0 && str[1] < 0x90 ? -4 : /* overlong code */
6ea30fb… florian 1272 str[0] < 0xf4 ||
6ea30fb… florian 1273 (str[0] == 0xf4 && str[1] < 0x90) ? 4 : /* good four-byte */
6ea30fb… florian 1274 -4; /* code > 0x10ffff */
6ea30fb… florian 1275 }
6ea30fb… florian 1276
6ea30fb… florian 1277 /* Return true if str[0..len-1] is valid UTF-8 *and* it contains at least one
6ea30fb… florian 1278 code of two or more bytes. This is used to determine whether or not to set
6ea30fb… florian 1279 bit 11 in the zip header flags. */
6ea30fb… florian 1280 local int isutf8(char const *str, size_t len) {
6ea30fb… florian 1281 int utf8 = 0;
6ea30fb… florian 1282 while (len) {
6ea30fb… florian 1283 int code = utf8len((unsigned char const *)str, len);
6ea30fb… florian 1284 if (code < 0)
6ea30fb… florian 1285 return 0;
6ea30fb… florian 1286 if (code > 1)
6ea30fb… florian 1287 utf8 = 1;
6ea30fb… florian 1288 str += code;
6ea30fb… florian 1289 len -= (unsigned)code;
6ea30fb… florian 1290 }
6ea30fb… florian 1291 return utf8;
f1f1d6c… drh 1292 }
f1f1d6c… drh 1293
7ef7284… drh 1294 /*
7ef7284… drh 1295 NOTE.
7ef7284… drh 1296 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
7ef7284… drh 1297 before calling this function it can be done with zipRemoveExtraInfoBlock
7ef7284… drh 1298
7ef7284… drh 1299 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
7ef7284… drh 1300 unnecessary allocations.
7ef7284… drh 1301 */
f1f1d6c… drh 1302 extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1303 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1304 const void* extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1305 const char* comment, int method, int level, int raw,
f1f1d6c… drh 1306 int windowBits,int memLevel, int strategy,
f1f1d6c… drh 1307 const char* password, uLong crcForCrypting,
f1f1d6c… drh 1308 uLong versionMadeBy, uLong flagBase, int zip64) {
7ef7284… drh 1309 zip64_internal* zi;
7ef7284… drh 1310 uInt size_filename;
7ef7284… drh 1311 uInt size_comment;
7ef7284… drh 1312 uInt i;
7ef7284… drh 1313 int err = ZIP_OK;
7ef7284… drh 1314
7ef7284… drh 1315 # ifdef NOCRYPT
7ef7284… drh 1316 if (password != NULL)
7ef7284… drh 1317 return ZIP_PARAMERROR;
7ef7284… drh 1318 # endif
7ef7284… drh 1319
7ef7284… drh 1320 if (file == NULL)
7ef7284… drh 1321 return ZIP_PARAMERROR;
7ef7284… drh 1322
7ef7284… drh 1323 #ifdef HAVE_BZIP2
7ef7284… drh 1324 if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
7ef7284… drh 1325 return ZIP_PARAMERROR;
7ef7284… drh 1326 #else
7ef7284… drh 1327 if ((method!=0) && (method!=Z_DEFLATED))
7ef7284… drh 1328 return ZIP_PARAMERROR;
7ef7284… drh 1329 #endif
64ce68d… drh 1330
6ea30fb… florian 1331 /* The filename and comment length must fit in 16 bits. */
64ce68d… drh 1332 if ((filename!=NULL) && (strlen(filename)>0xffff))
64ce68d… drh 1333 return ZIP_PARAMERROR;
64ce68d… drh 1334 if ((comment!=NULL) && (strlen(comment)>0xffff))
64ce68d… drh 1335 return ZIP_PARAMERROR;
6ea30fb… florian 1336 /* The extra field length must fit in 16 bits. If the member also requires
64ce68d… drh 1337 // a Zip64 extra block, that will also need to fit within that 16-bit
6ea30fb… florian 1338 // length, but that will be checked for later. */
64ce68d… drh 1339 if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff))
64ce68d… drh 1340 return ZIP_PARAMERROR;
7ef7284… drh 1341
7ef7284… drh 1342 zi = (zip64_internal*)file;
7ef7284… drh 1343
7ef7284… drh 1344 if (zi->in_opened_file_inzip == 1)
7ef7284… drh 1345 {
7ef7284… drh 1346 err = zipCloseFileInZip (file);
7ef7284… drh 1347 if (err != ZIP_OK)
7ef7284… drh 1348 return err;
7ef7284… drh 1349 }
7ef7284… drh 1350
7ef7284… drh 1351 if (filename==NULL)
7ef7284… drh 1352 filename="-";
7ef7284… drh 1353
7ef7284… drh 1354 if (comment==NULL)
7ef7284… drh 1355 size_comment = 0;
7ef7284… drh 1356 else
7ef7284… drh 1357 size_comment = (uInt)strlen(comment);
7ef7284… drh 1358
7ef7284… drh 1359 size_filename = (uInt)strlen(filename);
7ef7284… drh 1360
7ef7284… drh 1361 if (zipfi == NULL)
7ef7284… drh 1362 zi->ci.dosDate = 0;
7ef7284… drh 1363 else
7ef7284… drh 1364 {
7ef7284… drh 1365 if (zipfi->dosDate != 0)
7ef7284… drh 1366 zi->ci.dosDate = zipfi->dosDate;
7ef7284… drh 1367 else
7ef7284… drh 1368 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
7ef7284… drh 1369 }
7ef7284… drh 1370
7ef7284… drh 1371 zi->ci.flag = flagBase;
7ef7284… drh 1372 if ((level==8) || (level==9))
7ef7284… drh 1373 zi->ci.flag |= 2;
7ef7284… drh 1374 if (level==2)
7ef7284… drh 1375 zi->ci.flag |= 4;
7ef7284… drh 1376 if (level==1)
7ef7284… drh 1377 zi->ci.flag |= 6;
7ef7284… drh 1378 if (password != NULL)
7ef7284… drh 1379 zi->ci.flag |= 1;
6ea30fb… florian 1380 if (isutf8(filename, size_filename) &&
6ea30fb… florian 1381 (size_comment == 0 || isutf8(comment, size_comment)))
6ea30fb… florian 1382 zi->ci.flag |= (1 << 11);
7ef7284… drh 1383
7ef7284… drh 1384 zi->ci.crc32 = 0;
7ef7284… drh 1385 zi->ci.method = method;
7ef7284… drh 1386 zi->ci.encrypt = 0;
7ef7284… drh 1387 zi->ci.stream_initialised = 0;
7ef7284… drh 1388 zi->ci.pos_in_buffered_data = 0;
7ef7284… drh 1389 zi->ci.raw = raw;
7ef7284… drh 1390 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
7ef7284… drh 1391
7ef7284… drh 1392 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
6ea30fb… florian 1393 zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */
7ef7284… drh 1394
7ef7284… drh 1395 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
7ef7284… drh 1396
7ef7284… drh 1397 zi->ci.size_centralExtra = size_extrafield_global;
7ef7284… drh 1398 zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
7ef7284… drh 1399 /* version info */
7ef7284… drh 1400 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
7ef7284… drh 1401 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
7ef7284… drh 1402 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
7ef7284… drh 1403 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
7ef7284… drh 1404 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
7ef7284… drh 1405 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
7ef7284… drh 1406 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
7ef7284… drh 1407 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
7ef7284… drh 1408 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
7ef7284… drh 1409 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
7ef7284… drh 1410 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
7ef7284… drh 1411 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
7ef7284… drh 1412
7ef7284… drh 1413 if (zipfi==NULL)
7ef7284… drh 1414 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
7ef7284… drh 1415 else
7ef7284… drh 1416 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
7ef7284… drh 1417
7ef7284… drh 1418 if (zipfi==NULL)
7ef7284… drh 1419 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
7ef7284… drh 1420 else
7ef7284… drh 1421 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
7ef7284… drh 1422
7ef7284… drh 1423 if(zi->ci.pos_local_header >= 0xffffffff)
7ef7284… drh 1424 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
7ef7284… drh 1425 else
e38d5e1… jan.nijtmans 1426 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4);
7ef7284… drh 1427
7ef7284… drh 1428 for (i=0;i<size_filename;i++)
7ef7284… drh 1429 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
7ef7284… drh 1430
7ef7284… drh 1431 for (i=0;i<size_extrafield_global;i++)
7ef7284… drh 1432 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
7ef7284… drh 1433 *(((const char*)extrafield_global)+i);
7ef7284… drh 1434
7ef7284… drh 1435 for (i=0;i<size_comment;i++)
7ef7284… drh 1436 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
7ef7284… drh 1437 size_extrafield_global+i) = *(comment+i);
7ef7284… drh 1438 if (zi->ci.central_header == NULL)
7ef7284… drh 1439 return ZIP_INTERNALERROR;
7ef7284… drh 1440
7ef7284… drh 1441 zi->ci.zip64 = zip64;
7ef7284… drh 1442 zi->ci.totalCompressedData = 0;
7ef7284… drh 1443 zi->ci.totalUncompressedData = 0;
7ef7284… drh 1444 zi->ci.pos_zip64extrainfo = 0;
7ef7284… drh 1445
7ef7284… drh 1446 err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
7ef7284… drh 1447
7ef7284… drh 1448 #ifdef HAVE_BZIP2
7ef7284… drh 1449 zi->ci.bstream.avail_in = (uInt)0;
7ef7284… drh 1450 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1451 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
7ef7284… drh 1452 zi->ci.bstream.total_in_hi32 = 0;
7ef7284… drh 1453 zi->ci.bstream.total_in_lo32 = 0;
7ef7284… drh 1454 zi->ci.bstream.total_out_hi32 = 0;
7ef7284… drh 1455 zi->ci.bstream.total_out_lo32 = 0;
7ef7284… drh 1456 #endif
7ef7284… drh 1457
7ef7284… drh 1458 zi->ci.stream.avail_in = (uInt)0;
7ef7284… drh 1459 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1460 zi->ci.stream.next_out = zi->ci.buffered_data;
7ef7284… drh 1461 zi->ci.stream.total_in = 0;
7ef7284… drh 1462 zi->ci.stream.total_out = 0;
7ef7284… drh 1463 zi->ci.stream.data_type = Z_BINARY;
7ef7284… drh 1464
7ef7284… drh 1465 #ifdef HAVE_BZIP2
7ef7284… drh 1466 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
7ef7284… drh 1467 #else
7ef7284… drh 1468 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
7ef7284… drh 1469 #endif
7ef7284… drh 1470 {
7ef7284… drh 1471 if(zi->ci.method == Z_DEFLATED)
7ef7284… drh 1472 {
7ef7284… drh 1473 zi->ci.stream.zalloc = (alloc_func)0;
7ef7284… drh 1474 zi->ci.stream.zfree = (free_func)0;
7ef7284… drh 1475 zi->ci.stream.opaque = (voidpf)0;
7ef7284… drh 1476
7ef7284… drh 1477 if (windowBits>0)
7ef7284… drh 1478 windowBits = -windowBits;
7ef7284… drh 1479
7ef7284… drh 1480 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
7ef7284… drh 1481
7ef7284… drh 1482 if (err==Z_OK)
7ef7284… drh 1483 zi->ci.stream_initialised = Z_DEFLATED;
7ef7284… drh 1484 }
7ef7284… drh 1485 else if(zi->ci.method == Z_BZIP2ED)
7ef7284… drh 1486 {
7ef7284… drh 1487 #ifdef HAVE_BZIP2
6ea30fb… florian 1488 /* Init BZip stuff here */
7ef7284… drh 1489 zi->ci.bstream.bzalloc = 0;
7ef7284… drh 1490 zi->ci.bstream.bzfree = 0;
7ef7284… drh 1491 zi->ci.bstream.opaque = (voidpf)0;
7ef7284… drh 1492
7ef7284… drh 1493 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
7ef7284… drh 1494 if(err == BZ_OK)
7ef7284… drh 1495 zi->ci.stream_initialised = Z_BZIP2ED;
7ef7284… drh 1496 #endif
7ef7284… drh 1497 }
7ef7284… drh 1498
7ef7284… drh 1499 }
7ef7284… drh 1500
7ef7284… drh 1501 # ifndef NOCRYPT
7ef7284… drh 1502 zi->ci.crypt_header_size = 0;
7ef7284… drh 1503 if ((err==Z_OK) && (password != NULL))
7ef7284… drh 1504 {
7ef7284… drh 1505 unsigned char bufHead[RAND_HEAD_LEN];
7ef7284… drh 1506 unsigned int sizeHead;
7ef7284… drh 1507 zi->ci.encrypt = 1;
7ef7284… drh 1508 zi->ci.pcrc_32_tab = get_crc_table();
7ef7284… drh 1509 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
7ef7284… drh 1510
7ef7284… drh 1511 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
7ef7284… drh 1512 zi->ci.crypt_header_size = sizeHead;
7ef7284… drh 1513
7ef7284… drh 1514 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
7ef7284… drh 1515 err = ZIP_ERRNO;
7ef7284… drh 1516 }
7ef7284… drh 1517 # endif
7ef7284… drh 1518
7ef7284… drh 1519 if (err==Z_OK)
7ef7284… drh 1520 zi->in_opened_file_inzip = 1;
7ef7284… drh 1521 return err;
7ef7284… drh 1522 }
7ef7284… drh 1523
f1f1d6c… drh 1524 extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1525 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1526 const void* extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1527 const char* comment, int method, int level, int raw,
f1f1d6c… drh 1528 int windowBits,int memLevel, int strategy,
f1f1d6c… drh 1529 const char* password, uLong crcForCrypting,
f1f1d6c… drh 1530 uLong versionMadeBy, uLong flagBase) {
f1f1d6c… drh 1531 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1532 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1533 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1534 comment, method, level, raw,
f1f1d6c… drh 1535 windowBits, memLevel, strategy,
f1f1d6c… drh 1536 password, crcForCrypting, versionMadeBy, flagBase, 0);
f1f1d6c… drh 1537 }
f1f1d6c… drh 1538
f1f1d6c… drh 1539 extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1540 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1541 const void* extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1542 const char* comment, int method, int level, int raw,
f1f1d6c… drh 1543 int windowBits,int memLevel, int strategy,
f1f1d6c… drh 1544 const char* password, uLong crcForCrypting) {
f1f1d6c… drh 1545 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1546 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1547 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1548 comment, method, level, raw,
f1f1d6c… drh 1549 windowBits, memLevel, strategy,
f1f1d6c… drh 1550 password, crcForCrypting, VERSIONMADEBY, 0, 0);
7ef7284… drh 1551 }
7ef7284… drh 1552
7ef7284… drh 1553 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
7ef7284… drh 1554 const void* extrafield_local, uInt size_extrafield_local,
7ef7284… drh 1555 const void* extrafield_global, uInt size_extrafield_global,
7ef7284… drh 1556 const char* comment, int method, int level, int raw,
7ef7284… drh 1557 int windowBits,int memLevel, int strategy,
f1f1d6c… drh 1558 const char* password, uLong crcForCrypting, int zip64) {
f1f1d6c… drh 1559 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1560 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1561 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1562 comment, method, level, raw,
f1f1d6c… drh 1563 windowBits, memLevel, strategy,
f1f1d6c… drh 1564 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
7ef7284… drh 1565 }
7ef7284… drh 1566
7ef7284… drh 1567 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
7ef7284… drh 1568 const void* extrafield_local, uInt size_extrafield_local,
7ef7284… drh 1569 const void* extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1570 const char* comment, int method, int level, int raw) {
f1f1d6c… drh 1571 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1572 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1573 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1574 comment, method, level, raw,
f1f1d6c… drh 1575 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
f1f1d6c… drh 1576 NULL, 0, VERSIONMADEBY, 0, 0);
7ef7284… drh 1577 }
7ef7284… drh 1578
7ef7284… drh 1579 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1580 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1581 const void* extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1582 const char* comment, int method, int level, int raw, int zip64) {
f1f1d6c… drh 1583 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1584 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1585 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1586 comment, method, level, raw,
f1f1d6c… drh 1587 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
f1f1d6c… drh 1588 NULL, 0, VERSIONMADEBY, 0, zip64);
f1f1d6c… drh 1589 }
f1f1d6c… drh 1590
f1f1d6c… drh 1591 extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1592 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1593 const void*extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1594 const char* comment, int method, int level, int zip64) {
f1f1d6c… drh 1595 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1596 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1597 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1598 comment, method, level, 0,
f1f1d6c… drh 1599 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
f1f1d6c… drh 1600 NULL, 0, VERSIONMADEBY, 0, zip64);
f1f1d6c… drh 1601 }
f1f1d6c… drh 1602
f1f1d6c… drh 1603 extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi,
f1f1d6c… drh 1604 const void* extrafield_local, uInt size_extrafield_local,
f1f1d6c… drh 1605 const void*extrafield_global, uInt size_extrafield_global,
f1f1d6c… drh 1606 const char* comment, int method, int level) {
f1f1d6c… drh 1607 return zipOpenNewFileInZip4_64(file, filename, zipfi,
f1f1d6c… drh 1608 extrafield_local, size_extrafield_local,
f1f1d6c… drh 1609 extrafield_global, size_extrafield_global,
f1f1d6c… drh 1610 comment, method, level, 0,
f1f1d6c… drh 1611 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
f1f1d6c… drh 1612 NULL, 0, VERSIONMADEBY, 0, 0);
f1f1d6c… drh 1613 }
f1f1d6c… drh 1614
f1f1d6c… drh 1615 local int zip64FlushWriteBuffer(zip64_internal* zi) {
7ef7284… drh 1616 int err=ZIP_OK;
7ef7284… drh 1617
7ef7284… drh 1618 if (zi->ci.encrypt != 0)
7ef7284… drh 1619 {
7ef7284… drh 1620 #ifndef NOCRYPT
7ef7284… drh 1621 uInt i;
7ef7284… drh 1622 int t;
7ef7284… drh 1623 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
7ef7284… drh 1624 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
7ef7284… drh 1625 #endif
7ef7284… drh 1626 }
7ef7284… drh 1627
7ef7284… drh 1628 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
7ef7284… drh 1629 err = ZIP_ERRNO;
7ef7284… drh 1630
7ef7284… drh 1631 zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
7ef7284… drh 1632
7ef7284… drh 1633 #ifdef HAVE_BZIP2
7ef7284… drh 1634 if(zi->ci.method == Z_BZIP2ED)
7ef7284… drh 1635 {
7ef7284… drh 1636 zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
7ef7284… drh 1637 zi->ci.bstream.total_in_lo32 = 0;
7ef7284… drh 1638 zi->ci.bstream.total_in_hi32 = 0;
7ef7284… drh 1639 }
7ef7284… drh 1640 else
7ef7284… drh 1641 #endif
7ef7284… drh 1642 {
7ef7284… drh 1643 zi->ci.totalUncompressedData += zi->ci.stream.total_in;
7ef7284… drh 1644 zi->ci.stream.total_in = 0;
7ef7284… drh 1645 }
7ef7284… drh 1646
7ef7284… drh 1647
7ef7284… drh 1648 zi->ci.pos_in_buffered_data = 0;
7ef7284… drh 1649
7ef7284… drh 1650 return err;
7ef7284… drh 1651 }
7ef7284… drh 1652
f1f1d6c… drh 1653 extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) {
7ef7284… drh 1654 zip64_internal* zi;
7ef7284… drh 1655 int err=ZIP_OK;
7ef7284… drh 1656
7ef7284… drh 1657 if (file == NULL)
7ef7284… drh 1658 return ZIP_PARAMERROR;
7ef7284… drh 1659 zi = (zip64_internal*)file;
7ef7284… drh 1660
7ef7284… drh 1661 if (zi->in_opened_file_inzip == 0)
7ef7284… drh 1662 return ZIP_PARAMERROR;
7ef7284… drh 1663
7ef7284… drh 1664 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
7ef7284… drh 1665
7ef7284… drh 1666 #ifdef HAVE_BZIP2
7ef7284… drh 1667 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
7ef7284… drh 1668 {
7ef7284… drh 1669 zi->ci.bstream.next_in = (void*)buf;
7ef7284… drh 1670 zi->ci.bstream.avail_in = len;
7ef7284… drh 1671 err = BZ_RUN_OK;
7ef7284… drh 1672
7ef7284… drh 1673 while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
7ef7284… drh 1674 {
7ef7284… drh 1675 if (zi->ci.bstream.avail_out == 0)
7ef7284… drh 1676 {
7ef7284… drh 1677 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
7ef7284… drh 1678 err = ZIP_ERRNO;
7ef7284… drh 1679 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1680 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
7ef7284… drh 1681 }
7ef7284… drh 1682
7ef7284… drh 1683
7ef7284… drh 1684 if(err != BZ_RUN_OK)
7ef7284… drh 1685 break;
7ef7284… drh 1686
7ef7284… drh 1687 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
7ef7284… drh 1688 {
7ef7284… drh 1689 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
6ea30fb… florian 1690 /* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */
7ef7284… drh 1691 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
7ef7284… drh 1692
7ef7284… drh 1693 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
7ef7284… drh 1694 }
7ef7284… drh 1695 }
7ef7284… drh 1696
7ef7284… drh 1697 if(err == BZ_RUN_OK)
7ef7284… drh 1698 err = ZIP_OK;
7ef7284… drh 1699 }
7ef7284… drh 1700 else
7ef7284… drh 1701 #endif
7ef7284… drh 1702 {
6ea30fb… florian 1703 zi->ci.stream.next_in = buf;
7ef7284… drh 1704 zi->ci.stream.avail_in = len;
7ef7284… drh 1705
7ef7284… drh 1706 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
7ef7284… drh 1707 {
7ef7284… drh 1708 if (zi->ci.stream.avail_out == 0)
7ef7284… drh 1709 {
7ef7284… drh 1710 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
7ef7284… drh 1711 err = ZIP_ERRNO;
7ef7284… drh 1712 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1713 zi->ci.stream.next_out = zi->ci.buffered_data;
7ef7284… drh 1714 }
7ef7284… drh 1715
7ef7284… drh 1716
7ef7284… drh 1717 if(err != ZIP_OK)
7ef7284… drh 1718 break;
7ef7284… drh 1719
7ef7284… drh 1720 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
7ef7284… drh 1721 {
7ef7284… drh 1722 uLong uTotalOutBefore = zi->ci.stream.total_out;
7ef7284… drh 1723 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
7ef7284… drh 1724
7ef7284… drh 1725 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
7ef7284… drh 1726 }
7ef7284… drh 1727 else
7ef7284… drh 1728 {
7ef7284… drh 1729 uInt copy_this,i;
7ef7284… drh 1730 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
7ef7284… drh 1731 copy_this = zi->ci.stream.avail_in;
7ef7284… drh 1732 else
7ef7284… drh 1733 copy_this = zi->ci.stream.avail_out;
7ef7284… drh 1734
7ef7284… drh 1735 for (i = 0; i < copy_this; i++)
7ef7284… drh 1736 *(((char*)zi->ci.stream.next_out)+i) =
7ef7284… drh 1737 *(((const char*)zi->ci.stream.next_in)+i);
7ef7284… drh 1738 {
7ef7284… drh 1739 zi->ci.stream.avail_in -= copy_this;
7ef7284… drh 1740 zi->ci.stream.avail_out-= copy_this;
7ef7284… drh 1741 zi->ci.stream.next_in+= copy_this;
7ef7284… drh 1742 zi->ci.stream.next_out+= copy_this;
7ef7284… drh 1743 zi->ci.stream.total_in+= copy_this;
7ef7284… drh 1744 zi->ci.stream.total_out+= copy_this;
7ef7284… drh 1745 zi->ci.pos_in_buffered_data += copy_this;
7ef7284… drh 1746 }
7ef7284… drh 1747 }
6ea30fb… florian 1748 }/* while(...) */
7ef7284… drh 1749 }
7ef7284… drh 1750
7ef7284… drh 1751 return err;
7ef7284… drh 1752 }
7ef7284… drh 1753
f1f1d6c… drh 1754 extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) {
7ef7284… drh 1755 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
7ef7284… drh 1756 }
7ef7284… drh 1757
f1f1d6c… drh 1758 extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) {
7ef7284… drh 1759 zip64_internal* zi;
7ef7284… drh 1760 ZPOS64_T compressed_size;
7ef7284… drh 1761 uLong invalidValue = 0xffffffff;
adb9e8e… drh 1762 unsigned datasize = 0;
7ef7284… drh 1763 int err=ZIP_OK;
7ef7284… drh 1764
7ef7284… drh 1765 if (file == NULL)
7ef7284… drh 1766 return ZIP_PARAMERROR;
7ef7284… drh 1767 zi = (zip64_internal*)file;
7ef7284… drh 1768
7ef7284… drh 1769 if (zi->in_opened_file_inzip == 0)
7ef7284… drh 1770 return ZIP_PARAMERROR;
7ef7284… drh 1771 zi->ci.stream.avail_in = 0;
7ef7284… drh 1772
7ef7284… drh 1773 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
7ef7284… drh 1774 {
7ef7284… drh 1775 while (err==ZIP_OK)
7ef7284… drh 1776 {
7ef7284… drh 1777 uLong uTotalOutBefore;
7ef7284… drh 1778 if (zi->ci.stream.avail_out == 0)
7ef7284… drh 1779 {
7ef7284… drh 1780 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
7ef7284… drh 1781 err = ZIP_ERRNO;
7ef7284… drh 1782 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1783 zi->ci.stream.next_out = zi->ci.buffered_data;
7ef7284… drh 1784 }
7ef7284… drh 1785 uTotalOutBefore = zi->ci.stream.total_out;
7ef7284… drh 1786 err=deflate(&zi->ci.stream, Z_FINISH);
7ef7284… drh 1787 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
7ef7284… drh 1788 }
7ef7284… drh 1789 }
7ef7284… drh 1790 else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
7ef7284… drh 1791 {
7ef7284… drh 1792 #ifdef HAVE_BZIP2
7ef7284… drh 1793 err = BZ_FINISH_OK;
7ef7284… drh 1794 while (err==BZ_FINISH_OK)
7ef7284… drh 1795 {
7ef7284… drh 1796 uLong uTotalOutBefore;
7ef7284… drh 1797 if (zi->ci.bstream.avail_out == 0)
7ef7284… drh 1798 {
7ef7284… drh 1799 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
7ef7284… drh 1800 err = ZIP_ERRNO;
7ef7284… drh 1801 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
7ef7284… drh 1802 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
7ef7284… drh 1803 }
7ef7284… drh 1804 uTotalOutBefore = zi->ci.bstream.total_out_lo32;
7ef7284… drh 1805 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
7ef7284… drh 1806 if(err == BZ_STREAM_END)
7ef7284… drh 1807 err = Z_STREAM_END;
7ef7284… drh 1808
7ef7284… drh 1809 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
7ef7284… drh 1810 }
7ef7284… drh 1811
7ef7284… drh 1812 if(err == BZ_FINISH_OK)
7ef7284… drh 1813 err = ZIP_OK;
7ef7284… drh 1814 #endif
7ef7284… drh 1815 }
7ef7284… drh 1816
7ef7284… drh 1817 if (err==Z_STREAM_END)
7ef7284… drh 1818 err=ZIP_OK; /* this is normal */
7ef7284… drh 1819
7ef7284… drh 1820 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
7ef7284… drh 1821 {
7ef7284… drh 1822 if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
7ef7284… drh 1823 err = ZIP_ERRNO;
7ef7284… drh 1824 }
7ef7284… drh 1825
7ef7284… drh 1826 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
7ef7284… drh 1827 {
7ef7284… drh 1828 int tmp_err = deflateEnd(&zi->ci.stream);
7ef7284… drh 1829 if (err == ZIP_OK)
7ef7284… drh 1830 err = tmp_err;
7ef7284… drh 1831 zi->ci.stream_initialised = 0;
7ef7284… drh 1832 }
7ef7284… drh 1833 #ifdef HAVE_BZIP2
7ef7284… drh 1834 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
7ef7284… drh 1835 {
7ef7284… drh 1836 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
7ef7284… drh 1837 if (err==ZIP_OK)
7ef7284… drh 1838 err = tmperr;
7ef7284… drh 1839 zi->ci.stream_initialised = 0;
7ef7284… drh 1840 }
7ef7284… drh 1841 #endif
7ef7284… drh 1842
7ef7284… drh 1843 if (!zi->ci.raw)
7ef7284… drh 1844 {
7ef7284… drh 1845 crc32 = (uLong)zi->ci.crc32;
7ef7284… drh 1846 uncompressed_size = zi->ci.totalUncompressedData;
7ef7284… drh 1847 }
7ef7284… drh 1848 compressed_size = zi->ci.totalCompressedData;
7ef7284… drh 1849
7ef7284… drh 1850 # ifndef NOCRYPT
7ef7284… drh 1851 compressed_size += zi->ci.crypt_header_size;
7ef7284… drh 1852 # endif
7ef7284… drh 1853
6ea30fb… florian 1854 /* update Current Item crc and sizes, */
7ef7284… drh 1855 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
7ef7284… drh 1856 {
7ef7284… drh 1857 /*version Made by*/
7ef7284… drh 1858 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
7ef7284… drh 1859 /*version needed*/
7ef7284… drh 1860 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
7ef7284… drh 1861
7ef7284… drh 1862 }
7ef7284… drh 1863
7ef7284… drh 1864 zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
7ef7284… drh 1865
7ef7284… drh 1866
7ef7284… drh 1867 if(compressed_size >= 0xffffffff)
7ef7284… drh 1868 zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
7ef7284… drh 1869 else
7ef7284… drh 1870 zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
7ef7284… drh 1871
6ea30fb… florian 1872 /* set internal file attributes field */
7ef7284… drh 1873 if (zi->ci.stream.data_type == Z_ASCII)
7ef7284… drh 1874 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
7ef7284… drh 1875
7ef7284… drh 1876 if(uncompressed_size >= 0xffffffff)
7ef7284… drh 1877 zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
7ef7284… drh 1878 else
7ef7284… drh 1879 zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
7ef7284… drh 1880
6ea30fb… florian 1881 /* Add ZIP64 extra info field for uncompressed size */
7ef7284… drh 1882 if(uncompressed_size >= 0xffffffff)
7ef7284… drh 1883 datasize += 8;
7ef7284… drh 1884
6ea30fb… florian 1885 /* Add ZIP64 extra info field for compressed size */
7ef7284… drh 1886 if(compressed_size >= 0xffffffff)
7ef7284… drh 1887 datasize += 8;
7ef7284… drh 1888
6ea30fb… florian 1889 /* Add ZIP64 extra info field for relative offset to local file header of current file */
7ef7284… drh 1890 if(zi->ci.pos_local_header >= 0xffffffff)
7ef7284… drh 1891 datasize += 8;
7ef7284… drh 1892
7ef7284… drh 1893 if(datasize > 0)
7ef7284… drh 1894 {
7ef7284… drh 1895 char* p = NULL;
7ef7284… drh 1896
7ef7284… drh 1897 if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
7ef7284… drh 1898 {
6ea30fb… florian 1899 /* we cannot write more data to the buffer that we have room for. */
7ef7284… drh 1900 return ZIP_BADZIPFILE;
7ef7284… drh 1901 }
7ef7284… drh 1902
7ef7284… drh 1903 p = zi->ci.central_header + zi->ci.size_centralheader;
7ef7284… drh 1904
6ea30fb… florian 1905 /* Add Extra Information Header for 'ZIP64 information' */
6ea30fb… florian 1906 zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */
7ef7284… drh 1907 p += 2;
6ea30fb… florian 1908 zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */
7ef7284… drh 1909 p += 2;
7ef7284… drh 1910
7ef7284… drh 1911 if(uncompressed_size >= 0xffffffff)
7ef7284… drh 1912 {
7ef7284… drh 1913 zip64local_putValue_inmemory(p, uncompressed_size, 8);
7ef7284… drh 1914 p += 8;
7ef7284… drh 1915 }
7ef7284… drh 1916
7ef7284… drh 1917 if(compressed_size >= 0xffffffff)
7ef7284… drh 1918 {
7ef7284… drh 1919 zip64local_putValue_inmemory(p, compressed_size, 8);
7ef7284… drh 1920 p += 8;
7ef7284… drh 1921 }
7ef7284… drh 1922
7ef7284… drh 1923 if(zi->ci.pos_local_header >= 0xffffffff)
7ef7284… drh 1924 {
7ef7284… drh 1925 zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
7ef7284… drh 1926 p += 8;
7ef7284… drh 1927 }
7ef7284… drh 1928
6ea30fb… florian 1929 /* Update how much extra free space we got in the memory buffer
7ef7284… drh 1930 // and increase the centralheader size so the new ZIP64 fields are included
6ea30fb… florian 1931 // ( 4 below is the size of HeaderID and DataSize field ) */
7ef7284… drh 1932 zi->ci.size_centralExtraFree -= datasize + 4;
7ef7284… drh 1933 zi->ci.size_centralheader += datasize + 4;
7ef7284… drh 1934
6ea30fb… florian 1935 /* Update the extra info size field */
7ef7284… drh 1936 zi->ci.size_centralExtra += datasize + 4;
7ef7284… drh 1937 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
7ef7284… drh 1938 }
7ef7284… drh 1939
7ef7284… drh 1940 if (err==ZIP_OK)
7ef7284… drh 1941 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
7ef7284… drh 1942
7ef7284… drh 1943 free(zi->ci.central_header);
7ef7284… drh 1944
7ef7284… drh 1945 if (err==ZIP_OK)
7ef7284… drh 1946 {
6ea30fb… florian 1947 /* Update the LocalFileHeader with the new values. */
7ef7284… drh 1948
7ef7284… drh 1949 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
7ef7284… drh 1950
7ef7284… drh 1951 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 1952 err = ZIP_ERRNO;
7ef7284… drh 1953
7ef7284… drh 1954 if (err==ZIP_OK)
7ef7284… drh 1955 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
7ef7284… drh 1956
7ef7284… drh 1957 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
7ef7284… drh 1958 {
7ef7284… drh 1959 if(zi->ci.pos_zip64extrainfo > 0)
7ef7284… drh 1960 {
6ea30fb… florian 1961 /* Update the size in the ZIP64 extended field. */
7ef7284… drh 1962 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 1963 err = ZIP_ERRNO;
7ef7284… drh 1964
7ef7284… drh 1965 if (err==ZIP_OK) /* compressed size, unknown */
7ef7284… drh 1966 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
7ef7284… drh 1967
7ef7284… drh 1968 if (err==ZIP_OK) /* uncompressed size, unknown */
7ef7284… drh 1969 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
7ef7284… drh 1970 }
7ef7284… drh 1971 else
6ea30fb… florian 1972 err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */
7ef7284… drh 1973 }
7ef7284… drh 1974 else
7ef7284… drh 1975 {
7ef7284… drh 1976 if (err==ZIP_OK) /* compressed size, unknown */
7ef7284… drh 1977 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
7ef7284… drh 1978
7ef7284… drh 1979 if (err==ZIP_OK) /* uncompressed size, unknown */
7ef7284… drh 1980 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
7ef7284… drh 1981 }
7ef7284… drh 1982
7ef7284… drh 1983 if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
7ef7284… drh 1984 err = ZIP_ERRNO;
7ef7284… drh 1985 }
7ef7284… drh 1986
7ef7284… drh 1987 zi->number_entry ++;
7ef7284… drh 1988 zi->in_opened_file_inzip = 0;
7ef7284… drh 1989
7ef7284… drh 1990 return err;
7ef7284… drh 1991 }
7ef7284… drh 1992
f1f1d6c… drh 1993 extern int ZEXPORT zipCloseFileInZip(zipFile file) {
7ef7284… drh 1994 return zipCloseFileInZipRaw (file,0,0);
7ef7284… drh 1995 }
7ef7284… drh 1996
f1f1d6c… drh 1997 local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) {
7ef7284… drh 1998 int err = ZIP_OK;
e38d5e1… jan.nijtmans 1999 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
7ef7284… drh 2000
7ef7284… drh 2001 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
7ef7284… drh 2002
7ef7284… drh 2003 /*num disks*/
7ef7284… drh 2004 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
7ef7284… drh 2005 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
7ef7284… drh 2006
7ef7284… drh 2007 /*relative offset*/
7ef7284… drh 2008 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
7ef7284… drh 2009 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
7ef7284… drh 2010
7ef7284… drh 2011 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
7ef7284… drh 2012 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
7ef7284… drh 2013 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
7ef7284… drh 2014
7ef7284… drh 2015 return err;
7ef7284… drh 2016 }
7ef7284… drh 2017
f1f1d6c… drh 2018 local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) {
7ef7284… drh 2019 int err = ZIP_OK;
7ef7284… drh 2020
7ef7284… drh 2021 uLong Zip64DataSize = 44;
7ef7284… drh 2022
7ef7284… drh 2023 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
7ef7284… drh 2024
7ef7284… drh 2025 if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
6ea30fb… florian 2026 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */
7ef7284… drh 2027
7ef7284… drh 2028 if (err==ZIP_OK) /* version made by */
7ef7284… drh 2029 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
7ef7284… drh 2030
7ef7284… drh 2031 if (err==ZIP_OK) /* version needed */
7ef7284… drh 2032 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
7ef7284… drh 2033
7ef7284… drh 2034 if (err==ZIP_OK) /* number of this disk */
7ef7284… drh 2035 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
7ef7284… drh 2036
7ef7284… drh 2037 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
7ef7284… drh 2038 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
7ef7284… drh 2039
7ef7284… drh 2040 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
7ef7284… drh 2041 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
7ef7284… drh 2042
7ef7284… drh 2043 if (err==ZIP_OK) /* total number of entries in the central dir */
7ef7284… drh 2044 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
7ef7284… drh 2045
7ef7284… drh 2046 if (err==ZIP_OK) /* size of the central directory */
7ef7284… drh 2047 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
7ef7284… drh 2048
7ef7284… drh 2049 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
7ef7284… drh 2050 {
e38d5e1… jan.nijtmans 2051 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
7ef7284… drh 2052 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
7ef7284… drh 2053 }
7ef7284… drh 2054 return err;
7ef7284… drh 2055 }
f1f1d6c… drh 2056
f1f1d6c… drh 2057 local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) {
7ef7284… drh 2058 int err = ZIP_OK;
7ef7284… drh 2059
7ef7284… drh 2060 /*signature*/
7ef7284… drh 2061 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
7ef7284… drh 2062
7ef7284… drh 2063 if (err==ZIP_OK) /* number of this disk */
7ef7284… drh 2064 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
7ef7284… drh 2065
7ef7284… drh 2066 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
7ef7284… drh 2067 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
7ef7284… drh 2068
7ef7284… drh 2069 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
7ef7284… drh 2070 {
7ef7284… drh 2071 {
7ef7284… drh 2072 if(zi->number_entry >= 0xFFFF)
6ea30fb… florian 2073 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
7ef7284… drh 2074 else
7ef7284… drh 2075 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
7ef7284… drh 2076 }
7ef7284… drh 2077 }
7ef7284… drh 2078
7ef7284… drh 2079 if (err==ZIP_OK) /* total number of entries in the central dir */
7ef7284… drh 2080 {
7ef7284… drh 2081 if(zi->number_entry >= 0xFFFF)
6ea30fb… florian 2082 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
7ef7284… drh 2083 else
7ef7284… drh 2084 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
7ef7284… drh 2085 }
7ef7284… drh 2086
7ef7284… drh 2087 if (err==ZIP_OK) /* size of the central directory */
7ef7284… drh 2088 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
7ef7284… drh 2089
7ef7284… drh 2090 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
7ef7284… drh 2091 {
e38d5e1… jan.nijtmans 2092 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
7ef7284… drh 2093 if(pos >= 0xffffffff)
7ef7284… drh 2094 {
7ef7284… drh 2095 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
7ef7284… drh 2096 }
7ef7284… drh 2097 else
e38d5e1… jan.nijtmans 2098 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
7ef7284… drh 2099 }
7ef7284… drh 2100
7ef7284… drh 2101 return err;
7ef7284… drh 2102 }
7ef7284… drh 2103
f1f1d6c… drh 2104 local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) {
7ef7284… drh 2105 int err = ZIP_OK;
7ef7284… drh 2106 uInt size_global_comment = 0;
7ef7284… drh 2107
7ef7284… drh 2108 if(global_comment != NULL)
7ef7284… drh 2109 size_global_comment = (uInt)strlen(global_comment);
7ef7284… drh 2110
7ef7284… drh 2111 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
7ef7284… drh 2112
7ef7284… drh 2113 if (err == ZIP_OK && size_global_comment > 0)
7ef7284… drh 2114 {
7ef7284… drh 2115 if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
7ef7284… drh 2116 err = ZIP_ERRNO;
7ef7284… drh 2117 }
7ef7284… drh 2118 return err;
7ef7284… drh 2119 }
7ef7284… drh 2120
f1f1d6c… drh 2121 extern int ZEXPORT zipClose(zipFile file, const char* global_comment) {
7ef7284… drh 2122 zip64_internal* zi;
7ef7284… drh 2123 int err = 0;
7ef7284… drh 2124 uLong size_centraldir = 0;
7ef7284… drh 2125 ZPOS64_T centraldir_pos_inzip;
7ef7284… drh 2126 ZPOS64_T pos;
7ef7284… drh 2127
7ef7284… drh 2128 if (file == NULL)
7ef7284… drh 2129 return ZIP_PARAMERROR;
7ef7284… drh 2130
7ef7284… drh 2131 zi = (zip64_internal*)file;
7ef7284… drh 2132
7ef7284… drh 2133 if (zi->in_opened_file_inzip == 1)
7ef7284… drh 2134 {
7ef7284… drh 2135 err = zipCloseFileInZip (file);
7ef7284… drh 2136 }
7ef7284… drh 2137
7ef7284… drh 2138 #ifndef NO_ADDFILEINEXISTINGZIP
7ef7284… drh 2139 if (global_comment==NULL)
7ef7284… drh 2140 global_comment = zi->globalcomment;
7ef7284… drh 2141 #endif
7ef7284… drh 2142
7ef7284… drh 2143 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
7ef7284… drh 2144
7ef7284… drh 2145 if (err==ZIP_OK)
7ef7284… drh 2146 {
7ef7284… drh 2147 linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
7ef7284… drh 2148 while (ldi!=NULL)
7ef7284… drh 2149 {
7ef7284… drh 2150 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
7ef7284… drh 2151 {
7ef7284… drh 2152 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
7ef7284… drh 2153 err = ZIP_ERRNO;
7ef7284… drh 2154 }
7ef7284… drh 2155
7ef7284… drh 2156 size_centraldir += ldi->filled_in_this_block;
7ef7284… drh 2157 ldi = ldi->next_datablock;
7ef7284… drh 2158 }
7ef7284… drh 2159 }
7ef7284… drh 2160 free_linkedlist(&(zi->central_dir));
7ef7284… drh 2161
6ea30fb… florian 2162 set_end(&zi->set); /* set was zeroed, so this is safe */
6ea30fb… florian 2163
e38d5e1… jan.nijtmans 2164 pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
64ce68d… drh 2165 if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF)
7ef7284… drh 2166 {
7ef7284… drh 2167 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
7ef7284… drh 2168 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
7ef7284… drh 2169
7ef7284… drh 2170 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
7ef7284… drh 2171 }
7ef7284… drh 2172
7ef7284… drh 2173 if (err==ZIP_OK)
7ef7284… drh 2174 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
7ef7284… drh 2175
7ef7284… drh 2176 if(err == ZIP_OK)
7ef7284… drh 2177 err = Write_GlobalComment(zi, global_comment);
7ef7284… drh 2178
7ef7284… drh 2179 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
7ef7284… drh 2180 if (err == ZIP_OK)
7ef7284… drh 2181 err = ZIP_ERRNO;
7ef7284… drh 2182
7ef7284… drh 2183 #ifndef NO_ADDFILEINEXISTINGZIP
f1f1d6c… drh 2184 free(zi->globalcomment);
7ef7284… drh 2185 #endif
f1f1d6c… drh 2186 free(zi);
7ef7284… drh 2187
7ef7284… drh 2188 return err;
7ef7284… drh 2189 }
7ef7284… drh 2190
f1f1d6c… drh 2191 extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) {
7ef7284… drh 2192 char* p = pData;
7ef7284… drh 2193 int size = 0;
7ef7284… drh 2194 char* pNewHeader;
7ef7284… drh 2195 char* pTmp;
7ef7284… drh 2196 short header;
7ef7284… drh 2197 short dataSize;
7ef7284… drh 2198
7ef7284… drh 2199 int retVal = ZIP_OK;
7ef7284… drh 2200
a9e589c… florian 2201 if(pData == NULL || dataLen == NULL || *dataLen < 4)
7ef7284… drh 2202 return ZIP_PARAMERROR;
7ef7284… drh 2203
adb9e8e… drh 2204 pNewHeader = (char*)ALLOC((unsigned)*dataLen);
7ef7284… drh 2205 pTmp = pNewHeader;
7ef7284… drh 2206
7ef7284… drh 2207 while(p < (pData + *dataLen))
7ef7284… drh 2208 {
7ef7284… drh 2209 header = *(short*)p;
7ef7284… drh 2210 dataSize = *(((short*)p)+1);
7ef7284… drh 2211
6ea30fb… florian 2212 if( header == sHeader ) /* Header found. */
7ef7284… drh 2213 {
6ea30fb… florian 2214 p += dataSize + 4; /* skip it. do not copy to temp buffer */
7ef7284… drh 2215 }
7ef7284… drh 2216 else
7ef7284… drh 2217 {
6ea30fb… florian 2218 /* Extra Info block should not be removed, So copy it to the temp buffer. */
7ef7284… drh 2219 memcpy(pTmp, p, dataSize + 4);
7ef7284… drh 2220 p += dataSize + 4;
7ef7284… drh 2221 size += dataSize + 4;
7ef7284… drh 2222 }
7ef7284… drh 2223
7ef7284… drh 2224 }
7ef7284… drh 2225
7ef7284… drh 2226 if(size < *dataLen)
7ef7284… drh 2227 {
6ea30fb… florian 2228 /* clean old extra info block. */
7ef7284… drh 2229 memset(pData,0, *dataLen);
7ef7284… drh 2230
6ea30fb… florian 2231 /* copy the new extra info block over the old */
7ef7284… drh 2232 if(size > 0)
7ef7284… drh 2233 memcpy(pData, pNewHeader, size);
7ef7284… drh 2234
6ea30fb… florian 2235 /* set the new extra info size */
7ef7284… drh 2236 *dataLen = size;
7ef7284… drh 2237
7ef7284… drh 2238 retVal = ZIP_OK;
7ef7284… drh 2239 }
7ef7284… drh 2240 else
7ef7284… drh 2241 retVal = ZIP_ERRNO;
7ef7284… drh 2242
f1f1d6c… drh 2243 free(pNewHeader);
7ef7284… drh 2244
7ef7284… drh 2245 return retVal;
7ef7284… drh 2246 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button