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