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