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