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