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