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