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