blob: e8b2bc5c766c8aed7b1d7db902efcdd076122c5f [file] [log] [blame]
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001/* unzip.c -- IO for uncompress .zip files using zlib
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
erikkay@google.com19ba4a52008-12-30 00:40:04 +00004
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00005 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
erikkay@google.com19ba4a52008-12-30 00:40:04 +00006
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00007 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
erikkay@google.com19ba4a52008-12-30 00:40:04 +00009
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +000010 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
erikkay@google.com19ba4a52008-12-30 00:40:04 +000021 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
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +000027
28 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
erikkay@google.com19ba4a52008-12-30 00:40:04 +000029
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.)
erikkay@google.com19ba4a52008-12-30 00:40:04 +000034
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +000035 This encryption code is a direct transcription of the algorithm from
erikkay@google.com19ba4a52008-12-30 00:40:04 +000036 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).
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +000039
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*/
erikkay@google.com19ba4a52008-12-30 00:40:04 +000065
66
67#include <stdio.h>
68#include <stdlib.h>
69#include <string.h>
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +000070
erikkay@google.com8c6279b2009-01-29 00:06:47 +000071#include "third_party/zlib/zlib.h"
erikkay@google.com19ba4a52008-12-30 00:40:04 +000072#include "unzip.h"
73
74#ifdef STDC
75# include <stddef.h>
76# include <string.h>
77# include <stdlib.h>
78#endif
79#ifdef NO_ERRNO_H
80 extern int errno;
81#else
82# include <errno.h>
83#endif
84
85
86#ifndef local
87# define local static
88#endif
89/* compile with -Dlocal if your debugger can't find static symbols */
90
91
92#ifndef CASESENSITIVITYDEFAULT_NO
93# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
94# define CASESENSITIVITYDEFAULT_NO
95# endif
96#endif
97
98
99#ifndef UNZ_BUFSIZE
100#define UNZ_BUFSIZE (16384)
101#endif
102
103#ifndef UNZ_MAXFILENAMEINZIP
104#define UNZ_MAXFILENAMEINZIP (256)
105#endif
106
107#ifndef ALLOC
108# define ALLOC(size) (malloc(size))
109#endif
110#ifndef TRYFREE
111# define TRYFREE(p) {if (p) free(p);}
112#endif
113
114#define SIZECENTRALDIRITEM (0x2e)
115#define SIZEZIPLOCALHEADER (0x1e)
116
117
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000118const char unz_copyright[] =
119 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
120
121/* unz_file_info_interntal contain internal info about a file in zipfile*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000122typedef struct unz_file_info64_internal_s
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000123{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000124 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
125} unz_file_info64_internal;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000126
127
128/* file_in_zip_read_info_s contain internal information about a file in zipfile,
129 when reading and decompress it */
130typedef struct
131{
132 char *read_buffer; /* internal buffer for compressed data */
133 z_stream stream; /* zLib stream structure for inflate */
134
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000135#ifdef HAVE_BZIP2
136 bz_stream bstream; /* bzLib stream structure for bziped */
137#endif
138
139 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000140 uLong stream_initialised; /* flag set if stream structure is initialised*/
141
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000142 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000143 uInt size_local_extrafield;/* size of the local extra field */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000144 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
145 ZPOS64_T total_out_64;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000146
147 uLong crc32; /* crc32 of all data uncompressed */
148 uLong crc32_wait; /* crc32 we must obtain after decompress all */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000149 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
150 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
151 zlib_filefunc64_32_def z_filefunc;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000152 voidpf filestream; /* io structore of the zipfile */
153 uLong compression_method; /* compression method (0==store) */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000154 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000155 int raw;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000156} file_in_zip64_read_info_s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000157
158
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000159/* unz64_s contain internal information about the zipfile
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000160*/
161typedef struct
162{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000163 zlib_filefunc64_32_def z_filefunc;
164 int is64bitOpenFunction;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000165 voidpf filestream; /* io structore of the zipfile */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000166 unz_global_info64 gi; /* public global information */
167 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
168 ZPOS64_T num_file; /* number of the current file in the zipfile*/
169 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
170 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
171 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000172
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000173 ZPOS64_T size_central_dir; /* size of the central directory */
174 ZPOS64_T offset_central_dir; /* offset of start of central directory with
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000175 respect to the starting disk number */
176
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000177 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
178 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
179 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000180 file if we are decompressing it */
181 int encrypted;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000182
183 int isZip64;
184
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000185# ifndef NOUNCRYPT
186 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
jiadong.zhu6c142162016-06-22 21:22:18 -0700187 const z_crc_t* pcrc_32_tab;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000188# endif
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000189} unz64_s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000190
191
192#ifndef NOUNCRYPT
193#include "crypt.h"
194#endif
195
196/* ===========================================================================
197 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
198 for end of file.
mark13dc2462017-02-14 22:15:29 -0800199 IN assertion: the stream s has been successfully opened for reading.
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000200*/
201
202
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000203local int unz64local_getByte OF((
204 const zlib_filefunc64_32_def* pzlib_filefunc_def,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000205 voidpf filestream,
206 int *pi));
207
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000208local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000209{
210 unsigned char c;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000211 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000212 if (err==1)
213 {
214 *pi = (int)c;
215 return UNZ_OK;
216 }
217 else
218 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000219 if (ZERROR64(*pzlib_filefunc_def,filestream))
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000220 return UNZ_ERRNO;
221 else
222 return UNZ_EOF;
223 }
224}
225
226
227/* ===========================================================================
228 Reads a long in LSB order from the given gz_stream. Sets
229*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000230local int unz64local_getShort OF((
231 const zlib_filefunc64_32_def* pzlib_filefunc_def,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000232 voidpf filestream,
233 uLong *pX));
234
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000235local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
236 voidpf filestream,
237 uLong *pX)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000238{
239 uLong x ;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000240 int i = 0;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000241 int err;
242
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000243 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000244 x = (uLong)i;
245
246 if (err==UNZ_OK)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000247 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
248 x |= ((uLong)i)<<8;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000249
250 if (err==UNZ_OK)
251 *pX = x;
252 else
253 *pX = 0;
254 return err;
255}
256
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000257local int unz64local_getLong OF((
258 const zlib_filefunc64_32_def* pzlib_filefunc_def,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000259 voidpf filestream,
260 uLong *pX));
261
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000262local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
263 voidpf filestream,
264 uLong *pX)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000265{
266 uLong x ;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000267 int i = 0;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000268 int err;
269
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000270 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000271 x = (uLong)i;
272
273 if (err==UNZ_OK)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000274 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
275 x |= ((uLong)i)<<8;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000276
277 if (err==UNZ_OK)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000278 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
279 x |= ((uLong)i)<<16;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000280
281 if (err==UNZ_OK)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000282 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000283 x += ((uLong)i)<<24;
284
285 if (err==UNZ_OK)
286 *pX = x;
287 else
288 *pX = 0;
289 return err;
290}
291
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000292local int unz64local_getLong64 OF((
293 const zlib_filefunc64_32_def* pzlib_filefunc_def,
294 voidpf filestream,
295 ZPOS64_T *pX));
296
297
298local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
299 voidpf filestream,
300 ZPOS64_T *pX)
301{
302 ZPOS64_T x ;
303 int i = 0;
304 int err;
305
306 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
307 x = (ZPOS64_T)i;
308
309 if (err==UNZ_OK)
310 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
311 x |= ((ZPOS64_T)i)<<8;
312
313 if (err==UNZ_OK)
314 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
315 x |= ((ZPOS64_T)i)<<16;
316
317 if (err==UNZ_OK)
318 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
319 x |= ((ZPOS64_T)i)<<24;
320
321 if (err==UNZ_OK)
322 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
323 x |= ((ZPOS64_T)i)<<32;
324
325 if (err==UNZ_OK)
326 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
327 x |= ((ZPOS64_T)i)<<40;
328
329 if (err==UNZ_OK)
330 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
331 x |= ((ZPOS64_T)i)<<48;
332
333 if (err==UNZ_OK)
334 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
335 x |= ((ZPOS64_T)i)<<56;
336
337 if (err==UNZ_OK)
338 *pX = x;
339 else
340 *pX = 0;
341 return err;
342}
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000343
344/* My own strcmpi / strcasecmp */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000345local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000346{
347 for (;;)
348 {
349 char c1=*(fileName1++);
350 char c2=*(fileName2++);
351 if ((c1>='a') && (c1<='z'))
352 c1 -= 0x20;
353 if ((c2>='a') && (c2<='z'))
354 c2 -= 0x20;
355 if (c1=='\0')
356 return ((c2=='\0') ? 0 : -1);
357 if (c2=='\0')
358 return 1;
359 if (c1<c2)
360 return -1;
361 if (c1>c2)
362 return 1;
363 }
364}
365
366
367#ifdef CASESENSITIVITYDEFAULT_NO
368#define CASESENSITIVITYDEFAULTVALUE 2
369#else
370#define CASESENSITIVITYDEFAULTVALUE 1
371#endif
372
373#ifndef STRCMPCASENOSENTIVEFUNCTION
374#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
375#endif
376
377/*
378 Compare two filename (fileName1,fileName2).
379 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
380 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
381 or strcasecmp)
382 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
383 (like 1 on Unix, 2 on Windows)
384
385*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000386extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
387 const char* fileName2,
388 int iCaseSensitivity)
389
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000390{
391 if (iCaseSensitivity==0)
392 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
393
394 if (iCaseSensitivity==1)
395 return strcmp(fileName1,fileName2);
396
397 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
398}
399
400#ifndef BUFREADCOMMENT
401#define BUFREADCOMMENT (0x400)
402#endif
403
404/*
405 Locate the Central directory of a zipfile (at the end, just before
406 the global comment)
407*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000408local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
409local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000410{
411 unsigned char* buf;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000412 ZPOS64_T uSizeFile;
413 ZPOS64_T uBackRead;
414 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
415 ZPOS64_T uPosFound=0;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000416
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000417 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000418 return 0;
419
420
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000421 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000422
423 if (uMaxBack>uSizeFile)
424 uMaxBack = uSizeFile;
425
426 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
427 if (buf==NULL)
428 return 0;
429
430 uBackRead = 4;
431 while (uBackRead<uMaxBack)
432 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000433 uLong uReadSize;
434 ZPOS64_T uReadPos ;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000435 int i;
436 if (uBackRead+BUFREADCOMMENT>uMaxBack)
437 uBackRead = uMaxBack;
438 else
439 uBackRead+=BUFREADCOMMENT;
440 uReadPos = uSizeFile-uBackRead ;
441
442 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000443 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
444 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000445 break;
446
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000447 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000448 break;
449
450 for (i=(int)uReadSize-3; (i--)>0;)
451 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
452 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
453 {
454 uPosFound = uReadPos+i;
455 break;
456 }
457
458 if (uPosFound!=0)
459 break;
460 }
461 TRYFREE(buf);
462 return uPosFound;
463}
464
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000465
466/*
467 Locate the Central directory 64 of a zipfile (at the end, just before
468 the global comment)
469*/
470local ZPOS64_T unz64local_SearchCentralDir64 OF((
471 const zlib_filefunc64_32_def* pzlib_filefunc_def,
472 voidpf filestream));
473
474local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
475 voidpf filestream)
476{
477 unsigned char* buf;
478 ZPOS64_T uSizeFile;
479 ZPOS64_T uBackRead;
480 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
481 ZPOS64_T uPosFound=0;
482 uLong uL;
483 ZPOS64_T relativeOffset;
484
485 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
486 return 0;
487
488
489 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
490
491 if (uMaxBack>uSizeFile)
492 uMaxBack = uSizeFile;
493
494 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
495 if (buf==NULL)
496 return 0;
497
498 uBackRead = 4;
499 while (uBackRead<uMaxBack)
500 {
501 uLong uReadSize;
502 ZPOS64_T uReadPos;
503 int i;
504 if (uBackRead+BUFREADCOMMENT>uMaxBack)
505 uBackRead = uMaxBack;
506 else
507 uBackRead+=BUFREADCOMMENT;
508 uReadPos = uSizeFile-uBackRead ;
509
510 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
511 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
512 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
513 break;
514
515 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
516 break;
517
518 for (i=(int)uReadSize-3; (i--)>0;)
519 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
520 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
521 {
522 uPosFound = uReadPos+i;
523 break;
524 }
525
526 if (uPosFound!=0)
527 break;
528 }
529 TRYFREE(buf);
530 if (uPosFound == 0)
531 return 0;
532
533 /* Zip64 end of central directory locator */
534 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
535 return 0;
536
537 /* the signature, already checked */
538 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
539 return 0;
540
541 /* number of the disk with the start of the zip64 end of central directory */
542 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
543 return 0;
544 if (uL != 0)
545 return 0;
546
547 /* relative offset of the zip64 end of central directory record */
548 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
549 return 0;
550
551 /* total number of disks */
552 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
553 return 0;
554 if (uL != 1)
555 return 0;
556
557 /* Goto end of central directory record */
558 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
559 return 0;
560
561 /* the signature */
562 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
563 return 0;
564
565 if (uL != 0x06064b50)
566 return 0;
567
568 return relativeOffset;
569}
570
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000571/*
572 Open a Zip file. path contain the full pathname (by example,
573 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
574 "zlib/zlib114.zip".
575 If the zipfile cannot be opened (file doesn't exist or in not valid), the
576 return value is NULL.
577 Else, the return value is a unzFile Handle, usable with other function
578 of this unzip package.
579*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000580local unzFile unzOpenInternal (const void *path,
581 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
582 int is64bitOpenFunction)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000583{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000584 unz64_s us;
585 unz64_s *s;
586 ZPOS64_T central_pos;
587 uLong uL;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000588
589 uLong number_disk; /* number of the current dist, used for
590 spaning ZIP, unsupported, always 0*/
591 uLong number_disk_with_CD; /* number the the disk with central dir, used
592 for spaning ZIP, unsupported, always 0*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000593 ZPOS64_T number_entry_CD; /* total number of entries in
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000594 the central dir
595 (same than number_entry on nospan) */
596
597 int err=UNZ_OK;
598
599 if (unz_copyright[0]!=' ')
600 return NULL;
601
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000602 us.z_filefunc.zseek32_file = NULL;
603 us.z_filefunc.ztell32_file = NULL;
604 if (pzlib_filefunc64_32_def==NULL)
605 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000606 else
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000607 us.z_filefunc = *pzlib_filefunc64_32_def;
608 us.is64bitOpenFunction = is64bitOpenFunction;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000609
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000610
611
612 us.filestream = ZOPEN64(us.z_filefunc,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000613 path,
614 ZLIB_FILEFUNC_MODE_READ |
615 ZLIB_FILEFUNC_MODE_EXISTING);
616 if (us.filestream==NULL)
617 return NULL;
618
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000619 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
620 if (central_pos)
621 {
622 uLong uS;
623 ZPOS64_T uL64;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000624
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000625 us.isZip64 = 1;
626
627 if (ZSEEK64(us.z_filefunc, us.filestream,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000628 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
629 err=UNZ_ERRNO;
630
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000631 /* the signature, already checked */
632 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
633 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000634
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000635 /* size of zip64 end of central directory record */
636 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
637 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000638
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000639 /* version made by */
640 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
641 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000642
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000643 /* version needed to extract */
644 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
645 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000646
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000647 /* number of this disk */
648 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
649 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000650
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000651 /* number of the disk with the start of the central directory */
652 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
653 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000654
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000655 /* total number of entries in the central directory on this disk */
656 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
657 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000658
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000659 /* total number of entries in the central directory */
660 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
661 err=UNZ_ERRNO;
662
663 if ((number_entry_CD!=us.gi.number_entry) ||
664 (number_disk_with_CD!=0) ||
665 (number_disk!=0))
666 err=UNZ_BADZIPFILE;
667
668 /* size of the central directory */
669 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
670 err=UNZ_ERRNO;
671
672 /* offset of start of central directory with respect to the
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000673 starting disk number */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000674 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
675 err=UNZ_ERRNO;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000676
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000677 us.gi.size_comment = 0;
678 }
679 else
680 {
681 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
682 if (central_pos==0)
683 err=UNZ_ERRNO;
684
685 us.isZip64 = 0;
686
687 if (ZSEEK64(us.z_filefunc, us.filestream,
688 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
689 err=UNZ_ERRNO;
690
691 /* the signature, already checked */
692 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
693 err=UNZ_ERRNO;
694
695 /* number of this disk */
696 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
697 err=UNZ_ERRNO;
698
699 /* number of the disk with the start of the central directory */
700 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
701 err=UNZ_ERRNO;
702
703 /* total number of entries in the central dir on this disk */
704 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
705 err=UNZ_ERRNO;
706 us.gi.number_entry = uL;
707
708 /* total number of entries in the central dir */
709 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
710 err=UNZ_ERRNO;
711 number_entry_CD = uL;
712
713 if ((number_entry_CD!=us.gi.number_entry) ||
714 (number_disk_with_CD!=0) ||
715 (number_disk!=0))
716 err=UNZ_BADZIPFILE;
717
718 /* size of the central directory */
719 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
720 err=UNZ_ERRNO;
721 us.size_central_dir = uL;
722
723 /* offset of start of central directory with respect to the
724 starting disk number */
725 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
726 err=UNZ_ERRNO;
727 us.offset_central_dir = uL;
728
729 /* zipfile comment length */
730 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
731 err=UNZ_ERRNO;
732 }
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000733
734 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
735 (err==UNZ_OK))
736 err=UNZ_BADZIPFILE;
737
738 if (err!=UNZ_OK)
739 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000740 ZCLOSE64(us.z_filefunc, us.filestream);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000741 return NULL;
742 }
743
744 us.byte_before_the_zipfile = central_pos -
745 (us.offset_central_dir+us.size_central_dir);
746 us.central_pos = central_pos;
747 us.pfile_in_zip_read = NULL;
748 us.encrypted = 0;
749
750
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000751 s=(unz64_s*)ALLOC(sizeof(unz64_s));
752 if( s != NULL)
753 {
754 *s=us;
755 unzGoToFirstFile((unzFile)s);
756 }
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000757 return (unzFile)s;
758}
759
760
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000761extern unzFile ZEXPORT unzOpen2 (const char *path,
762 zlib_filefunc_def* pzlib_filefunc32_def)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000763{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000764 if (pzlib_filefunc32_def != NULL)
765 {
766 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
767 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
768 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
769 }
770 else
771 return unzOpenInternal(path, NULL, 0);
772}
773
774extern unzFile ZEXPORT unzOpen2_64 (const void *path,
775 zlib_filefunc64_def* pzlib_filefunc_def)
776{
777 if (pzlib_filefunc_def != NULL)
778 {
779 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
780 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
781 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
782 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
783 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
784 }
785 else
786 return unzOpenInternal(path, NULL, 1);
787}
788
789extern unzFile ZEXPORT unzOpen (const char *path)
790{
791 return unzOpenInternal(path, NULL, 0);
792}
793
794extern unzFile ZEXPORT unzOpen64 (const void *path)
795{
796 return unzOpenInternal(path, NULL, 1);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000797}
798
799/*
jiadong.zhu6c142162016-06-22 21:22:18 -0700800 Close a ZipFile opened with unzOpen.
801 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
802 these files MUST be closed with unzCloseCurrentFile before call unzClose.
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000803 return UNZ_OK if there is no problem. */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000804extern int ZEXPORT unzClose (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000805{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000806 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000807 if (file==NULL)
808 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000809 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000810
811 if (s->pfile_in_zip_read!=NULL)
812 unzCloseCurrentFile(file);
813
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000814 ZCLOSE64(s->z_filefunc, s->filestream);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000815 TRYFREE(s);
816 return UNZ_OK;
817}
818
819
820/*
821 Write info about the ZipFile in the *pglobal_info structure.
822 No preparation of the structure is needed
823 return UNZ_OK if there is no problem. */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000824extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000825{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000826 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000827 if (file==NULL)
828 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000829 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000830 *pglobal_info=s->gi;
831 return UNZ_OK;
832}
833
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000834extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
835{
836 unz64_s* s;
837 if (file==NULL)
838 return UNZ_PARAMERROR;
839 s=(unz64_s*)file;
840 /* to do : check if number_entry is not truncated */
841 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
842 pglobal_info32->size_comment = s->gi.size_comment;
843 return UNZ_OK;
844}
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000845/*
846 Translate date/time from Dos format to tm_unz (readable more easilty)
847*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000848local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000849{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000850 ZPOS64_T uDate;
851 uDate = (ZPOS64_T)(ulDosDate>>16);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000852 ptm->tm_mday = (uInt)(uDate&0x1f) ;
853 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
854 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
855
856 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
857 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
858 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
859}
860
861/*
862 Get Info about the current file in the zipfile, with internal only info
863*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000864local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
865 unz_file_info64 *pfile_info,
866 unz_file_info64_internal
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000867 *pfile_info_internal,
868 char *szFileName,
869 uLong fileNameBufferSize,
870 void *extraField,
871 uLong extraFieldBufferSize,
872 char *szComment,
873 uLong commentBufferSize));
874
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000875local int unz64local_GetCurrentFileInfoInternal (unzFile file,
876 unz_file_info64 *pfile_info,
877 unz_file_info64_internal
878 *pfile_info_internal,
879 char *szFileName,
880 uLong fileNameBufferSize,
881 void *extraField,
882 uLong extraFieldBufferSize,
883 char *szComment,
884 uLong commentBufferSize)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000885{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000886 unz64_s* s;
887 unz_file_info64 file_info;
888 unz_file_info64_internal file_info_internal;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000889 int err=UNZ_OK;
890 uLong uMagic;
891 long lSeek=0;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000892 uLong uL;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000893
894 if (file==NULL)
895 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000896 s=(unz64_s*)file;
897 if (ZSEEK64(s->z_filefunc, s->filestream,
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000898 s->pos_in_central_dir+s->byte_before_the_zipfile,
899 ZLIB_FILEFUNC_SEEK_SET)!=0)
900 err=UNZ_ERRNO;
901
902
903 /* we check the magic */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000904 if (err==UNZ_OK)
905 {
906 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000907 err=UNZ_ERRNO;
908 else if (uMagic!=0x02014b50)
909 err=UNZ_BADZIPFILE;
erikkay@google.com8c6279b2009-01-29 00:06:47 +0000910 }
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000911
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000912 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000913 err=UNZ_ERRNO;
914
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000915 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000916 err=UNZ_ERRNO;
917
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000918 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000919 err=UNZ_ERRNO;
920
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000921 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000922 err=UNZ_ERRNO;
923
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000924 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000925 err=UNZ_ERRNO;
926
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000927 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000928
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000929 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000930 err=UNZ_ERRNO;
931
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000932 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
933 err=UNZ_ERRNO;
934 file_info.compressed_size = uL;
935
936 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
937 err=UNZ_ERRNO;
938 file_info.uncompressed_size = uL;
939
940 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000941 err=UNZ_ERRNO;
942
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000943 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000944 err=UNZ_ERRNO;
945
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000946 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000947 err=UNZ_ERRNO;
948
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000949 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000950 err=UNZ_ERRNO;
951
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000952 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000953 err=UNZ_ERRNO;
954
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000955 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000956 err=UNZ_ERRNO;
957
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000958 // relative offset of local header
959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000960 err=UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000961 file_info_internal.offset_curfile = uL;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000962
963 lSeek+=file_info.size_filename;
964 if ((err==UNZ_OK) && (szFileName!=NULL))
965 {
966 uLong uSizeRead ;
967 if (file_info.size_filename<fileNameBufferSize)
968 {
969 *(szFileName+file_info.size_filename)='\0';
970 uSizeRead = file_info.size_filename;
971 }
972 else
973 uSizeRead = fileNameBufferSize;
974
975 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000976 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000977 err=UNZ_ERRNO;
978 lSeek -= uSizeRead;
979 }
980
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000981 // Read extrafield
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000982 if ((err==UNZ_OK) && (extraField!=NULL))
983 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000984 ZPOS64_T uSizeRead ;
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000985 if (file_info.size_file_extra<extraFieldBufferSize)
986 uSizeRead = file_info.size_file_extra;
987 else
988 uSizeRead = extraFieldBufferSize;
989
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000990 if (lSeek!=0)
991 {
992 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000993 lSeek=0;
994 else
995 err=UNZ_ERRNO;
erikkay@google.com8c6279b2009-01-29 00:06:47 +0000996 }
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000997
erikkay@google.com19ba4a52008-12-30 00:40:04 +0000998 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +0000999 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001000 err=UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001001
1002 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001003 }
1004 else
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001005 lSeek += file_info.size_file_extra;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001006
1007
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001008 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1009 {
1010 uLong acc = 0;
1011
1012 // since lSeek now points to after the extra field we need to move back
1013 lSeek -= file_info.size_file_extra;
1014
1015 if (lSeek!=0)
1016 {
1017 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1018 lSeek=0;
1019 else
1020 err=UNZ_ERRNO;
1021 }
1022
1023 while(acc < file_info.size_file_extra)
1024 {
1025 uLong headerId;
1026 uLong dataSize;
1027
1028 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1029 err=UNZ_ERRNO;
1030
1031 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1032 err=UNZ_ERRNO;
1033
1034 /* ZIP64 extra fields */
1035 if (headerId == 0x0001)
1036 {
1037 uLong uL;
1038
jiadong.zhu6c142162016-06-22 21:22:18 -07001039 if(file_info.uncompressed_size == MAXU32)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001040 {
1041 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1042 err=UNZ_ERRNO;
1043 }
1044
jiadong.zhu6c142162016-06-22 21:22:18 -07001045 if(file_info.compressed_size == MAXU32)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001046 {
1047 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1048 err=UNZ_ERRNO;
1049 }
1050
jiadong.zhu6c142162016-06-22 21:22:18 -07001051 if(file_info_internal.offset_curfile == MAXU32)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001052 {
1053 /* Relative Header offset */
1054 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1055 err=UNZ_ERRNO;
1056 }
1057
jiadong.zhu6c142162016-06-22 21:22:18 -07001058 if(file_info.disk_num_start == MAXU32)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001059 {
1060 /* Disk Start Number */
1061 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1062 err=UNZ_ERRNO;
1063 }
1064
1065 }
1066 else
1067 {
1068 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1069 err=UNZ_ERRNO;
1070 }
1071
1072 acc += 2 + 2 + dataSize;
1073 }
1074 }
1075
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001076 if ((err==UNZ_OK) && (szComment!=NULL))
1077 {
1078 uLong uSizeRead ;
1079 if (file_info.size_file_comment<commentBufferSize)
1080 {
1081 *(szComment+file_info.size_file_comment)='\0';
1082 uSizeRead = file_info.size_file_comment;
1083 }
1084 else
1085 uSizeRead = commentBufferSize;
1086
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001087 if (lSeek!=0)
1088 {
1089 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001090 lSeek=0;
1091 else
1092 err=UNZ_ERRNO;
erikkay@google.com8c6279b2009-01-29 00:06:47 +00001093 }
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001094
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001095 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001096 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001097 err=UNZ_ERRNO;
1098 lSeek+=file_info.size_file_comment - uSizeRead;
1099 }
1100 else
1101 lSeek+=file_info.size_file_comment;
1102
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001103
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001104 if ((err==UNZ_OK) && (pfile_info!=NULL))
1105 *pfile_info=file_info;
1106
1107 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1108 *pfile_info_internal=file_info_internal;
1109
1110 return err;
1111}
1112
1113
1114
1115/*
1116 Write info about the ZipFile in the *pglobal_info structure.
1117 No preparation of the structure is needed
1118 return UNZ_OK if there is no problem.
1119*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001120extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1121 unz_file_info64 * pfile_info,
1122 char * szFileName, uLong fileNameBufferSize,
1123 void *extraField, uLong extraFieldBufferSize,
1124 char* szComment, uLong commentBufferSize)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001125{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001126 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001127 szFileName,fileNameBufferSize,
1128 extraField,extraFieldBufferSize,
1129 szComment,commentBufferSize);
1130}
1131
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001132extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1133 unz_file_info * pfile_info,
1134 char * szFileName, uLong fileNameBufferSize,
1135 void *extraField, uLong extraFieldBufferSize,
1136 char* szComment, uLong commentBufferSize)
1137{
1138 int err;
1139 unz_file_info64 file_info64;
1140 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1141 szFileName,fileNameBufferSize,
1142 extraField,extraFieldBufferSize,
1143 szComment,commentBufferSize);
jiadong.zhu6c142162016-06-22 21:22:18 -07001144 if ((err==UNZ_OK) && (pfile_info != NULL))
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001145 {
1146 pfile_info->version = file_info64.version;
1147 pfile_info->version_needed = file_info64.version_needed;
1148 pfile_info->flag = file_info64.flag;
1149 pfile_info->compression_method = file_info64.compression_method;
1150 pfile_info->dosDate = file_info64.dosDate;
1151 pfile_info->crc = file_info64.crc;
1152
1153 pfile_info->size_filename = file_info64.size_filename;
1154 pfile_info->size_file_extra = file_info64.size_file_extra;
1155 pfile_info->size_file_comment = file_info64.size_file_comment;
1156
1157 pfile_info->disk_num_start = file_info64.disk_num_start;
1158 pfile_info->internal_fa = file_info64.internal_fa;
1159 pfile_info->external_fa = file_info64.external_fa;
1160
1161 pfile_info->tmu_date = file_info64.tmu_date,
1162
1163
1164 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1165 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1166
1167 }
1168 return err;
1169}
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001170/*
1171 Set the current file of the zipfile to the first file.
1172 return UNZ_OK if there is no problem
1173*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001174extern int ZEXPORT unzGoToFirstFile (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001175{
1176 int err=UNZ_OK;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001177 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001178 if (file==NULL)
1179 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001180 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001181 s->pos_in_central_dir=s->offset_central_dir;
1182 s->num_file=0;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001183 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001184 &s->cur_file_info_internal,
1185 NULL,0,NULL,0,NULL,0);
1186 s->current_file_ok = (err == UNZ_OK);
1187 return err;
1188}
1189
1190/*
1191 Set the current file of the zipfile to the next file.
1192 return UNZ_OK if there is no problem
1193 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1194*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001195extern int ZEXPORT unzGoToNextFile (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001196{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001197 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001198 int err;
1199
1200 if (file==NULL)
1201 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001202 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001203 if (!s->current_file_ok)
1204 return UNZ_END_OF_LIST_OF_FILE;
1205 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1206 if (s->num_file+1==s->gi.number_entry)
1207 return UNZ_END_OF_LIST_OF_FILE;
1208
1209 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1210 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1211 s->num_file++;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001212 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001213 &s->cur_file_info_internal,
1214 NULL,0,NULL,0,NULL,0);
1215 s->current_file_ok = (err == UNZ_OK);
1216 return err;
1217}
1218
1219
1220/*
1221 Try locate the file szFileName in the zipfile.
jiadong.zhu6c142162016-06-22 21:22:18 -07001222 For the iCaseSensitivity signification, see unzStringFileNameCompare
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001223
1224 return value :
1225 UNZ_OK if the file is found. It becomes the current file.
1226 UNZ_END_OF_LIST_OF_FILE if the file is not found
1227*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001228extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001229{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001230 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001231 int err;
1232
1233 /* We remember the 'current' position in the file so that we can jump
1234 * back there if we fail.
1235 */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001236 unz_file_info64 cur_file_infoSaved;
1237 unz_file_info64_internal cur_file_info_internalSaved;
1238 ZPOS64_T num_fileSaved;
1239 ZPOS64_T pos_in_central_dirSaved;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001240
1241
1242 if (file==NULL)
1243 return UNZ_PARAMERROR;
1244
1245 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1246 return UNZ_PARAMERROR;
1247
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001248 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001249 if (!s->current_file_ok)
1250 return UNZ_END_OF_LIST_OF_FILE;
1251
1252 /* Save the current state */
1253 num_fileSaved = s->num_file;
1254 pos_in_central_dirSaved = s->pos_in_central_dir;
1255 cur_file_infoSaved = s->cur_file_info;
1256 cur_file_info_internalSaved = s->cur_file_info_internal;
1257
1258 err = unzGoToFirstFile(file);
1259
1260 while (err == UNZ_OK)
1261 {
1262 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001263 err = unzGetCurrentFileInfo64(file,NULL,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001264 szCurrentFileName,sizeof(szCurrentFileName)-1,
1265 NULL,0,NULL,0);
1266 if (err == UNZ_OK)
1267 {
1268 if (unzStringFileNameCompare(szCurrentFileName,
1269 szFileName,iCaseSensitivity)==0)
1270 return UNZ_OK;
1271 err = unzGoToNextFile(file);
1272 }
1273 }
1274
1275 /* We failed, so restore the state of the 'current file' to where we
1276 * were.
1277 */
1278 s->num_file = num_fileSaved ;
1279 s->pos_in_central_dir = pos_in_central_dirSaved ;
1280 s->cur_file_info = cur_file_infoSaved;
1281 s->cur_file_info_internal = cur_file_info_internalSaved;
1282 return err;
1283}
1284
1285
1286/*
1287///////////////////////////////////////////
1288// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1289// I need random access
1290//
1291// Further optimization could be realized by adding an ability
1292// to cache the directory in memory. The goal being a single
1293// comprehensive file read to put the file I need in a memory.
1294*/
1295
1296/*
1297typedef struct unz_file_pos_s
1298{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001299 ZPOS64_T pos_in_zip_directory; // offset in file
1300 ZPOS64_T num_of_file; // # of file
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001301} unz_file_pos;
1302*/
1303
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001304extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001305{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001306 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001307
1308 if (file==NULL || file_pos==NULL)
1309 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001310 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001311 if (!s->current_file_ok)
1312 return UNZ_END_OF_LIST_OF_FILE;
1313
1314 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1315 file_pos->num_of_file = s->num_file;
1316
1317 return UNZ_OK;
1318}
1319
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001320extern int ZEXPORT unzGetFilePos(
1321 unzFile file,
1322 unz_file_pos* file_pos)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001323{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001324 unz64_file_pos file_pos64;
1325 int err = unzGetFilePos64(file,&file_pos64);
1326 if (err==UNZ_OK)
1327 {
1328 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1329 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1330 }
1331 return err;
1332}
1333
1334extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1335{
1336 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001337 int err;
1338
1339 if (file==NULL || file_pos==NULL)
1340 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001341 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001342
1343 /* jump to the right spot */
1344 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1345 s->num_file = file_pos->num_of_file;
1346
1347 /* set the current file */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001348 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001349 &s->cur_file_info_internal,
1350 NULL,0,NULL,0,NULL,0);
1351 /* return results */
1352 s->current_file_ok = (err == UNZ_OK);
1353 return err;
1354}
1355
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001356extern int ZEXPORT unzGoToFilePos(
1357 unzFile file,
1358 unz_file_pos* file_pos)
1359{
1360 unz64_file_pos file_pos64;
1361 if (file_pos == NULL)
1362 return UNZ_PARAMERROR;
1363
1364 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1365 file_pos64.num_of_file = file_pos->num_of_file;
1366 return unzGoToFilePos64(file,&file_pos64);
1367}
1368
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001369/*
1370// Unzip Helper Functions - should be here?
1371///////////////////////////////////////////
1372*/
1373
1374/*
1375 Read the local header of the current zipfile
1376 Check the coherency of the local header and info in the end of central
1377 directory about this file
1378 store in *piSizeVar the size of extra info in local header
1379 (filename and size of extra field data)
1380*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001381local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1382 ZPOS64_T * poffset_local_extrafield,
1383 uInt * psize_local_extrafield)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001384{
1385 uLong uMagic,uData,uFlags;
1386 uLong size_filename;
1387 uLong size_extra_field;
1388 int err=UNZ_OK;
1389
1390 *piSizeVar = 0;
1391 *poffset_local_extrafield = 0;
1392 *psize_local_extrafield = 0;
1393
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001394 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001395 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1396 return UNZ_ERRNO;
1397
1398
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001399 if (err==UNZ_OK)
1400 {
1401 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001402 err=UNZ_ERRNO;
1403 else if (uMagic!=0x04034b50)
1404 err=UNZ_BADZIPFILE;
erikkay@google.com8c6279b2009-01-29 00:06:47 +00001405 }
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001406
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001407 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001408 err=UNZ_ERRNO;
1409/*
1410 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1411 err=UNZ_BADZIPFILE;
1412*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001413 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001414 err=UNZ_ERRNO;
1415
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001416 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001417 err=UNZ_ERRNO;
1418 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1419 err=UNZ_BADZIPFILE;
1420
1421 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001422/* #ifdef HAVE_BZIP2 */
1423 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1424/* #endif */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001425 (s->cur_file_info.compression_method!=Z_DEFLATED))
1426 err=UNZ_BADZIPFILE;
1427
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001428 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001429 err=UNZ_ERRNO;
1430
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001431 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001432 err=UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001433 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001434 err=UNZ_BADZIPFILE;
1435
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001436 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001437 err=UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001438 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001439 err=UNZ_BADZIPFILE;
1440
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001441 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001442 err=UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001443 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001444 err=UNZ_BADZIPFILE;
1445
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001446 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001447 err=UNZ_ERRNO;
1448 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1449 err=UNZ_BADZIPFILE;
1450
1451 *piSizeVar += (uInt)size_filename;
1452
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001453 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001454 err=UNZ_ERRNO;
1455 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1456 SIZEZIPLOCALHEADER + size_filename;
1457 *psize_local_extrafield = (uInt)size_extra_field;
1458
1459 *piSizeVar += (uInt)size_extra_field;
1460
1461 return err;
1462}
1463
1464/*
1465 Open for reading data the current file in the zipfile.
1466 If there is no error and the file is opened, the return value is UNZ_OK.
1467*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001468extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1469 int* level, int raw, const char* password)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001470{
1471 int err=UNZ_OK;
1472 uInt iSizeVar;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001473 unz64_s* s;
1474 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1475 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001476 uInt size_local_extrafield; /* size of the local extra field */
1477# ifndef NOUNCRYPT
1478 char source[12];
1479# else
1480 if (password != NULL)
1481 return UNZ_PARAMERROR;
1482# endif
1483
1484 if (file==NULL)
1485 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001486 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001487 if (!s->current_file_ok)
1488 return UNZ_PARAMERROR;
1489
1490 if (s->pfile_in_zip_read != NULL)
1491 unzCloseCurrentFile(file);
1492
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001493 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001494 return UNZ_BADZIPFILE;
1495
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001496 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001497 if (pfile_in_zip_read_info==NULL)
1498 return UNZ_INTERNALERROR;
1499
1500 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1501 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1502 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1503 pfile_in_zip_read_info->pos_local_extrafield=0;
1504 pfile_in_zip_read_info->raw=raw;
1505
1506 if (pfile_in_zip_read_info->read_buffer==NULL)
1507 {
1508 TRYFREE(pfile_in_zip_read_info);
1509 return UNZ_INTERNALERROR;
1510 }
1511
1512 pfile_in_zip_read_info->stream_initialised=0;
1513
1514 if (method!=NULL)
1515 *method = (int)s->cur_file_info.compression_method;
1516
1517 if (level!=NULL)
1518 {
1519 *level = 6;
1520 switch (s->cur_file_info.flag & 0x06)
1521 {
1522 case 6 : *level = 1; break;
1523 case 4 : *level = 2; break;
1524 case 2 : *level = 9; break;
1525 }
1526 }
1527
1528 if ((s->cur_file_info.compression_method!=0) &&
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001529/* #ifdef HAVE_BZIP2 */
1530 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1531/* #endif */
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001532 (s->cur_file_info.compression_method!=Z_DEFLATED))
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001533
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001534 err=UNZ_BADZIPFILE;
1535
1536 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1537 pfile_in_zip_read_info->crc32=0;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001538 pfile_in_zip_read_info->total_out_64=0;
1539 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001540 pfile_in_zip_read_info->filestream=s->filestream;
1541 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1542 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1543
1544 pfile_in_zip_read_info->stream.total_out = 0;
1545
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001546 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001547 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001548#ifdef HAVE_BZIP2
1549 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1550 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1551 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1552 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1553
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001554 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1555 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1556 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1557 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1558 pfile_in_zip_read_info->stream.avail_in = 0;
1559
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001560 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1561 if (err == Z_OK)
1562 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1563 else
1564 {
1565 TRYFREE(pfile_in_zip_read_info);
1566 return err;
1567 }
1568#else
1569 pfile_in_zip_read_info->raw=1;
1570#endif
1571 }
1572 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1573 {
1574 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1575 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1576 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1577 pfile_in_zip_read_info->stream.next_in = 0;
1578 pfile_in_zip_read_info->stream.avail_in = 0;
1579
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001580 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1581 if (err == Z_OK)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001582 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001583 else
1584 {
1585 TRYFREE(pfile_in_zip_read_info);
1586 return err;
1587 }
1588 /* windowBits is passed < 0 to tell that there is no zlib header.
1589 * Note that in this case inflate *requires* an extra "dummy" byte
1590 * after the compressed stream in order to complete decompression and
1591 * return Z_STREAM_END.
1592 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1593 * size of both compressed and uncompressed data
1594 */
1595 }
1596 pfile_in_zip_read_info->rest_read_compressed =
1597 s->cur_file_info.compressed_size ;
1598 pfile_in_zip_read_info->rest_read_uncompressed =
1599 s->cur_file_info.uncompressed_size ;
1600
1601
1602 pfile_in_zip_read_info->pos_in_zipfile =
1603 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1604 iSizeVar;
1605
1606 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1607
1608 s->pfile_in_zip_read = pfile_in_zip_read_info;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001609 s->encrypted = 0;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001610
1611# ifndef NOUNCRYPT
1612 if (password != NULL)
1613 {
1614 int i;
1615 s->pcrc_32_tab = get_crc_table();
1616 init_keys(password,s->keys,s->pcrc_32_tab);
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001617 if (ZSEEK64(s->z_filefunc, s->filestream,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001618 s->pfile_in_zip_read->pos_in_zipfile +
1619 s->pfile_in_zip_read->byte_before_the_zipfile,
1620 SEEK_SET)!=0)
1621 return UNZ_INTERNALERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001622 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001623 return UNZ_INTERNALERROR;
1624
1625 for (i = 0; i<12; i++)
1626 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1627
1628 s->pfile_in_zip_read->pos_in_zipfile+=12;
Che-yu Wuf0721112018-08-06 14:09:22 +00001629 s->pfile_in_zip_read->rest_read_compressed-=12;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001630 s->encrypted=1;
1631 }
1632# endif
1633
1634
1635 return UNZ_OK;
1636}
1637
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001638extern int ZEXPORT unzOpenCurrentFile (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001639{
1640 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1641}
1642
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001643extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001644{
1645 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1646}
1647
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001648extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001649{
1650 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1651}
1652
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001653/** Addition for GDAL : START */
1654
1655extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1656{
1657 unz64_s* s;
1658 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1659 s=(unz64_s*)file;
1660 if (file==NULL)
1661 return 0; //UNZ_PARAMERROR;
1662 pfile_in_zip_read_info=s->pfile_in_zip_read;
1663 if (pfile_in_zip_read_info==NULL)
1664 return 0; //UNZ_PARAMERROR;
1665 return pfile_in_zip_read_info->pos_in_zipfile +
1666 pfile_in_zip_read_info->byte_before_the_zipfile;
1667}
1668
1669/** Addition for GDAL : END */
1670
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001671/*
1672 Read bytes from the current file.
1673 buf contain buffer where data must be copied
1674 len the size of buf.
1675
1676 return the number of byte copied if somes bytes are copied
1677 return 0 if the end of file was reached
1678 return <0 with error code if there is an error
1679 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1680*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001681extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001682{
1683 int err=UNZ_OK;
1684 uInt iRead = 0;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001685 unz64_s* s;
1686 file_in_zip64_read_info_s* pfile_in_zip_read_info;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001687 if (file==NULL)
1688 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001689 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001690 pfile_in_zip_read_info=s->pfile_in_zip_read;
1691
1692 if (pfile_in_zip_read_info==NULL)
1693 return UNZ_PARAMERROR;
1694
1695
jiadong.zhu6c142162016-06-22 21:22:18 -07001696 if (pfile_in_zip_read_info->read_buffer == NULL)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001697 return UNZ_END_OF_LIST_OF_FILE;
1698 if (len==0)
1699 return 0;
1700
1701 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1702
1703 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1704
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001705 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1706 pfile_in_zip_read_info->stream.avail_in) &&
1707 (pfile_in_zip_read_info->raw))
1708 pfile_in_zip_read_info->stream.avail_out =
1709 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1710 pfile_in_zip_read_info->stream.avail_in;
1711
1712 while (pfile_in_zip_read_info->stream.avail_out>0)
1713 {
1714 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1715 (pfile_in_zip_read_info->rest_read_compressed>0))
1716 {
1717 uInt uReadThis = UNZ_BUFSIZE;
1718 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1719 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1720 if (uReadThis == 0)
1721 return UNZ_EOF;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001722 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001723 pfile_in_zip_read_info->filestream,
1724 pfile_in_zip_read_info->pos_in_zipfile +
1725 pfile_in_zip_read_info->byte_before_the_zipfile,
1726 ZLIB_FILEFUNC_SEEK_SET)!=0)
1727 return UNZ_ERRNO;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001728 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001729 pfile_in_zip_read_info->filestream,
1730 pfile_in_zip_read_info->read_buffer,
1731 uReadThis)!=uReadThis)
1732 return UNZ_ERRNO;
1733
1734
1735# ifndef NOUNCRYPT
1736 if(s->encrypted)
1737 {
1738 uInt i;
1739 for(i=0;i<uReadThis;i++)
1740 pfile_in_zip_read_info->read_buffer[i] =
1741 zdecode(s->keys,s->pcrc_32_tab,
1742 pfile_in_zip_read_info->read_buffer[i]);
1743 }
1744# endif
1745
1746
1747 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1748
1749 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1750
1751 pfile_in_zip_read_info->stream.next_in =
1752 (Bytef*)pfile_in_zip_read_info->read_buffer;
1753 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1754 }
1755
1756 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1757 {
1758 uInt uDoCopy,i ;
1759
1760 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1761 (pfile_in_zip_read_info->rest_read_compressed == 0))
1762 return (iRead==0) ? UNZ_EOF : iRead;
1763
1764 if (pfile_in_zip_read_info->stream.avail_out <
1765 pfile_in_zip_read_info->stream.avail_in)
1766 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1767 else
1768 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1769
1770 for (i=0;i<uDoCopy;i++)
1771 *(pfile_in_zip_read_info->stream.next_out+i) =
1772 *(pfile_in_zip_read_info->stream.next_in+i);
1773
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001774 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1775
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001776 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1777 pfile_in_zip_read_info->stream.next_out,
1778 uDoCopy);
1779 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1780 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1781 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1782 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1783 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1784 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1785 iRead += uDoCopy;
1786 }
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001787 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001788 {
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001789#ifdef HAVE_BZIP2
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001790 uLong uTotalOutBefore,uTotalOutAfter;
1791 const Bytef *bufBefore;
1792 uLong uOutThis;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001793
1794 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1795 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1796 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1797 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1798 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1799 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1800 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1801 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1802
1803 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1804 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1805
1806 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1807
1808 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1809 uOutThis = uTotalOutAfter-uTotalOutBefore;
1810
1811 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1812
1813 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1814 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1815 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1816
1817 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1818 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1819 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1820 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1821 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1822 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1823
1824 if (err==BZ_STREAM_END)
1825 return (iRead==0) ? UNZ_EOF : iRead;
1826 if (err!=BZ_OK)
1827 break;
1828#endif
1829 } // end Z_BZIP2ED
1830 else
1831 {
1832 ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1833 const Bytef *bufBefore;
1834 ZPOS64_T uOutThis;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001835 int flush=Z_SYNC_FLUSH;
1836
1837 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1838 bufBefore = pfile_in_zip_read_info->stream.next_out;
1839
1840 /*
1841 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1842 pfile_in_zip_read_info->stream.avail_out) &&
1843 (pfile_in_zip_read_info->rest_read_compressed == 0))
1844 flush = Z_FINISH;
1845 */
1846 err=inflate(&pfile_in_zip_read_info->stream,flush);
1847
1848 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1849 err = Z_DATA_ERROR;
1850
1851 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1852 uOutThis = uTotalOutAfter-uTotalOutBefore;
1853
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001854 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1855
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001856 pfile_in_zip_read_info->crc32 =
1857 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1858 (uInt)(uOutThis));
1859
1860 pfile_in_zip_read_info->rest_read_uncompressed -=
1861 uOutThis;
1862
1863 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1864
1865 if (err==Z_STREAM_END)
1866 return (iRead==0) ? UNZ_EOF : iRead;
1867 if (err!=Z_OK)
1868 break;
1869 }
1870 }
1871
1872 if (err==Z_OK)
1873 return iRead;
1874 return err;
1875}
1876
1877
1878/*
1879 Give the current position in uncompressed data
1880*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001881extern z_off_t ZEXPORT unztell (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001882{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001883 unz64_s* s;
1884 file_in_zip64_read_info_s* pfile_in_zip_read_info;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001885 if (file==NULL)
1886 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001887 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001888 pfile_in_zip_read_info=s->pfile_in_zip_read;
1889
1890 if (pfile_in_zip_read_info==NULL)
1891 return UNZ_PARAMERROR;
1892
1893 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1894}
1895
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001896extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1897{
1898
1899 unz64_s* s;
1900 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1901 if (file==NULL)
1902 return (ZPOS64_T)-1;
1903 s=(unz64_s*)file;
1904 pfile_in_zip_read_info=s->pfile_in_zip_read;
1905
1906 if (pfile_in_zip_read_info==NULL)
1907 return (ZPOS64_T)-1;
1908
1909 return pfile_in_zip_read_info->total_out_64;
1910}
1911
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001912
1913/*
1914 return 1 if the end of file was reached, 0 elsewhere
1915*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001916extern int ZEXPORT unzeof (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001917{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001918 unz64_s* s;
1919 file_in_zip64_read_info_s* pfile_in_zip_read_info;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001920 if (file==NULL)
1921 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001922 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001923 pfile_in_zip_read_info=s->pfile_in_zip_read;
1924
1925 if (pfile_in_zip_read_info==NULL)
1926 return UNZ_PARAMERROR;
1927
1928 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1929 return 1;
1930 else
1931 return 0;
1932}
1933
1934
1935
1936/*
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001937Read extra field from the current file (opened by unzOpenCurrentFile)
1938This is the local-header version of the extra field (sometimes, there is
1939more info in the local-header version than in the central-header)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001940
1941 if buf==NULL, it return the size of the local extra field that can be read
1942
1943 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1944 buf.
1945 the return value is the number of bytes copied in buf, or (if <0)
1946 the error code
1947*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001948extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001949{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001950 unz64_s* s;
1951 file_in_zip64_read_info_s* pfile_in_zip_read_info;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001952 uInt read_now;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001953 ZPOS64_T size_to_read;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001954
1955 if (file==NULL)
1956 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001957 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001958 pfile_in_zip_read_info=s->pfile_in_zip_read;
1959
1960 if (pfile_in_zip_read_info==NULL)
1961 return UNZ_PARAMERROR;
1962
1963 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1964 pfile_in_zip_read_info->pos_local_extrafield);
1965
1966 if (buf==NULL)
1967 return (int)size_to_read;
1968
1969 if (len>size_to_read)
1970 read_now = (uInt)size_to_read;
1971 else
1972 read_now = (uInt)len ;
1973
1974 if (read_now==0)
1975 return 0;
1976
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001977 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001978 pfile_in_zip_read_info->filestream,
1979 pfile_in_zip_read_info->offset_local_extrafield +
1980 pfile_in_zip_read_info->pos_local_extrafield,
1981 ZLIB_FILEFUNC_SEEK_SET)!=0)
1982 return UNZ_ERRNO;
1983
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001984 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001985 pfile_in_zip_read_info->filestream,
1986 buf,read_now)!=read_now)
1987 return UNZ_ERRNO;
1988
1989 return (int)read_now;
1990}
1991
1992/*
jiadong.zhu6c142162016-06-22 21:22:18 -07001993 Close the file in zip opened with unzOpenCurrentFile
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001994 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1995*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00001996extern int ZEXPORT unzCloseCurrentFile (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00001997{
1998 int err=UNZ_OK;
1999
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002000 unz64_s* s;
2001 file_in_zip64_read_info_s* pfile_in_zip_read_info;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002002 if (file==NULL)
2003 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002004 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002005 pfile_in_zip_read_info=s->pfile_in_zip_read;
2006
2007 if (pfile_in_zip_read_info==NULL)
2008 return UNZ_PARAMERROR;
2009
2010
2011 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2012 (!pfile_in_zip_read_info->raw))
2013 {
2014 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2015 err=UNZ_CRCERROR;
2016 }
2017
2018
2019 TRYFREE(pfile_in_zip_read_info->read_buffer);
2020 pfile_in_zip_read_info->read_buffer = NULL;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002021 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002022 inflateEnd(&pfile_in_zip_read_info->stream);
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002023#ifdef HAVE_BZIP2
2024 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2025 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2026#endif
2027
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002028
2029 pfile_in_zip_read_info->stream_initialised = 0;
2030 TRYFREE(pfile_in_zip_read_info);
2031
2032 s->pfile_in_zip_read=NULL;
2033
2034 return err;
2035}
2036
2037
2038/*
2039 Get the global comment string of the ZipFile, in the szComment buffer.
2040 uSizeBuf is the size of the szComment buffer.
2041 return the number of byte copied or an error code <0
2042*/
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002043extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002044{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002045 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002046 uLong uReadThis ;
2047 if (file==NULL)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002048 return (int)UNZ_PARAMERROR;
2049 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002050
2051 uReadThis = uSizeBuf;
2052 if (uReadThis>s->gi.size_comment)
2053 uReadThis = s->gi.size_comment;
2054
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002055 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002056 return UNZ_ERRNO;
2057
2058 if (uReadThis>0)
2059 {
2060 *szComment='\0';
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002061 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002062 return UNZ_ERRNO;
2063 }
2064
2065 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2066 *(szComment+s->gi.size_comment)='\0';
2067 return (int)uReadThis;
2068}
2069
2070/* Additions by RX '2004 */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002071extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002072{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002073 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002074
2075 if (file==NULL)
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002076 return 0; //UNZ_PARAMERROR;
2077 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002078 if (!s->current_file_ok)
2079 return 0;
2080 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2081 if (s->num_file==s->gi.number_entry)
2082 return 0;
2083 return s->pos_in_central_dir;
2084}
2085
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002086extern uLong ZEXPORT unzGetOffset (unzFile file)
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002087{
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002088 ZPOS64_T offset64;
2089
2090 if (file==NULL)
2091 return 0; //UNZ_PARAMERROR;
2092 offset64 = unzGetOffset64(file);
2093 return (uLong)offset64;
2094}
2095
2096extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2097{
2098 unz64_s* s;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002099 int err;
2100
2101 if (file==NULL)
2102 return UNZ_PARAMERROR;
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002103 s=(unz64_s*)file;
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002104
2105 s->pos_in_central_dir = pos;
2106 s->num_file = s->gi.number_entry; /* hack */
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002107 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
erikkay@google.com19ba4a52008-12-30 00:40:04 +00002108 &s->cur_file_info_internal,
2109 NULL,0,NULL,0,NULL,0);
2110 s->current_file_ok = (err == UNZ_OK);
2111 return err;
2112}
hbono@chromium.orgd2dc2092011-12-12 08:48:38 +00002113
2114extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2115{
2116 return unzSetOffset64(file,pos);
2117}