Coverage Report

Created: 2025-08-28 06:38

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