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