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