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