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