1 /* unzip.c -- IO for uncompress .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 of Unzip for Zip64
8          Copyright (C) 2007-2008 Even Rouault
9 
10          Modifications for Zip64 support on both zip and unzip
11          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
12 
13          For more info read MiniZip_info.txt
14 
15 
16   ------------------------------------------------------------------------------------
17   Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
18   compatibility with older software. The following is from the original crypt.c.
19   Code woven in by Terry Thorsen 1/2003.
20 
21   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
22 
23   See the accompanying file LICENSE, version 2000-Apr-09 or later
24   (the contents of which are also included in zip.h) for terms of use.
25   If, for some reason, all these files are missing, the Info-ZIP license
26   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
27 
28         crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
29 
30   The encryption/decryption parts of this source code (as opposed to the
31   non-echoing password parts) were originally written in Europe.  The
32   whole source package can be freely distributed, including from the USA.
33   (Prior to January 2000, re-export from the US was a violation of US law.)
34 
35         This encryption code is a direct transcription of the algorithm from
36   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
37   file (appnote.txt) is distributed with the PKZIP program (even in the
38   version without encryption capabilities).
39 
40         ------------------------------------------------------------------------------------
41 
42         Changes in unzip.c
43 
44         2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
45   2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
46   2007-2008 - Even Rouault - Remove old C style function prototypes
47   2007-2008 - Even Rouault - Add unzip support for ZIP64
48 
49         Copyright (C) 2007-2008 Even Rouault
50 
51 
52         Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
53   Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
54                                 should only read the compressed/uncompressed size from the Zip64 format if
55                                 the size from normal header was 0xFFFFFFFF
56   Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
57         Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
58                                 Patch created by Daniel Borca
59 
60   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
61 
62   Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
63 
64 */
65 
66 
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 
71 #ifndef NOUNCRYPT
72         #define NOUNCRYPT
73 #endif
74 
75 #include "zlib.h"
76 #include "unzip.h"
77 
78 #ifdef STDC
79 #  include <stddef.h>
80 #  include <string.h>
81 #  include <stdlib.h>
82 #endif
83 #ifdef NO_ERRNO_H
84     extern int errno;
85 #else
86 #   include <errno.h>
87 #endif
88 
89 
90 #ifndef local
91 #  define local static
92 #endif
93 /* compile with -Dlocal if your debugger can't find static symbols */
94 
95 
96 #ifndef CASESENSITIVITYDEFAULT_NO
97 #  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
98 #    define CASESENSITIVITYDEFAULT_NO
99 #  endif
100 #endif
101 
102 
103 #ifndef UNZ_BUFSIZE
104 #define UNZ_BUFSIZE (16384)
105 #endif
106 
107 #ifndef UNZ_MAXFILENAMEINZIP
108 #define UNZ_MAXFILENAMEINZIP (256)
109 #endif
110 
111 #ifndef ALLOC
112 # define ALLOC(size) (malloc(size))
113 #endif
114 #ifndef TRYFREE
115 # define TRYFREE(p) {if (p) free(p);}
116 #endif
117 
118 #define SIZECENTRALDIRITEM (0x2e)
119 #define SIZEZIPLOCALHEADER (0x1e)
120 
121 
122 const char unz_copyright[] =
123    " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
124 
125 /* unz_file_info_interntal contain internal info about a file in zipfile*/
126 typedef struct unz_file_info64_internal_s
127 {
128     ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
129 } unz_file_info64_internal;
130 
131 
132 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
133     when reading and decompress it */
134 typedef struct
135 {
136     char  *read_buffer;         /* internal buffer for compressed data */
137     z_stream stream;            /* zLib stream structure for inflate */
138 
139 #ifdef HAVE_BZIP2
140     bz_stream bstream;          /* bzLib stream structure for bziped */
141 #endif
142 
143     ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
144     uLong stream_initialised;   /* flag set if stream structure is initialised*/
145 
146     ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
147     uInt  size_local_extrafield;/* size of the local extra field */
148     ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
149     ZPOS64_T total_out_64;
150 
151     uLong crc32;                /* crc32 of all data uncompressed */
152     uLong crc32_wait;           /* crc32 we must obtain after decompress all */
153     ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
154     ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
155     zlib_filefunc64_32_def z_filefunc;
156     voidpf filestream;        /* io structore of the zipfile */
157     uLong compression_method;   /* compression method (0==store) */
158     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
159     int   raw;
160     /* GODOT start */
161     int extra_size;
162     /* GODOT end */
163 } file_in_zip64_read_info_s;
164 
165 
166 /* unz64_s contain internal information about the zipfile
167 */
168 typedef struct
169 {
170     zlib_filefunc64_32_def z_filefunc;
171     int is64bitOpenFunction;
172     voidpf filestream;        /* io structore of the zipfile */
173     unz_global_info64 gi;       /* public global information */
174     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
175     ZPOS64_T num_file;             /* number of the current file in the zipfile*/
176     ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
177     ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
178     ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
179 
180     ZPOS64_T size_central_dir;     /* size of the central directory  */
181     ZPOS64_T offset_central_dir;   /* offset of start of central directory with
182                                    respect to the starting disk number */
183 
184     unz_file_info64 cur_file_info; /* public info about the current file in zip*/
185     unz_file_info64_internal cur_file_info_internal; /* private info about it*/
186     file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
187                                         file if we are decompressing it */
188     int encrypted;
189 
190     int isZip64;
191 
192 #    ifndef NOUNCRYPT
193     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
194     const z_crc_t* pcrc_32_tab;
195 #    endif
196 } unz64_s;
197 
198 
199 #ifndef NOUNCRYPT
200 #include "crypt.h"
201 #endif
202 
203 /* ===========================================================================
204      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
205    for end of file.
206    IN assertion: the stream s has been successfully opened for reading.
207 */
208 
209 
210 local int unz64local_getByte OF((
211     const zlib_filefunc64_32_def* pzlib_filefunc_def,
212     voidpf filestream,
213     int *pi));
214 
unz64local_getByte(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,int * pi)215 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
216 {
217     unsigned char c;
218     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
219     if (err==1)
220     {
221         *pi = (int)c;
222         return UNZ_OK;
223     }
224     else
225     {
226         if (ZERROR64(*pzlib_filefunc_def,filestream))
227             return UNZ_ERRNO;
228         else
229             return UNZ_EOF;
230     }
231 }
232 
233 
234 /* ===========================================================================
235    Reads a long in LSB order from the given gz_stream. Sets
236 */
237 local int unz64local_getShort OF((
238     const zlib_filefunc64_32_def* pzlib_filefunc_def,
239     voidpf filestream,
240     uLong *pX));
241 
unz64local_getShort(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)242 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
243                              voidpf filestream,
244                              uLong *pX)
245 {
246     uLong x ;
247     int i = 0;
248     int err;
249 
250     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
251     x = (uLong)i;
252 
253     if (err==UNZ_OK)
254         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
255     x |= ((uLong)i)<<8;
256 
257     if (err==UNZ_OK)
258         *pX = x;
259     else
260         *pX = 0;
261     return err;
262 }
263 
264 local int unz64local_getLong OF((
265     const zlib_filefunc64_32_def* pzlib_filefunc_def,
266     voidpf filestream,
267     uLong *pX));
268 
unz64local_getLong(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)269 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
270                             voidpf filestream,
271                             uLong *pX)
272 {
273     uLong x ;
274     int i = 0;
275     int err;
276 
277     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
278     x = (uLong)i;
279 
280     if (err==UNZ_OK)
281         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
282     x |= ((uLong)i)<<8;
283 
284     if (err==UNZ_OK)
285         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
286     x |= ((uLong)i)<<16;
287 
288     if (err==UNZ_OK)
289         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
290     x += ((uLong)i)<<24;
291 
292     if (err==UNZ_OK)
293         *pX = x;
294     else
295         *pX = 0;
296     return err;
297 }
298 
299 local int unz64local_getLong64 OF((
300     const zlib_filefunc64_32_def* pzlib_filefunc_def,
301     voidpf filestream,
302     ZPOS64_T *pX));
303 
304 
unz64local_getLong64(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,ZPOS64_T * pX)305 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
306                             voidpf filestream,
307                             ZPOS64_T *pX)
308 {
309     ZPOS64_T x ;
310     int i = 0;
311     int err;
312 
313     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
314     x = (ZPOS64_T)i;
315 
316     if (err==UNZ_OK)
317         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
318     x |= ((ZPOS64_T)i)<<8;
319 
320     if (err==UNZ_OK)
321         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
322     x |= ((ZPOS64_T)i)<<16;
323 
324     if (err==UNZ_OK)
325         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
326     x |= ((ZPOS64_T)i)<<24;
327 
328     if (err==UNZ_OK)
329         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
330     x |= ((ZPOS64_T)i)<<32;
331 
332     if (err==UNZ_OK)
333         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
334     x |= ((ZPOS64_T)i)<<40;
335 
336     if (err==UNZ_OK)
337         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
338     x |= ((ZPOS64_T)i)<<48;
339 
340     if (err==UNZ_OK)
341         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
342     x |= ((ZPOS64_T)i)<<56;
343 
344     if (err==UNZ_OK)
345         *pX = x;
346     else
347         *pX = 0;
348     return err;
349 }
350 
351 /* My own strcmpi / strcasecmp */
strcmpcasenosensitive_internal(const char * fileName1,const char * fileName2)352 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
353 {
354     for (;;)
355     {
356         char c1=*(fileName1++);
357         char c2=*(fileName2++);
358         if ((c1>='a') && (c1<='z'))
359             c1 -= 0x20;
360         if ((c2>='a') && (c2<='z'))
361             c2 -= 0x20;
362         if (c1=='\0')
363             return ((c2=='\0') ? 0 : -1);
364         if (c2=='\0')
365             return 1;
366         if (c1<c2)
367             return -1;
368         if (c1>c2)
369             return 1;
370     }
371 }
372 
373 
374 #ifdef  CASESENSITIVITYDEFAULT_NO
375 #define CASESENSITIVITYDEFAULTVALUE 2
376 #else
377 #define CASESENSITIVITYDEFAULTVALUE 1
378 #endif
379 
380 #ifndef STRCMPCASENOSENTIVEFUNCTION
381 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
382 #endif
383 
384 /*
385    Compare two filename (fileName1,fileName2).
386    If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
387    If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
388                                                                 or strcasecmp)
389    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
390         (like 1 on Unix, 2 on Windows)
391 
392 */
unzStringFileNameCompare(const char * fileName1,const char * fileName2,int iCaseSensitivity)393 extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
394                                                  const char*  fileName2,
395                                                  int iCaseSensitivity)
396 
397 {
398     if (iCaseSensitivity==0)
399         iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
400 
401     if (iCaseSensitivity==1)
402         return strcmp(fileName1,fileName2);
403 
404     return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
405 }
406 
407 #ifndef BUFREADCOMMENT
408 #define BUFREADCOMMENT (0x400)
409 #endif
410 
411 /*
412   Locate the Central directory of a zipfile (at the end, just before
413     the global comment)
414 */
415 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
unz64local_SearchCentralDir(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream)416 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
417 {
418     unsigned char* buf;
419     ZPOS64_T uSizeFile;
420     ZPOS64_T uBackRead;
421     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
422     ZPOS64_T uPosFound=0;
423 
424     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
425         return 0;
426 
427 
428     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
429 
430     if (uMaxBack>uSizeFile)
431         uMaxBack = uSizeFile;
432 
433     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
434     if (buf==NULL)
435         return 0;
436 
437     uBackRead = 4;
438     while (uBackRead<uMaxBack)
439     {
440         uLong uReadSize;
441         ZPOS64_T uReadPos ;
442         int i;
443         if (uBackRead+BUFREADCOMMENT>uMaxBack)
444             uBackRead = uMaxBack;
445         else
446             uBackRead+=BUFREADCOMMENT;
447         uReadPos = uSizeFile-uBackRead ;
448 
449         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
450                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
451         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
452             break;
453 
454         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
455             break;
456 
457         for (i=(int)uReadSize-3; (i--)>0;)
458             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
459                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
460             {
461                 uPosFound = uReadPos+i;
462                 break;
463             }
464 
465         if (uPosFound!=0)
466             break;
467     }
468     TRYFREE(buf);
469     return uPosFound;
470 }
471 
472 
473 /*
474   Locate the Central directory 64 of a zipfile (at the end, just before
475     the global comment)
476 */
477 local ZPOS64_T unz64local_SearchCentralDir64 OF((
478     const zlib_filefunc64_32_def* pzlib_filefunc_def,
479     voidpf filestream));
480 
unz64local_SearchCentralDir64(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream)481 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
482                                       voidpf filestream)
483 {
484     unsigned char* buf;
485     ZPOS64_T uSizeFile;
486     ZPOS64_T uBackRead;
487     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
488     ZPOS64_T uPosFound=0;
489     uLong uL;
490                 ZPOS64_T relativeOffset;
491 
492     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
493         return 0;
494 
495 
496     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
497 
498     if (uMaxBack>uSizeFile)
499         uMaxBack = uSizeFile;
500 
501     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
502     if (buf==NULL)
503         return 0;
504 
505     uBackRead = 4;
506     while (uBackRead<uMaxBack)
507     {
508         uLong uReadSize;
509         ZPOS64_T uReadPos;
510         int i;
511         if (uBackRead+BUFREADCOMMENT>uMaxBack)
512             uBackRead = uMaxBack;
513         else
514             uBackRead+=BUFREADCOMMENT;
515         uReadPos = uSizeFile-uBackRead ;
516 
517         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
518                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
519         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
520             break;
521 
522         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
523             break;
524 
525         for (i=(int)uReadSize-3; (i--)>0;)
526             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
527                 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
528             {
529                 uPosFound = uReadPos+i;
530                 break;
531             }
532 
533         if (uPosFound!=0)
534             break;
535     }
536     TRYFREE(buf);
537     if (uPosFound == 0)
538         return 0;
539 
540     /* Zip64 end of central directory locator */
541     if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
542         return 0;
543 
544     /* the signature, already checked */
545     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
546         return 0;
547 
548     /* number of the disk with the start of the zip64 end of  central directory */
549     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
550         return 0;
551     if (uL != 0)
552         return 0;
553 
554     /* relative offset of the zip64 end of central directory record */
555     if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
556         return 0;
557 
558     /* total number of disks */
559     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
560         return 0;
561     if (uL != 1)
562         return 0;
563 
564     /* Goto end of central directory record */
565     if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
566         return 0;
567 
568      /* the signature */
569     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
570         return 0;
571 
572     if (uL != 0x06064b50)
573         return 0;
574 
575     return relativeOffset;
576 }
577 
578 /*
579   Open a Zip file. path contain the full pathname (by example,
580      on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
581      "zlib/zlib114.zip".
582      If the zipfile cannot be opened (file doesn't exist or in not valid), the
583        return value is NULL.
584      Else, the return value is a unzFile Handle, usable with other function
585        of this unzip package.
586 */
unzOpenInternal(const void * path,zlib_filefunc64_32_def * pzlib_filefunc64_32_def,int is64bitOpenFunction)587 local unzFile unzOpenInternal (const void *path,
588                                zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
589                                int is64bitOpenFunction)
590 {
591     unz64_s us;
592     unz64_s *s;
593     ZPOS64_T central_pos;
594     uLong   uL;
595 
596     uLong number_disk;          /* number of the current dist, used for
597                                    spaning ZIP, unsupported, always 0*/
598     uLong number_disk_with_CD;  /* number the the disk with central dir, used
599                                    for spaning ZIP, unsupported, always 0*/
600     ZPOS64_T number_entry_CD;      /* total number of entries in
601                                    the central dir
602                                    (same than number_entry on nospan) */
603 
604     int err=UNZ_OK;
605 
606     if (unz_copyright[0]!=' ')
607         return NULL;
608 
609     us.z_filefunc.zseek32_file = NULL;
610     us.z_filefunc.ztell32_file = NULL;
611     if (pzlib_filefunc64_32_def==NULL)
612         /* GODOT start */
613         return NULL; // standard i/o not supported
614     us.z_filefunc = *pzlib_filefunc64_32_def;
615     /* GODOT end */
616     us.is64bitOpenFunction = is64bitOpenFunction;
617 
618 
619 
620     us.filestream = ZOPEN64(us.z_filefunc,
621                                                  path,
622                                                  ZLIB_FILEFUNC_MODE_READ |
623                                                  ZLIB_FILEFUNC_MODE_EXISTING);
624     if (us.filestream==NULL)
625         return NULL;
626 
627     central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
628     if (central_pos)
629     {
630         uLong uS;
631         ZPOS64_T uL64;
632 
633         us.isZip64 = 1;
634 
635         if (ZSEEK64(us.z_filefunc, us.filestream,
636                                       central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
637         err=UNZ_ERRNO;
638 
639         /* the signature, already checked */
640         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
641             err=UNZ_ERRNO;
642 
643         /* size of zip64 end of central directory record */
644         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
645             err=UNZ_ERRNO;
646 
647         /* version made by */
648         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
649             err=UNZ_ERRNO;
650 
651         /* version needed to extract */
652         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
653             err=UNZ_ERRNO;
654 
655         /* number of this disk */
656         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
657             err=UNZ_ERRNO;
658 
659         /* number of the disk with the start of the central directory */
660         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
661             err=UNZ_ERRNO;
662 
663         /* total number of entries in the central directory on this disk */
664         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
665             err=UNZ_ERRNO;
666 
667         /* total number of entries in the central directory */
668         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
669             err=UNZ_ERRNO;
670 
671         if ((number_entry_CD!=us.gi.number_entry) ||
672             (number_disk_with_CD!=0) ||
673             (number_disk!=0))
674             err=UNZ_BADZIPFILE;
675 
676         /* size of the central directory */
677         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
678             err=UNZ_ERRNO;
679 
680         /* offset of start of central directory with respect to the
681           starting disk number */
682         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
683             err=UNZ_ERRNO;
684 
685         us.gi.size_comment = 0;
686     }
687     else
688     {
689         central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
690         if (central_pos==0)
691             err=UNZ_ERRNO;
692 
693         us.isZip64 = 0;
694 
695         if (ZSEEK64(us.z_filefunc, us.filestream,
696                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
697             err=UNZ_ERRNO;
698 
699         /* the signature, already checked */
700         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
701             err=UNZ_ERRNO;
702 
703         /* number of this disk */
704         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
705             err=UNZ_ERRNO;
706 
707         /* number of the disk with the start of the central directory */
708         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
709             err=UNZ_ERRNO;
710 
711         /* total number of entries in the central dir on this disk */
712         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
713             err=UNZ_ERRNO;
714         us.gi.number_entry = uL;
715 
716         /* total number of entries in the central dir */
717         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
718             err=UNZ_ERRNO;
719         number_entry_CD = uL;
720 
721         if ((number_entry_CD!=us.gi.number_entry) ||
722             (number_disk_with_CD!=0) ||
723             (number_disk!=0))
724             err=UNZ_BADZIPFILE;
725 
726         /* size of the central directory */
727         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
728             err=UNZ_ERRNO;
729         us.size_central_dir = uL;
730 
731         /* offset of start of central directory with respect to the
732             starting disk number */
733         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
734             err=UNZ_ERRNO;
735         us.offset_central_dir = uL;
736 
737         /* zipfile comment length */
738         if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
739             err=UNZ_ERRNO;
740     }
741 
742     if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
743         (err==UNZ_OK))
744         err=UNZ_BADZIPFILE;
745 
746     if (err!=UNZ_OK)
747     {
748         ZCLOSE64(us.z_filefunc, us.filestream);
749         return NULL;
750     }
751 
752     us.byte_before_the_zipfile = central_pos -
753                             (us.offset_central_dir+us.size_central_dir);
754     us.central_pos = central_pos;
755     us.pfile_in_zip_read = NULL;
756     us.encrypted = 0;
757 
758 
759     s=(unz64_s*)ALLOC(sizeof(unz64_s));
760     if( s != NULL)
761     {
762         *s=us;
763         unzGoToFirstFile((unzFile)s);
764     }
765     return (unzFile)s;
766 }
767 
768 
unzOpen2(const char * path,zlib_filefunc_def * pzlib_filefunc32_def)769 extern unzFile ZEXPORT unzOpen2 (const char *path,
770                                         zlib_filefunc_def* pzlib_filefunc32_def)
771 {
772     if (pzlib_filefunc32_def != NULL)
773     {
774         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
775         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
776         return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
777     }
778     else
779         return unzOpenInternal(path, NULL, 0);
780 }
781 
unzOpen2_64(const void * path,zlib_filefunc64_def * pzlib_filefunc_def)782 extern unzFile ZEXPORT unzOpen2_64 (const void *path,
783                                      zlib_filefunc64_def* pzlib_filefunc_def)
784 {
785     if (pzlib_filefunc_def != NULL)
786     {
787         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
788         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
789         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
790         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
791         return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
792     }
793     else
794         return unzOpenInternal(path, NULL, 1);
795 }
796 
unzOpen(const char * path)797 extern unzFile ZEXPORT unzOpen (const char *path)
798 {
799     return unzOpenInternal(path, NULL, 0);
800 }
801 
unzOpen64(const void * path)802 extern unzFile ZEXPORT unzOpen64 (const void *path)
803 {
804     return unzOpenInternal(path, NULL, 1);
805 }
806 
807 /* GODOT start */
unzGetOpaque(unzFile file)808 extern void* unzGetOpaque(unzFile file) {
809 
810     unz64_s* s;
811     if (file==NULL)
812         return NULL;
813     s=(unz64_s*)file;
814 
815     return s->z_filefunc.zfile_func64.opaque;
816 };
817 /* GODOT end */
818 
819 /*
820   Close a ZipFile opened with unzOpen.
821   If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
822     these files MUST be closed with unzCloseCurrentFile before call unzClose.
823   return UNZ_OK if there is no problem. */
unzClose(unzFile file)824 extern int ZEXPORT unzClose (unzFile file)
825 {
826     unz64_s* s;
827     if (file==NULL)
828         return UNZ_PARAMERROR;
829     s=(unz64_s*)file;
830 
831     if (s->pfile_in_zip_read!=NULL)
832         unzCloseCurrentFile(file);
833 
834     ZCLOSE64(s->z_filefunc, s->filestream);
835     TRYFREE(s);
836     return UNZ_OK;
837 }
838 
839 
840 /*
841   Write info about the ZipFile in the *pglobal_info structure.
842   No preparation of the structure is needed
843   return UNZ_OK if there is no problem. */
unzGetGlobalInfo64(unzFile file,unz_global_info64 * pglobal_info)844 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
845 {
846     unz64_s* s;
847     if (file==NULL)
848         return UNZ_PARAMERROR;
849     s=(unz64_s*)file;
850     *pglobal_info=s->gi;
851     return UNZ_OK;
852 }
853 
unzGetGlobalInfo(unzFile file,unz_global_info * pglobal_info32)854 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
855 {
856     unz64_s* s;
857     if (file==NULL)
858         return UNZ_PARAMERROR;
859     s=(unz64_s*)file;
860     /* to do : check if number_entry is not truncated */
861     pglobal_info32->number_entry = (uLong)s->gi.number_entry;
862     pglobal_info32->size_comment = s->gi.size_comment;
863     return UNZ_OK;
864 }
865 /*
866    Translate date/time from Dos format to tm_unz (readable more easilty)
867 */
unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate,tm_unz * ptm)868 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
869 {
870     ZPOS64_T uDate;
871     uDate = (ZPOS64_T)(ulDosDate>>16);
872     ptm->tm_mday = (uInt)(uDate&0x1f) ;
873     ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
874     ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
875 
876     ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
877     ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
878     ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
879 }
880 
881 /*
882   Get Info about the current file in the zipfile, with internal only info
883 */
884 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
885                                                   unz_file_info64 *pfile_info,
886                                                   unz_file_info64_internal
887                                                   *pfile_info_internal,
888                                                   char *szFileName,
889                                                   uLong fileNameBufferSize,
890                                                   void *extraField,
891                                                   uLong extraFieldBufferSize,
892                                                   char *szComment,
893                                                   uLong commentBufferSize));
894 
unz64local_GetCurrentFileInfoInternal(unzFile file,unz_file_info64 * pfile_info,unz_file_info64_internal * pfile_info_internal,char * szFileName,uLong fileNameBufferSize,void * extraField,uLong extraFieldBufferSize,char * szComment,uLong commentBufferSize)895 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
896                                                   unz_file_info64 *pfile_info,
897                                                   unz_file_info64_internal
898                                                   *pfile_info_internal,
899                                                   char *szFileName,
900                                                   uLong fileNameBufferSize,
901                                                   void *extraField,
902                                                   uLong extraFieldBufferSize,
903                                                   char *szComment,
904                                                   uLong commentBufferSize)
905 {
906     unz64_s* s;
907     unz_file_info64 file_info;
908     unz_file_info64_internal file_info_internal;
909     int err=UNZ_OK;
910     uLong uMagic;
911     long lSeek=0;
912     uLong uL;
913 
914     if (file==NULL)
915         return UNZ_PARAMERROR;
916     s=(unz64_s*)file;
917     if (ZSEEK64(s->z_filefunc, s->filestream,
918               s->pos_in_central_dir+s->byte_before_the_zipfile,
919               ZLIB_FILEFUNC_SEEK_SET)!=0)
920         err=UNZ_ERRNO;
921 
922 
923     /* we check the magic */
924     if (err==UNZ_OK)
925     {
926         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
927             err=UNZ_ERRNO;
928         else if (uMagic!=0x02014b50)
929             err=UNZ_BADZIPFILE;
930     }
931 
932     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
933         err=UNZ_ERRNO;
934 
935     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
936         err=UNZ_ERRNO;
937 
938     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
939         err=UNZ_ERRNO;
940 
941     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
942         err=UNZ_ERRNO;
943 
944     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
945         err=UNZ_ERRNO;
946 
947     unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
948 
949     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
950         err=UNZ_ERRNO;
951 
952     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
953         err=UNZ_ERRNO;
954     file_info.compressed_size = uL;
955 
956     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
957         err=UNZ_ERRNO;
958     file_info.uncompressed_size = uL;
959 
960     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
961         err=UNZ_ERRNO;
962 
963     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
964         err=UNZ_ERRNO;
965 
966     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
967         err=UNZ_ERRNO;
968 
969     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
970         err=UNZ_ERRNO;
971 
972     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
973         err=UNZ_ERRNO;
974 
975     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
976         err=UNZ_ERRNO;
977 
978                 // relative offset of local header
979     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
980         err=UNZ_ERRNO;
981     file_info_internal.offset_curfile = uL;
982 
983     lSeek+=file_info.size_filename;
984     if ((err==UNZ_OK) && (szFileName!=NULL))
985     {
986         uLong uSizeRead ;
987         if (file_info.size_filename<fileNameBufferSize)
988         {
989             *(szFileName+file_info.size_filename)='\0';
990             uSizeRead = file_info.size_filename;
991         }
992         else
993             uSizeRead = fileNameBufferSize;
994 
995         if ((file_info.size_filename>0) && (fileNameBufferSize>0))
996             if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
997                 err=UNZ_ERRNO;
998         lSeek -= uSizeRead;
999     }
1000 
1001     // Read extrafield
1002     if ((err==UNZ_OK) && (extraField!=NULL))
1003     {
1004         ZPOS64_T uSizeRead ;
1005         if (file_info.size_file_extra<extraFieldBufferSize)
1006             uSizeRead = file_info.size_file_extra;
1007         else
1008             uSizeRead = extraFieldBufferSize;
1009 
1010         if (lSeek!=0)
1011         {
1012             if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1013                 lSeek=0;
1014             else
1015                 err=UNZ_ERRNO;
1016         }
1017 
1018         if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1019             if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1020                 err=UNZ_ERRNO;
1021 
1022         lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1023     }
1024     else
1025         lSeek += file_info.size_file_extra;
1026 
1027 
1028     if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1029     {
1030                                 uLong acc = 0;
1031 
1032         // since lSeek now points to after the extra field we need to move back
1033         lSeek -= file_info.size_file_extra;
1034 
1035         if (lSeek!=0)
1036         {
1037             /* GODOT start */
1038             if (lSeek<0) {
1039                 // WORKAROUND for backwards seeking
1040                 z_off_t pos = ZTELL64(s->z_filefunc, s->filestream);
1041                 if (ZSEEK64(s->z_filefunc, s->filestream,pos+lSeek,ZLIB_FILEFUNC_SEEK_SET)==0)
1042                     lSeek=0;
1043                 else
1044                     err=UNZ_ERRNO;
1045             } else {
1046                 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1047                     lSeek=0;
1048                 else
1049                     err=UNZ_ERRNO;
1050             }
1051         }
1052 
1053         while(acc < file_info.size_file_extra)
1054         {
1055             uLong headerId;
1056                                                 uLong dataSize;
1057 
1058             if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1059                 err=UNZ_ERRNO;
1060 
1061             if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1062                 err=UNZ_ERRNO;
1063 
1064             /* ZIP64 extra fields */
1065             if (headerId == 0x0001)
1066             {
1067                                                         uLong uL;
1068 
1069                                                                 if(file_info.uncompressed_size == MAXU32)
1070                                                                 {
1071                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1072                                                                                         err=UNZ_ERRNO;
1073                                                                 }
1074 
1075                                                                 if(file_info.compressed_size == MAXU32)
1076                                                                 {
1077                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1078                                                                                   err=UNZ_ERRNO;
1079                                                                 }
1080 
1081                                                                 if(file_info_internal.offset_curfile == MAXU32)
1082                                                                 {
1083                                                                         /* Relative Header offset */
1084                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1085                                                                                 err=UNZ_ERRNO;
1086                                                                 }
1087 
1088                                                                 if(file_info.disk_num_start == MAXU32)
1089                                                                 {
1090                                                                         /* Disk Start Number */
1091                                                                         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1092                                                                                 err=UNZ_ERRNO;
1093                                                                 }
1094 
1095             }
1096             else
1097             {
1098                 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1099                     err=UNZ_ERRNO;
1100             }
1101 
1102             acc += 2 + 2 + dataSize;
1103         }
1104     }
1105 
1106     if ((err==UNZ_OK) && (szComment!=NULL))
1107     {
1108         uLong uSizeRead ;
1109         if (file_info.size_file_comment<commentBufferSize)
1110         {
1111             *(szComment+file_info.size_file_comment)='\0';
1112             uSizeRead = file_info.size_file_comment;
1113         }
1114         else
1115             uSizeRead = commentBufferSize;
1116 
1117         if (lSeek!=0)
1118         {
1119             if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1120                 lSeek=0;
1121             else
1122                 err=UNZ_ERRNO;
1123         }
1124 
1125         if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1126             if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1127                 err=UNZ_ERRNO;
1128         lSeek+=file_info.size_file_comment - uSizeRead;
1129     }
1130     else
1131         lSeek+=file_info.size_file_comment;
1132 
1133 
1134     if ((err==UNZ_OK) && (pfile_info!=NULL))
1135         *pfile_info=file_info;
1136 
1137     if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1138         *pfile_info_internal=file_info_internal;
1139 
1140     return err;
1141 }
1142 
1143 
1144 
1145 /*
1146   Write info about the ZipFile in the *pglobal_info structure.
1147   No preparation of the structure is needed
1148   return UNZ_OK if there is no problem.
1149 */
unzGetCurrentFileInfo64(unzFile file,unz_file_info64 * pfile_info,char * szFileName,uLong fileNameBufferSize,void * extraField,uLong extraFieldBufferSize,char * szComment,uLong commentBufferSize)1150 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1151                                           unz_file_info64 * pfile_info,
1152                                           char * szFileName, uLong fileNameBufferSize,
1153                                           void *extraField, uLong extraFieldBufferSize,
1154                                           char* szComment,  uLong commentBufferSize)
1155 {
1156     return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1157                                                 szFileName,fileNameBufferSize,
1158                                                 extraField,extraFieldBufferSize,
1159                                                 szComment,commentBufferSize);
1160 }
1161 
unzGetCurrentFileInfo(unzFile file,unz_file_info * pfile_info,char * szFileName,uLong fileNameBufferSize,void * extraField,uLong extraFieldBufferSize,char * szComment,uLong commentBufferSize)1162 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1163                                           unz_file_info * pfile_info,
1164                                           char * szFileName, uLong fileNameBufferSize,
1165                                           void *extraField, uLong extraFieldBufferSize,
1166                                           char* szComment,  uLong commentBufferSize)
1167 {
1168     int err;
1169     unz_file_info64 file_info64;
1170     err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1171                                                 szFileName,fileNameBufferSize,
1172                                                 extraField,extraFieldBufferSize,
1173                                                 szComment,commentBufferSize);
1174     if ((err==UNZ_OK) && (pfile_info != NULL))
1175     {
1176         pfile_info->version = file_info64.version;
1177         pfile_info->version_needed = file_info64.version_needed;
1178         pfile_info->flag = file_info64.flag;
1179         pfile_info->compression_method = file_info64.compression_method;
1180         pfile_info->dosDate = file_info64.dosDate;
1181         pfile_info->crc = file_info64.crc;
1182 
1183         pfile_info->size_filename = file_info64.size_filename;
1184         pfile_info->size_file_extra = file_info64.size_file_extra;
1185         pfile_info->size_file_comment = file_info64.size_file_comment;
1186 
1187         pfile_info->disk_num_start = file_info64.disk_num_start;
1188         pfile_info->internal_fa = file_info64.internal_fa;
1189         pfile_info->external_fa = file_info64.external_fa;
1190 
1191         pfile_info->tmu_date = file_info64.tmu_date,
1192 
1193 
1194         pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1195         pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1196 
1197     }
1198     return err;
1199 }
1200 /*
1201   Set the current file of the zipfile to the first file.
1202   return UNZ_OK if there is no problem
1203 */
unzGoToFirstFile(unzFile file)1204 extern int ZEXPORT unzGoToFirstFile (unzFile file)
1205 {
1206     int err=UNZ_OK;
1207     unz64_s* s;
1208     if (file==NULL)
1209         return UNZ_PARAMERROR;
1210     s=(unz64_s*)file;
1211     s->pos_in_central_dir=s->offset_central_dir;
1212     s->num_file=0;
1213     err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1214                                              &s->cur_file_info_internal,
1215                                              NULL,0,NULL,0,NULL,0);
1216     s->current_file_ok = (err == UNZ_OK);
1217     return err;
1218 }
1219 
1220 /*
1221   Set the current file of the zipfile to the next file.
1222   return UNZ_OK if there is no problem
1223   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1224 */
unzGoToNextFile(unzFile file)1225 extern int ZEXPORT unzGoToNextFile (unzFile  file)
1226 {
1227     unz64_s* s;
1228     int err;
1229 
1230     if (file==NULL)
1231         return UNZ_PARAMERROR;
1232     s=(unz64_s*)file;
1233     if (!s->current_file_ok)
1234         return UNZ_END_OF_LIST_OF_FILE;
1235     if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
1236       if (s->num_file+1==s->gi.number_entry)
1237         return UNZ_END_OF_LIST_OF_FILE;
1238 
1239     s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1240             s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1241     s->num_file++;
1242     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1243                                                &s->cur_file_info_internal,
1244                                                NULL,0,NULL,0,NULL,0);
1245     s->current_file_ok = (err == UNZ_OK);
1246     return err;
1247 }
1248 
1249 
1250 /*
1251   Try locate the file szFileName in the zipfile.
1252   For the iCaseSensitivity signification, see unzStringFileNameCompare
1253 
1254   return value :
1255   UNZ_OK if the file is found. It becomes the current file.
1256   UNZ_END_OF_LIST_OF_FILE if the file is not found
1257 */
unzLocateFile(unzFile file,const char * szFileName,int iCaseSensitivity)1258 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1259 {
1260     unz64_s* s;
1261     int err;
1262 
1263     /* We remember the 'current' position in the file so that we can jump
1264      * back there if we fail.
1265      */
1266     unz_file_info64 cur_file_infoSaved;
1267     unz_file_info64_internal cur_file_info_internalSaved;
1268     ZPOS64_T num_fileSaved;
1269     ZPOS64_T pos_in_central_dirSaved;
1270 
1271 
1272     if (file==NULL)
1273         return UNZ_PARAMERROR;
1274 
1275     if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1276         return UNZ_PARAMERROR;
1277 
1278     s=(unz64_s*)file;
1279     if (!s->current_file_ok)
1280         return UNZ_END_OF_LIST_OF_FILE;
1281 
1282     /* Save the current state */
1283     num_fileSaved = s->num_file;
1284     pos_in_central_dirSaved = s->pos_in_central_dir;
1285     cur_file_infoSaved = s->cur_file_info;
1286     cur_file_info_internalSaved = s->cur_file_info_internal;
1287 
1288     err = unzGoToFirstFile(file);
1289 
1290     while (err == UNZ_OK)
1291     {
1292         char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1293         err = unzGetCurrentFileInfo64(file,NULL,
1294                                     szCurrentFileName,sizeof(szCurrentFileName)-1,
1295                                     NULL,0,NULL,0);
1296         if (err == UNZ_OK)
1297         {
1298             if (unzStringFileNameCompare(szCurrentFileName,
1299                                             szFileName,iCaseSensitivity)==0)
1300                 return UNZ_OK;
1301             err = unzGoToNextFile(file);
1302         }
1303     }
1304 
1305     /* We failed, so restore the state of the 'current file' to where we
1306      * were.
1307      */
1308     s->num_file = num_fileSaved ;
1309     s->pos_in_central_dir = pos_in_central_dirSaved ;
1310     s->cur_file_info = cur_file_infoSaved;
1311     s->cur_file_info_internal = cur_file_info_internalSaved;
1312     return err;
1313 }
1314 
1315 
1316 /*
1317 ///////////////////////////////////////////
1318 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1319 // I need random access
1320 //
1321 // Further optimization could be realized by adding an ability
1322 // to cache the directory in memory. The goal being a single
1323 // comprehensive file read to put the file I need in a memory.
1324 */
1325 
1326 /*
1327 typedef struct unz_file_pos_s
1328 {
1329     ZPOS64_T pos_in_zip_directory;   // offset in file
1330     ZPOS64_T num_of_file;            // # of file
1331 } unz_file_pos;
1332 */
1333 
unzGetFilePos64(unzFile file,unz64_file_pos * file_pos)1334 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
1335 {
1336     unz64_s* s;
1337 
1338     if (file==NULL || file_pos==NULL)
1339         return UNZ_PARAMERROR;
1340     s=(unz64_s*)file;
1341     if (!s->current_file_ok)
1342         return UNZ_END_OF_LIST_OF_FILE;
1343 
1344     file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
1345     file_pos->num_of_file           = s->num_file;
1346 
1347     return UNZ_OK;
1348 }
1349 
unzGetFilePos(unzFile file,unz_file_pos * file_pos)1350 extern int ZEXPORT unzGetFilePos(
1351     unzFile file,
1352     unz_file_pos* file_pos)
1353 {
1354     unz64_file_pos file_pos64;
1355     int err = unzGetFilePos64(file,&file_pos64);
1356     if (err==UNZ_OK)
1357     {
1358         file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1359         file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1360     }
1361     return err;
1362 }
1363 
unzGoToFilePos64(unzFile file,const unz64_file_pos * file_pos)1364 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1365 {
1366     unz64_s* s;
1367     int err;
1368 
1369     if (file==NULL || file_pos==NULL)
1370         return UNZ_PARAMERROR;
1371     s=(unz64_s*)file;
1372 
1373     /* jump to the right spot */
1374     s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1375     s->num_file           = file_pos->num_of_file;
1376 
1377     /* set the current file */
1378     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1379                                                &s->cur_file_info_internal,
1380                                                NULL,0,NULL,0,NULL,0);
1381     /* return results */
1382     s->current_file_ok = (err == UNZ_OK);
1383     return err;
1384 }
1385 
unzGoToFilePos(unzFile file,unz_file_pos * file_pos)1386 extern int ZEXPORT unzGoToFilePos(
1387     unzFile file,
1388     unz_file_pos* file_pos)
1389 {
1390     unz64_file_pos file_pos64;
1391     if (file_pos == NULL)
1392         return UNZ_PARAMERROR;
1393 
1394     file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1395     file_pos64.num_of_file = file_pos->num_of_file;
1396     return unzGoToFilePos64(file,&file_pos64);
1397 }
1398 
1399 /*
1400 // Unzip Helper Functions - should be here?
1401 ///////////////////////////////////////////
1402 */
1403 
1404 /*
1405   Read the local header of the current zipfile
1406   Check the coherency of the local header and info in the end of central
1407         directory about this file
1408   store in *piSizeVar the size of extra info in local header
1409         (filename and size of extra field data)
1410 */
unz64local_CheckCurrentFileCoherencyHeader(unz64_s * s,uInt * piSizeVar,ZPOS64_T * poffset_local_extrafield,uInt * psize_local_extrafield)1411 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1412                                                     ZPOS64_T * poffset_local_extrafield,
1413                                                     uInt  * psize_local_extrafield)
1414 {
1415     uLong uMagic,uData,uFlags;
1416     uLong size_filename;
1417     uLong size_extra_field;
1418     int err=UNZ_OK;
1419 
1420     *piSizeVar = 0;
1421     *poffset_local_extrafield = 0;
1422     *psize_local_extrafield = 0;
1423 
1424     if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1425                                 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1426         return UNZ_ERRNO;
1427 
1428 
1429     if (err==UNZ_OK)
1430     {
1431         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1432             err=UNZ_ERRNO;
1433         else if (uMagic!=0x04034b50)
1434             err=UNZ_BADZIPFILE;
1435     }
1436 
1437     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1438         err=UNZ_ERRNO;
1439 /*
1440     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1441         err=UNZ_BADZIPFILE;
1442 */
1443     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1444         err=UNZ_ERRNO;
1445 
1446     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1447         err=UNZ_ERRNO;
1448     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1449         err=UNZ_BADZIPFILE;
1450 
1451     if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1452 /* #ifdef HAVE_BZIP2 */
1453                          (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1454 /* #endif */
1455                          (s->cur_file_info.compression_method!=Z_DEFLATED))
1456         err=UNZ_BADZIPFILE;
1457 
1458     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1459         err=UNZ_ERRNO;
1460 
1461     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1462         err=UNZ_ERRNO;
1463     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1464         err=UNZ_BADZIPFILE;
1465 
1466     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1467         err=UNZ_ERRNO;
1468     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1469         err=UNZ_BADZIPFILE;
1470 
1471     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1472         err=UNZ_ERRNO;
1473     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1474         err=UNZ_BADZIPFILE;
1475 
1476     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1477         err=UNZ_ERRNO;
1478     else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1479         err=UNZ_BADZIPFILE;
1480 
1481     *piSizeVar += (uInt)size_filename;
1482 
1483     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1484         err=UNZ_ERRNO;
1485     *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1486                                     SIZEZIPLOCALHEADER + size_filename;
1487     *psize_local_extrafield = (uInt)size_extra_field;
1488 
1489     *piSizeVar += (uInt)size_extra_field;
1490 
1491     return err;
1492 }
1493 
1494 /*
1495   Open for reading data the current file in the zipfile.
1496   If there is no error and the file is opened, the return value is UNZ_OK.
1497 */
unzOpenCurrentFile3(unzFile file,int * method,int * level,int raw,const char * password)1498 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1499                                             int* level, int raw, const char* password)
1500 {
1501     int err=UNZ_OK;
1502     uInt iSizeVar;
1503     unz64_s* s;
1504     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1505     ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
1506     uInt  size_local_extrafield;    /* size of the local extra field */
1507 #    ifndef NOUNCRYPT
1508     char source[12];
1509 #    else
1510     if (password != NULL)
1511         return UNZ_PARAMERROR;
1512 #    endif
1513 
1514     if (file==NULL)
1515         return UNZ_PARAMERROR;
1516     s=(unz64_s*)file;
1517     if (!s->current_file_ok)
1518         return UNZ_PARAMERROR;
1519 
1520     if (s->pfile_in_zip_read != NULL)
1521         unzCloseCurrentFile(file);
1522 
1523     if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1524         return UNZ_BADZIPFILE;
1525 
1526     pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1527     if (pfile_in_zip_read_info==NULL)
1528         return UNZ_INTERNALERROR;
1529 
1530     pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1531     pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1532     pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1533     pfile_in_zip_read_info->pos_local_extrafield=0;
1534     pfile_in_zip_read_info->raw=raw;
1535 
1536     if (pfile_in_zip_read_info->read_buffer==NULL)
1537     {
1538         TRYFREE(pfile_in_zip_read_info);
1539         return UNZ_INTERNALERROR;
1540     }
1541 
1542     pfile_in_zip_read_info->stream_initialised=0;
1543 
1544     if (method!=NULL)
1545         *method = (int)s->cur_file_info.compression_method;
1546 
1547     if (level!=NULL)
1548     {
1549         *level = 6;
1550         switch (s->cur_file_info.flag & 0x06)
1551         {
1552           case 6 : *level = 1; break;
1553           case 4 : *level = 2; break;
1554           case 2 : *level = 9; break;
1555         }
1556     }
1557 
1558     if ((s->cur_file_info.compression_method!=0) &&
1559 /* #ifdef HAVE_BZIP2 */
1560         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1561 /* #endif */
1562         (s->cur_file_info.compression_method!=Z_DEFLATED))
1563 
1564         err=UNZ_BADZIPFILE;
1565 
1566     pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1567     pfile_in_zip_read_info->crc32=0;
1568     pfile_in_zip_read_info->total_out_64=0;
1569     pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1570     pfile_in_zip_read_info->filestream=s->filestream;
1571     pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1572     pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1573 
1574     pfile_in_zip_read_info->stream.total_out = 0;
1575 
1576     if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1577     {
1578 #ifdef HAVE_BZIP2
1579       pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1580       pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1581       pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1582       pfile_in_zip_read_info->bstream.state = (voidpf)0;
1583 
1584       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1585       pfile_in_zip_read_info->stream.zfree = (free_func)0;
1586       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1587       pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1588       pfile_in_zip_read_info->stream.avail_in = 0;
1589 
1590       err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1591       if (err == Z_OK)
1592         pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1593       else
1594       {
1595         TRYFREE(pfile_in_zip_read_info);
1596         return err;
1597       }
1598 #else
1599       pfile_in_zip_read_info->raw=1;
1600 #endif
1601     }
1602     else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1603     {
1604       /* GODOT start */
1605       pfile_in_zip_read_info->stream.zalloc = s->z_filefunc.zfile_func64.alloc_mem;
1606       pfile_in_zip_read_info->stream.zfree = s->z_filefunc.zfile_func64.free_mem;
1607       /* GODOT end */
1608       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1609       pfile_in_zip_read_info->stream.next_in = 0;
1610       pfile_in_zip_read_info->stream.avail_in = 0;
1611 
1612       err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1613       if (err == Z_OK)
1614         pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1615       else
1616       {
1617         TRYFREE(pfile_in_zip_read_info);
1618         return err;
1619       }
1620         /* windowBits is passed < 0 to tell that there is no zlib header.
1621          * Note that in this case inflate *requires* an extra "dummy" byte
1622          * after the compressed stream in order to complete decompression and
1623          * return Z_STREAM_END.
1624          * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1625          * size of both compressed and uncompressed data
1626          */
1627     }
1628     pfile_in_zip_read_info->rest_read_compressed =
1629             s->cur_file_info.compressed_size ;
1630     pfile_in_zip_read_info->rest_read_uncompressed =
1631             s->cur_file_info.uncompressed_size ;
1632 
1633 
1634     pfile_in_zip_read_info->pos_in_zipfile =
1635             s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1636               iSizeVar;
1637 
1638     pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1639     /* GODOT start */
1640     pfile_in_zip_read_info->extra_size = iSizeVar;
1641     /* GODOT end */
1642 
1643     s->pfile_in_zip_read = pfile_in_zip_read_info;
1644                 s->encrypted = 0;
1645 
1646 #    ifndef NOUNCRYPT
1647     if (password != NULL)
1648     {
1649         int i;
1650         s->pcrc_32_tab = get_crc_table();
1651         init_keys(password,s->keys,s->pcrc_32_tab);
1652         if (ZSEEK64(s->z_filefunc, s->filestream,
1653                   s->pfile_in_zip_read->pos_in_zipfile +
1654                      s->pfile_in_zip_read->byte_before_the_zipfile,
1655                   SEEK_SET)!=0)
1656             return UNZ_INTERNALERROR;
1657         if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1658             return UNZ_INTERNALERROR;
1659 
1660         for (i = 0; i<12; i++)
1661             zdecode(s->keys,s->pcrc_32_tab,source[i]);
1662 
1663         s->pfile_in_zip_read->pos_in_zipfile+=12;
1664         s->encrypted=1;
1665     }
1666 #    endif
1667 
1668 
1669     return UNZ_OK;
1670 }
1671 
1672 /* GODOT start */
unzSeekCurrentFile(unzFile file,int pos)1673 extern int ZEXPORT unzSeekCurrentFile(unzFile file, int pos) {
1674 
1675     unz64_s* s;
1676     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1677     if (file==NULL)
1678         return UNZ_PARAMERROR;
1679     s=(unz64_s*)file;
1680     pfile_in_zip_read_info=s->pfile_in_zip_read;
1681 
1682     if (pfile_in_zip_read_info==NULL)
1683         return UNZ_PARAMERROR;
1684 
1685     if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) { // don't know how to support bzip
1686         return UNZ_INTERNALERROR;
1687     };
1688 
1689     if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) {
1690 
1691         pfile_in_zip_read_info->rest_read_compressed =
1692                 s->cur_file_info.compressed_size - pos;
1693         pfile_in_zip_read_info->rest_read_uncompressed =
1694                 s->cur_file_info.uncompressed_size - pos;
1695 
1696         pfile_in_zip_read_info->pos_in_zipfile =
1697                 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1698                         pfile_in_zip_read_info->extra_size + pos;
1699 
1700         pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1701         pfile_in_zip_read_info->stream.total_out = pos;
1702 
1703         return ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1704                        pfile_in_zip_read_info->filestream,
1705                        pfile_in_zip_read_info->byte_before_the_zipfile + pfile_in_zip_read_info->pos_in_zipfile,
1706                        ZLIB_FILEFUNC_SEEK_SET);
1707 
1708     } else { // gzip
1709 
1710         if (pos < pfile_in_zip_read_info->stream.total_out) { // negative seek, rewind
1711 
1712             pfile_in_zip_read_info->rest_read_compressed =
1713                     s->cur_file_info.compressed_size ;
1714             pfile_in_zip_read_info->rest_read_uncompressed =
1715                     s->cur_file_info.uncompressed_size ;
1716 
1717             pfile_in_zip_read_info->pos_in_zipfile =
1718                     s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1719                             pfile_in_zip_read_info->extra_size;
1720 
1721             (void)inflateReset(&pfile_in_zip_read_info->stream);
1722 
1723             pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1724             pfile_in_zip_read_info->stream.total_out = 0;
1725             pfile_in_zip_read_info->stream.next_in = 0;
1726         };
1727 
1728         // not sure where to read, so read on the stack
1729         {
1730             char buf[512];
1731             int to_read = pos - pfile_in_zip_read_info->stream.total_out;
1732             while (to_read) {
1733 
1734                 int len = to_read > sizeof(buf)?sizeof(buf):to_read;
1735                 int read = unzReadCurrentFile(file, buf, len);
1736                 if (read < 0) {
1737                     return read;
1738                 };
1739                 to_read -= read;
1740                 if (read == UNZ_EOF) {
1741                     return pos;
1742                 };
1743             };
1744         };
1745     };
1746 
1747     return pos;
1748 };
1749 /* GODOT end */
1750 
unzOpenCurrentFile(unzFile file)1751 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1752 {
1753     return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1754 }
1755 
unzOpenCurrentFilePassword(unzFile file,const char * password)1756 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
1757 {
1758     return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1759 }
1760 
unzOpenCurrentFile2(unzFile file,int * method,int * level,int raw)1761 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1762 {
1763     return unzOpenCurrentFile3(file, method, level, raw, NULL);
1764 }
1765 
1766 /** Addition for GDAL : START */
1767 
unzGetCurrentFileZStreamPos64(unzFile file)1768 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1769 {
1770     unz64_s* s;
1771     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1772     s=(unz64_s*)file;
1773     if (file==NULL)
1774         return 0; //UNZ_PARAMERROR;
1775     pfile_in_zip_read_info=s->pfile_in_zip_read;
1776     if (pfile_in_zip_read_info==NULL)
1777         return 0; //UNZ_PARAMERROR;
1778     return pfile_in_zip_read_info->pos_in_zipfile +
1779                          pfile_in_zip_read_info->byte_before_the_zipfile;
1780 }
1781 
1782 /** Addition for GDAL : END */
1783 
1784 /*
1785   Read bytes from the current file.
1786   buf contain buffer where data must be copied
1787   len the size of buf.
1788 
1789   return the number of byte copied if somes bytes are copied
1790   return 0 if the end of file was reached
1791   return <0 with error code if there is an error
1792     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1793 */
unzReadCurrentFile(unzFile file,voidp buf,unsigned len)1794 extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
1795 {
1796     int err=UNZ_OK;
1797     uInt iRead = 0;
1798     unz64_s* s;
1799     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1800     if (file==NULL)
1801         return UNZ_PARAMERROR;
1802     s=(unz64_s*)file;
1803     pfile_in_zip_read_info=s->pfile_in_zip_read;
1804 
1805     if (pfile_in_zip_read_info==NULL)
1806         return UNZ_PARAMERROR;
1807 
1808 
1809     if (pfile_in_zip_read_info->read_buffer == NULL)
1810         return UNZ_END_OF_LIST_OF_FILE;
1811     if (len==0)
1812         return 0;
1813 
1814     pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1815 
1816     pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1817 
1818     if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1819         (!(pfile_in_zip_read_info->raw)))
1820         pfile_in_zip_read_info->stream.avail_out =
1821             (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1822 
1823     if ((len>pfile_in_zip_read_info->rest_read_compressed+
1824            pfile_in_zip_read_info->stream.avail_in) &&
1825          (pfile_in_zip_read_info->raw))
1826         pfile_in_zip_read_info->stream.avail_out =
1827             (uInt)pfile_in_zip_read_info->rest_read_compressed+
1828             pfile_in_zip_read_info->stream.avail_in;
1829 
1830     while (pfile_in_zip_read_info->stream.avail_out>0)
1831     {
1832         if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1833             (pfile_in_zip_read_info->rest_read_compressed>0))
1834         {
1835             uInt uReadThis = UNZ_BUFSIZE;
1836             if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1837                 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1838             if (uReadThis == 0)
1839                 return UNZ_EOF;
1840             if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1841                       pfile_in_zip_read_info->filestream,
1842                       pfile_in_zip_read_info->pos_in_zipfile +
1843                          pfile_in_zip_read_info->byte_before_the_zipfile,
1844                          ZLIB_FILEFUNC_SEEK_SET)!=0)
1845                 return UNZ_ERRNO;
1846             if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1847                       pfile_in_zip_read_info->filestream,
1848                       pfile_in_zip_read_info->read_buffer,
1849                       uReadThis)!=uReadThis)
1850                 return UNZ_ERRNO;
1851 
1852 
1853 #            ifndef NOUNCRYPT
1854             if(s->encrypted)
1855             {
1856                 uInt i;
1857                 for(i=0;i<uReadThis;i++)
1858                   pfile_in_zip_read_info->read_buffer[i] =
1859                       zdecode(s->keys,s->pcrc_32_tab,
1860                               pfile_in_zip_read_info->read_buffer[i]);
1861             }
1862 #            endif
1863 
1864 
1865             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1866 
1867             pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1868 
1869             pfile_in_zip_read_info->stream.next_in =
1870                 (Bytef*)pfile_in_zip_read_info->read_buffer;
1871             pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1872         }
1873 
1874         if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1875         {
1876             uInt uDoCopy,i ;
1877 
1878             if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1879                 (pfile_in_zip_read_info->rest_read_compressed == 0))
1880                 return (iRead==0) ? UNZ_EOF : iRead;
1881 
1882             if (pfile_in_zip_read_info->stream.avail_out <
1883                             pfile_in_zip_read_info->stream.avail_in)
1884                 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1885             else
1886                 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1887 
1888             for (i=0;i<uDoCopy;i++)
1889                 *(pfile_in_zip_read_info->stream.next_out+i) =
1890                         *(pfile_in_zip_read_info->stream.next_in+i);
1891 
1892             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1893 
1894             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1895                                 pfile_in_zip_read_info->stream.next_out,
1896                                 uDoCopy);
1897             pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1898             pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1899             pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1900             pfile_in_zip_read_info->stream.next_out += uDoCopy;
1901             pfile_in_zip_read_info->stream.next_in += uDoCopy;
1902             pfile_in_zip_read_info->stream.total_out += uDoCopy;
1903             iRead += uDoCopy;
1904         }
1905         else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1906         {
1907 #ifdef HAVE_BZIP2
1908             uLong uTotalOutBefore,uTotalOutAfter;
1909             const Bytef *bufBefore;
1910             uLong uOutThis;
1911 
1912             pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
1913             pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
1914             pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
1915             pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
1916             pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
1917             pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
1918             pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1919             pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1920 
1921             uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1922             bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1923 
1924             err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1925 
1926             uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1927             uOutThis = uTotalOutAfter-uTotalOutBefore;
1928 
1929             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1930 
1931             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1932             pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1933             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1934 
1935             pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1936             pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
1937             pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
1938             pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1939             pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1940             pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1941 
1942             if (err==BZ_STREAM_END)
1943               return (iRead==0) ? UNZ_EOF : iRead;
1944             if (err!=BZ_OK)
1945               break;
1946 #endif
1947         } // end Z_BZIP2ED
1948         else
1949         {
1950             ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1951             const Bytef *bufBefore;
1952             ZPOS64_T uOutThis;
1953             int flush=Z_SYNC_FLUSH;
1954 
1955             uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1956             bufBefore = pfile_in_zip_read_info->stream.next_out;
1957 
1958             /*
1959             if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1960                      pfile_in_zip_read_info->stream.avail_out) &&
1961                 (pfile_in_zip_read_info->rest_read_compressed == 0))
1962                 flush = Z_FINISH;
1963             */
1964             err=inflate(&pfile_in_zip_read_info->stream,flush);
1965 
1966             if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1967               err = Z_DATA_ERROR;
1968 
1969             uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1970             uOutThis = uTotalOutAfter-uTotalOutBefore;
1971 
1972             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1973 
1974             pfile_in_zip_read_info->crc32 =
1975                 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1976                         (uInt)(uOutThis));
1977 
1978             pfile_in_zip_read_info->rest_read_uncompressed -=
1979                 uOutThis;
1980 
1981             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1982 
1983             if (err==Z_STREAM_END)
1984                 return (iRead==0) ? UNZ_EOF : iRead;
1985             if (err!=Z_OK)
1986                 break;
1987         }
1988     }
1989 
1990     if (err==Z_OK)
1991         return iRead;
1992     return err;
1993 }
1994 
1995 
1996 /*
1997   Give the current position in uncompressed data
1998 */
unztell(unzFile file)1999 extern z_off_t ZEXPORT unztell (unzFile file)
2000 {
2001     unz64_s* s;
2002     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2003     if (file==NULL)
2004         return UNZ_PARAMERROR;
2005     s=(unz64_s*)file;
2006     pfile_in_zip_read_info=s->pfile_in_zip_read;
2007 
2008     if (pfile_in_zip_read_info==NULL)
2009         return UNZ_PARAMERROR;
2010 
2011     return (z_off_t)pfile_in_zip_read_info->stream.total_out;
2012 }
2013 
unztell64(unzFile file)2014 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
2015 {
2016 
2017     unz64_s* s;
2018     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2019     if (file==NULL)
2020         return (ZPOS64_T)-1;
2021     s=(unz64_s*)file;
2022     pfile_in_zip_read_info=s->pfile_in_zip_read;
2023 
2024     if (pfile_in_zip_read_info==NULL)
2025         return (ZPOS64_T)-1;
2026 
2027     return pfile_in_zip_read_info->total_out_64;
2028 }
2029 
2030 
2031 /*
2032   return 1 if the end of file was reached, 0 elsewhere
2033 */
unzeof(unzFile file)2034 extern int ZEXPORT unzeof (unzFile file)
2035 {
2036     unz64_s* s;
2037     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2038     if (file==NULL)
2039         return UNZ_PARAMERROR;
2040     s=(unz64_s*)file;
2041     pfile_in_zip_read_info=s->pfile_in_zip_read;
2042 
2043     if (pfile_in_zip_read_info==NULL)
2044         return UNZ_PARAMERROR;
2045 
2046     if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
2047         return 1;
2048     else
2049         return 0;
2050 }
2051 
2052 
2053 
2054 /*
2055 Read extra field from the current file (opened by unzOpenCurrentFile)
2056 This is the local-header version of the extra field (sometimes, there is
2057 more info in the local-header version than in the central-header)
2058 
2059   if buf==NULL, it return the size of the local extra field that can be read
2060 
2061   if buf!=NULL, len is the size of the buffer, the extra header is copied in
2062     buf.
2063   the return value is the number of bytes copied in buf, or (if <0)
2064     the error code
2065 */
unzGetLocalExtrafield(unzFile file,voidp buf,unsigned len)2066 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
2067 {
2068     unz64_s* s;
2069     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2070     uInt read_now;
2071     ZPOS64_T size_to_read;
2072 
2073     if (file==NULL)
2074         return UNZ_PARAMERROR;
2075     s=(unz64_s*)file;
2076     pfile_in_zip_read_info=s->pfile_in_zip_read;
2077 
2078     if (pfile_in_zip_read_info==NULL)
2079         return UNZ_PARAMERROR;
2080 
2081     size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
2082                 pfile_in_zip_read_info->pos_local_extrafield);
2083 
2084     if (buf==NULL)
2085         return (int)size_to_read;
2086 
2087     if (len>size_to_read)
2088         read_now = (uInt)size_to_read;
2089     else
2090         read_now = (uInt)len ;
2091 
2092     if (read_now==0)
2093         return 0;
2094 
2095     if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
2096               pfile_in_zip_read_info->filestream,
2097               pfile_in_zip_read_info->offset_local_extrafield +
2098               pfile_in_zip_read_info->pos_local_extrafield,
2099               ZLIB_FILEFUNC_SEEK_SET)!=0)
2100         return UNZ_ERRNO;
2101 
2102     if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
2103               pfile_in_zip_read_info->filestream,
2104               buf,read_now)!=read_now)
2105         return UNZ_ERRNO;
2106 
2107     return (int)read_now;
2108 }
2109 
2110 /*
2111   Close the file in zip opened with unzOpenCurrentFile
2112   Return UNZ_CRCERROR if all the file was read but the CRC is not good
2113 */
unzCloseCurrentFile(unzFile file)2114 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2115 {
2116     int err=UNZ_OK;
2117 
2118     unz64_s* s;
2119     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2120     if (file==NULL)
2121         return UNZ_PARAMERROR;
2122     s=(unz64_s*)file;
2123     pfile_in_zip_read_info=s->pfile_in_zip_read;
2124 
2125     if (pfile_in_zip_read_info==NULL)
2126         return UNZ_PARAMERROR;
2127 
2128 
2129     if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2130         (!pfile_in_zip_read_info->raw))
2131     {
2132         if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2133             err=UNZ_CRCERROR;
2134     }
2135 
2136 
2137     TRYFREE(pfile_in_zip_read_info->read_buffer);
2138     pfile_in_zip_read_info->read_buffer = NULL;
2139     if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2140         inflateEnd(&pfile_in_zip_read_info->stream);
2141 #ifdef HAVE_BZIP2
2142     else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2143         BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2144 #endif
2145 
2146 
2147     pfile_in_zip_read_info->stream_initialised = 0;
2148     TRYFREE(pfile_in_zip_read_info);
2149 
2150     s->pfile_in_zip_read=NULL;
2151 
2152     return err;
2153 }
2154 
2155 
2156 /*
2157   Get the global comment string of the ZipFile, in the szComment buffer.
2158   uSizeBuf is the size of the szComment buffer.
2159   return the number of byte copied or an error code <0
2160 */
unzGetGlobalComment(unzFile file,char * szComment,uLong uSizeBuf)2161 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2162 {
2163     unz64_s* s;
2164     uLong uReadThis ;
2165     if (file==NULL)
2166         return (int)UNZ_PARAMERROR;
2167     s=(unz64_s*)file;
2168 
2169     uReadThis = uSizeBuf;
2170     if (uReadThis>s->gi.size_comment)
2171         uReadThis = s->gi.size_comment;
2172 
2173     if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2174         return UNZ_ERRNO;
2175 
2176     if (uReadThis>0)
2177     {
2178       *szComment='\0';
2179       if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2180         return UNZ_ERRNO;
2181     }
2182 
2183     if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2184         *(szComment+s->gi.size_comment)='\0';
2185     return (int)uReadThis;
2186 }
2187 
2188 /* Additions by RX '2004 */
unzGetOffset64(unzFile file)2189 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2190 {
2191     unz64_s* s;
2192 
2193     if (file==NULL)
2194           return 0; //UNZ_PARAMERROR;
2195     s=(unz64_s*)file;
2196     if (!s->current_file_ok)
2197       return 0;
2198     if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2199       if (s->num_file==s->gi.number_entry)
2200          return 0;
2201     return s->pos_in_central_dir;
2202 }
2203 
unzGetOffset(unzFile file)2204 extern uLong ZEXPORT unzGetOffset (unzFile file)
2205 {
2206     ZPOS64_T offset64;
2207 
2208     if (file==NULL)
2209           return 0; //UNZ_PARAMERROR;
2210     offset64 = unzGetOffset64(file);
2211     return (uLong)offset64;
2212 }
2213 
unzSetOffset64(unzFile file,ZPOS64_T pos)2214 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2215 {
2216     unz64_s* s;
2217     int err;
2218 
2219     if (file==NULL)
2220         return UNZ_PARAMERROR;
2221     s=(unz64_s*)file;
2222 
2223     s->pos_in_central_dir = pos;
2224     s->num_file = s->gi.number_entry;      /* hack */
2225     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2226                                               &s->cur_file_info_internal,
2227                                               NULL,0,NULL,0,NULL,0);
2228     s->current_file_ok = (err == UNZ_OK);
2229     return err;
2230 }
2231 
unzSetOffset(unzFile file,uLong pos)2232 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2233 {
2234     return unzSetOffset64(file,pos);
2235 }
2236