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