Coverage Report

Created: 2026-05-16 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/contrib/unzip/unzip.c
Line
Count
Source
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
0
# define ALLOC(size) (malloc(size))
111
#endif
112
113
0
#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
0
                              uLong *pX) {
203
0
    unsigned char c[2];
204
0
    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2);
205
0
    if (err==2)
206
0
    {
207
0
        *pX = c[0] | ((uLong)c[1] << 8);
208
0
        return UNZ_OK;
209
0
    }
210
0
    else
211
0
    {
212
0
        *pX = 0;
213
0
        if (ZERROR64(*pzlib_filefunc_def,filestream))
214
0
            return UNZ_ERRNO;
215
0
        else
216
0
            return UNZ_EOF;
217
0
    }
218
0
}
219
220
local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def,
221
                             voidpf filestream,
222
0
                             uLong *pX) {
223
0
    unsigned char c[4];
224
0
    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4);
225
0
    if (err==4)
226
0
    {
227
0
        *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24);
228
0
        return UNZ_OK;
229
0
    }
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
0
}
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
0
#define BUFREADCOMMENT (0x400)
317
#endif
318
319
#ifndef CENTRALDIRINVALID
320
0
#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
0
local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
328
0
    unsigned char* buf;
329
0
    ZPOS64_T uSizeFile;
330
0
    ZPOS64_T uBackRead;
331
0
    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
332
0
    ZPOS64_T uPosFound=CENTRALDIRINVALID;
333
334
0
    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
335
0
        return CENTRALDIRINVALID;
336
337
338
0
    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
339
340
0
    if (uMaxBack>uSizeFile)
341
0
        uMaxBack = uSizeFile;
342
343
0
    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
344
0
    if (buf==NULL)
345
0
        return CENTRALDIRINVALID;
346
347
0
    uBackRead = 4;
348
0
    while (uBackRead<uMaxBack)
349
0
    {
350
0
        uLong uReadSize;
351
0
        ZPOS64_T uReadPos ;
352
0
        int i;
353
0
        if (uBackRead+BUFREADCOMMENT>uMaxBack)
354
0
            uBackRead = uMaxBack;
355
0
        else
356
0
            uBackRead+=BUFREADCOMMENT;
357
0
        uReadPos = uSizeFile-uBackRead ;
358
359
0
        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
360
0
                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
361
0
        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
362
0
            break;
363
364
0
        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
365
0
            break;
366
367
0
        for (i=(int)uReadSize-3; (i--)>0;)
368
0
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
369
0
                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
370
0
            {
371
0
                uPosFound = uReadPos+(unsigned)i;
372
0
                break;
373
0
            }
374
375
0
        if (uPosFound!=CENTRALDIRINVALID)
376
0
            break;
377
0
    }
378
0
    free(buf);
379
0
    return uPosFound;
380
0
}
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
0
                                             voidpf filestream) {
389
0
    unsigned char* buf;
390
0
    ZPOS64_T uSizeFile;
391
0
    ZPOS64_T uBackRead;
392
0
    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
393
0
    ZPOS64_T uPosFound=CENTRALDIRINVALID;
394
0
    uLong uL;
395
0
                ZPOS64_T relativeOffset;
396
397
0
    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
398
0
        return CENTRALDIRINVALID;
399
400
401
0
    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
402
403
0
    if (uMaxBack>uSizeFile)
404
0
        uMaxBack = uSizeFile;
405
406
0
    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
407
0
    if (buf==NULL)
408
0
        return CENTRALDIRINVALID;
409
410
0
    uBackRead = 4;
411
0
    while (uBackRead<uMaxBack)
412
0
    {
413
0
        uLong uReadSize;
414
0
        ZPOS64_T uReadPos;
415
0
        int i;
416
0
        if (uBackRead+BUFREADCOMMENT>uMaxBack)
417
0
            uBackRead = uMaxBack;
418
0
        else
419
0
            uBackRead+=BUFREADCOMMENT;
420
0
        uReadPos = uSizeFile-uBackRead ;
421
422
0
        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
423
0
                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
424
0
        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
425
0
            break;
426
427
0
        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
428
0
            break;
429
430
0
        for (i=(int)uReadSize-3; (i--)>0;)
431
0
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
432
0
                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
433
0
            {
434
0
                uPosFound = uReadPos+(unsigned)i;
435
0
                break;
436
0
            }
437
438
0
        if (uPosFound!=CENTRALDIRINVALID)
439
0
            break;
440
0
    }
441
0
    free(buf);
442
0
    if (uPosFound == CENTRALDIRINVALID)
443
0
        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
0
                              int is64bitOpenFunction) {
495
0
    unz64_s us;
496
0
    unz64_s *s;
497
0
    ZPOS64_T central_pos;
498
0
    uLong   uL;
499
500
0
    uLong number_disk;          /* number of the current disk, used for
501
                                   spanning ZIP, unsupported, always 0*/
502
0
    uLong number_disk_with_CD;  /* number the disk with central dir, used
503
                                   for spanning ZIP, unsupported, always 0*/
504
0
    ZPOS64_T number_entry_CD;      /* total number of entries in
505
                                   the central dir
506
                                   (same than number_entry on nospan) */
507
508
0
    int err=UNZ_OK;
509
510
0
    if (unz_copyright[0]!=' ')
511
0
        return NULL;
512
513
0
    us.z_filefunc.zseek32_file = NULL;
514
0
    us.z_filefunc.ztell32_file = NULL;
515
0
    if (pzlib_filefunc64_32_def==NULL)
516
0
        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
517
0
    else
518
0
        us.z_filefunc = *pzlib_filefunc64_32_def;
519
0
    us.is64bitOpenFunction = is64bitOpenFunction;
520
521
522
523
0
    us.filestream = ZOPEN64(us.z_filefunc,
524
0
                                                 path,
525
0
                                                 ZLIB_FILEFUNC_MODE_READ |
526
0
                                                 ZLIB_FILEFUNC_MODE_EXISTING);
527
0
    if (us.filestream==NULL)
528
0
        return NULL;
529
530
0
    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
531
0
    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
0
    else
591
0
    {
592
0
        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
593
0
        if (central_pos==CENTRALDIRINVALID)
594
0
            err=UNZ_ERRNO;
595
596
0
        us.isZip64 = 0;
597
598
0
        if (ZSEEK64(us.z_filefunc, us.filestream,
599
0
                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
600
0
            err=UNZ_ERRNO;
601
602
        /* the signature, already checked */
603
0
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
604
0
            err=UNZ_ERRNO;
605
606
        /* number of this disk */
607
0
        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
0
        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
0
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
616
0
            err=UNZ_ERRNO;
617
0
        us.gi.number_entry = uL;
618
619
        /* total number of entries in the central dir */
620
0
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
621
0
            err=UNZ_ERRNO;
622
0
        number_entry_CD = uL;
623
624
0
        if ((number_entry_CD!=us.gi.number_entry) ||
625
0
            (number_disk_with_CD!=0) ||
626
0
            (number_disk!=0))
627
0
            err=UNZ_BADZIPFILE;
628
629
        /* size of the central directory */
630
0
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
631
0
            err=UNZ_ERRNO;
632
0
        us.size_central_dir = uL;
633
634
        /* offset of start of central directory with respect to the
635
            starting disk number */
636
0
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
637
0
            err=UNZ_ERRNO;
638
0
        us.offset_central_dir = uL;
639
640
        /* zipfile comment length */
641
0
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
642
0
            err=UNZ_ERRNO;
643
0
    }
644
645
0
    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
646
0
        (err==UNZ_OK))
647
0
        err=UNZ_BADZIPFILE;
648
649
0
    if (err!=UNZ_OK)
650
0
    {
651
0
        ZCLOSE64(us.z_filefunc, us.filestream);
652
0
        return NULL;
653
0
    }
654
655
0
    us.byte_before_the_zipfile = central_pos -
656
0
                            (us.offset_central_dir+us.size_central_dir);
657
0
    us.central_pos = central_pos;
658
0
    us.pfile_in_zip_read = NULL;
659
0
    us.encrypted = 0;
660
661
662
0
    s=(unz64_s*)ALLOC(sizeof(unz64_s));
663
0
    if( s != NULL)
664
0
    {
665
0
        *s=us;
666
0
        unzGoToFirstFile((unzFile)s);
667
0
    }
668
0
    return (unzFile)s;
669
0
}
670
671
672
extern unzFile ZEXPORT unzOpen2(const char *path,
673
0
                                zlib_filefunc_def* pzlib_filefunc32_def) {
674
0
    if (pzlib_filefunc32_def != NULL)
675
0
    {
676
0
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
677
0
        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
678
0
        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
679
0
    }
680
0
    else
681
0
        return unzOpenInternal(path, NULL, 0);
682
0
}
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
0
extern int ZEXPORT unzClose(unzFile file) {
712
0
    unz64_s* s;
713
0
    if (file==NULL)
714
0
        return UNZ_PARAMERROR;
715
0
    s=(unz64_s*)file;
716
717
0
    if (s->pfile_in_zip_read!=NULL)
718
0
        unzCloseCurrentFile(file);
719
720
0
    ZCLOSE64(s->z_filefunc, s->filestream);
721
0
    free(s);
722
0
    return UNZ_OK;
723
0
}
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
0
local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) {
753
0
    ZPOS64_T uDate;
754
0
    uDate = (ZPOS64_T)(ulDosDate>>16);
755
0
    ptm->tm_mday = (int)(uDate&0x1f) ;
756
0
    ptm->tm_mon =  (int)((((uDate)&0x1E0)/0x20)-1) ;
757
0
    ptm->tm_year = (int)(((uDate&0x0FE00)/0x0200)+1980) ;
758
759
0
    ptm->tm_hour = (int) ((ulDosDate &0xF800)/0x800);
760
0
    ptm->tm_min =  (int) ((ulDosDate&0x7E0)/0x20) ;
761
0
    ptm->tm_sec =  (int) (2*(ulDosDate&0x1f)) ;
762
0
}
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
0
                                                uLong commentBufferSize) {
777
0
    unz64_s* s;
778
0
    unz_file_info64 file_info;
779
0
    unz_file_info64_internal file_info_internal;
780
0
    int err=UNZ_OK;
781
0
    uLong uMagic;
782
0
    long lSeek=0;
783
0
    uLong uL;
784
785
0
    if (file==NULL)
786
0
        return UNZ_PARAMERROR;
787
0
    s=(unz64_s*)file;
788
0
    if (ZSEEK64(s->z_filefunc, s->filestream,
789
0
              s->pos_in_central_dir+s->byte_before_the_zipfile,
790
0
              ZLIB_FILEFUNC_SEEK_SET)!=0)
791
0
        err=UNZ_ERRNO;
792
793
794
    /* we check the magic */
795
0
    if (err==UNZ_OK)
796
0
    {
797
0
        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
798
0
            err=UNZ_ERRNO;
799
0
        else if (uMagic!=0x02014b50)
800
0
            err=UNZ_BADZIPFILE;
801
0
    }
802
803
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
804
0
        err=UNZ_ERRNO;
805
806
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
807
0
        err=UNZ_ERRNO;
808
809
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
810
0
        err=UNZ_ERRNO;
811
812
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
813
0
        err=UNZ_ERRNO;
814
815
0
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
816
0
        err=UNZ_ERRNO;
817
818
0
    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
819
820
0
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
821
0
        err=UNZ_ERRNO;
822
823
0
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
824
0
        err=UNZ_ERRNO;
825
0
    file_info.compressed_size = uL;
826
827
0
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
828
0
        err=UNZ_ERRNO;
829
0
    file_info.uncompressed_size = uL;
830
831
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
832
0
        err=UNZ_ERRNO;
833
834
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
835
0
        err=UNZ_ERRNO;
836
837
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
838
0
        err=UNZ_ERRNO;
839
840
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
841
0
        err=UNZ_ERRNO;
842
843
0
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
844
0
        err=UNZ_ERRNO;
845
846
0
    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
0
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
851
0
        err=UNZ_ERRNO;
852
0
    file_info_internal.offset_curfile = uL;
853
854
0
    lSeek+=file_info.size_filename;
855
0
    if ((err==UNZ_OK) && (szFileName!=NULL))
856
0
    {
857
0
        uLong uSizeRead ;
858
0
        if (file_info.size_filename<fileNameBufferSize)
859
0
        {
860
0
            *(szFileName+file_info.size_filename)='\0';
861
0
            uSizeRead = file_info.size_filename;
862
0
        }
863
0
        else
864
0
            uSizeRead = fileNameBufferSize;
865
866
0
        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
867
0
            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
868
0
                err=UNZ_ERRNO;
869
0
        lSeek -= uSizeRead;
870
0
    }
871
872
    // Read extrafield
873
0
    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
0
    else
896
0
        lSeek += file_info.size_file_extra;
897
898
899
0
    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
900
0
    {
901
0
                                uLong acc = 0;
902
903
        // since lSeek now points to after the extra field we need to move back
904
0
        lSeek -= file_info.size_file_extra;
905
906
0
        if (lSeek!=0)
907
0
        {
908
0
            if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
909
0
                lSeek=0;
910
0
            else
911
0
                err=UNZ_ERRNO;
912
0
        }
913
914
0
        while(acc < file_info.size_file_extra)
915
0
        {
916
0
            uLong headerId;
917
0
                                                uLong dataSize;
918
919
0
            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
920
0
                err=UNZ_ERRNO;
921
922
0
            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
923
0
                err=UNZ_ERRNO;
924
925
            /* ZIP64 extra fields */
926
0
            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
0
            else
956
0
            {
957
0
                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
958
0
                    err=UNZ_ERRNO;
959
0
            }
960
961
0
            acc += 2 + 2 + dataSize;
962
0
        }
963
0
    }
964
965
0
    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
0
    else
990
0
        lSeek+=file_info.size_file_comment;
991
992
993
0
    if ((err==UNZ_OK) && (pfile_info!=NULL))
994
0
        *pfile_info=file_info;
995
996
0
    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
997
0
        *pfile_info_internal=file_info_internal;
998
999
0
    return err;
1000
0
}
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
0
                                         char* szComment,  uLong commentBufferSize) {
1025
0
    int err;
1026
0
    unz_file_info64 file_info64;
1027
0
    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1028
0
                                                szFileName,fileNameBufferSize,
1029
0
                                                extraField,extraFieldBufferSize,
1030
0
                                                szComment,commentBufferSize);
1031
0
    if ((err==UNZ_OK) && (pfile_info != NULL))
1032
0
    {
1033
0
        pfile_info->version = file_info64.version;
1034
0
        pfile_info->version_needed = file_info64.version_needed;
1035
0
        pfile_info->flag = file_info64.flag;
1036
0
        pfile_info->compression_method = file_info64.compression_method;
1037
0
        pfile_info->dosDate = file_info64.dosDate;
1038
0
        pfile_info->crc = file_info64.crc;
1039
1040
0
        pfile_info->size_filename = file_info64.size_filename;
1041
0
        pfile_info->size_file_extra = file_info64.size_file_extra;
1042
0
        pfile_info->size_file_comment = file_info64.size_file_comment;
1043
1044
0
        pfile_info->disk_num_start = file_info64.disk_num_start;
1045
0
        pfile_info->internal_fa = file_info64.internal_fa;
1046
0
        pfile_info->external_fa = file_info64.external_fa;
1047
1048
0
        pfile_info->tmu_date = file_info64.tmu_date;
1049
1050
1051
0
        pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1052
0
        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1053
1054
0
    }
1055
0
    return err;
1056
0
}
1057
/*
1058
  Set the current file of the zipfile to the first file.
1059
  return UNZ_OK if there is no problem
1060
*/
1061
0
extern int ZEXPORT unzGoToFirstFile(unzFile file) {
1062
0
    int err=UNZ_OK;
1063
0
    unz64_s* s;
1064
0
    if (file==NULL)
1065
0
        return UNZ_PARAMERROR;
1066
0
    s=(unz64_s*)file;
1067
0
    s->pos_in_central_dir=s->offset_central_dir;
1068
0
    s->num_file=0;
1069
0
    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1070
0
                                             &s->cur_file_info_internal,
1071
0
                                             NULL,0,NULL,0,NULL,0);
1072
0
    s->current_file_ok = (err == UNZ_OK);
1073
0
    return err;
1074
0
}
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
0
extern int ZEXPORT unzGoToNextFile(unzFile file) {
1082
0
    unz64_s* s;
1083
0
    int err;
1084
1085
0
    if (file==NULL)
1086
0
        return UNZ_PARAMERROR;
1087
0
    s=(unz64_s*)file;
1088
0
    if (!s->current_file_ok)
1089
0
        return UNZ_END_OF_LIST_OF_FILE;
1090
0
    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
1091
0
      if (s->num_file+1==s->gi.number_entry)
1092
0
        return UNZ_END_OF_LIST_OF_FILE;
1093
1094
0
    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1095
0
            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1096
0
    s->num_file++;
1097
0
    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1098
0
                                               &s->cur_file_info_internal,
1099
0
                                               NULL,0,NULL,0,NULL,0);
1100
0
    s->current_file_ok = (err == UNZ_OK);
1101
0
    return err;
1102
0
}
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
0
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) {
1189
0
    unz64_s* s;
1190
1191
0
    if (file==NULL || file_pos==NULL)
1192
0
        return UNZ_PARAMERROR;
1193
0
    s=(unz64_s*)file;
1194
0
    if (!s->current_file_ok)
1195
0
        return UNZ_END_OF_LIST_OF_FILE;
1196
1197
0
    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
1198
0
    file_pos->num_of_file           = s->num_file;
1199
1200
0
    return UNZ_OK;
1201
0
}
1202
1203
0
extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) {
1204
0
    unz64_file_pos file_pos64;
1205
0
    int err = unzGetFilePos64(file,&file_pos64);
1206
0
    if (err==UNZ_OK)
1207
0
    {
1208
0
        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1209
0
        file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1210
0
    }
1211
0
    return err;
1212
0
}
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
}