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