unzip.c 69.4 KB
Newer Older
M
Mark Adler 已提交
1
/* unzip.c -- IO for uncompress .zip files using zlib
M
Mark Adler 已提交
2
   Version 1.1, February 14h, 2010
M
Mark Adler 已提交
3
   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
M
Mark Adler 已提交
4

M
Mark Adler 已提交
5
         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
M
Mark Adler 已提交
6

M
Mark Adler 已提交
7 8
         Modifications of Unzip for Zip64
         Copyright (C) 2007-2008 Even Rouault
M
Mark Adler 已提交
9

M
Mark Adler 已提交
10 11
         Modifications for Zip64 support on both zip and unzip
         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
M
Mark Adler 已提交
12

M
Mark Adler 已提交
13
         For more info read MiniZip_info.txt
M
Mark Adler 已提交
14 15 16 17


  ------------------------------------------------------------------------------------
  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
M
Mark Adler 已提交
18
  compatibility with older software. The following is from the original crypt.c.
M
Mark Adler 已提交
19
  Code woven in by Terry Thorsen 1/2003.
M
Mark Adler 已提交
20 21 22 23 24 25 26

  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.

  See the accompanying file LICENSE, version 2000-Apr-09 or later
  (the contents of which are also included in zip.h) for terms of use.
  If, for some reason, all these files are missing, the Info-ZIP license
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
M
Mark Adler 已提交
27

M
Mark Adler 已提交
28
        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
M
Mark Adler 已提交
29 30 31 32 33 34

  The encryption/decryption parts of this source code (as opposed to the
  non-echoing password parts) were originally written in Europe.  The
  whole source package can be freely distributed, including from the USA.
  (Prior to January 2000, re-export from the US was a violation of US law.)

M
Mark Adler 已提交
35
        This encryption code is a direct transcription of the algorithm from
M
Mark Adler 已提交
36 37 38
  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
  file (appnote.txt) is distributed with the PKZIP program (even in the
  version without encryption capabilities).
M
Mark Adler 已提交
39

M
Mark Adler 已提交
40
        ------------------------------------------------------------------------------------
M
Mark Adler 已提交
41

M
Mark Adler 已提交
42
        Changes in unzip.c
M
Mark Adler 已提交
43

M
Mark Adler 已提交
44
        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
M
Mark Adler 已提交
45 46 47
  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
  2007-2008 - Even Rouault - Remove old C style function prototypes
  2007-2008 - Even Rouault - Add unzip support for ZIP64
M
Mark Adler 已提交
48

M
Mark Adler 已提交
49
        Copyright (C) 2007-2008 Even Rouault
M
Mark Adler 已提交
50 51


M
Mark Adler 已提交
52 53
        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).
  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
M
Mark Adler 已提交
54
                                should only read the compressed/uncompressed size from the Zip64 format if
M
Mark Adler 已提交
55
                                the size from normal header was 0xFFFFFFFF
M
Mark Adler 已提交
56 57
  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
M
Mark Adler 已提交
58 59
                                Patch created by Daniel Borca

M
Mark Adler 已提交
60 61 62
  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer

  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
M
Mark Adler 已提交
63 64

*/
M
Mark Adler 已提交
65 66 67 68 69


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
M
Mark Adler 已提交
70 71

#ifndef NOUNCRYPT
M
Mark Adler 已提交
72
        #define NOUNCRYPT
M
Mark Adler 已提交
73 74
#endif

M
Mark Adler 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
#include "zlib.h"
#include "unzip.h"

#ifdef STDC
#  include <stddef.h>
#  include <string.h>
#  include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
    extern int errno;
#else
#   include <errno.h>
#endif


#ifndef local
#  define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */


#ifndef CASESENSITIVITYDEFAULT_NO
#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
#    define CASESENSITIVITYDEFAULT_NO
#  endif
#endif


#ifndef UNZ_BUFSIZE
#define UNZ_BUFSIZE (16384)
#endif

#ifndef UNZ_MAXFILENAMEINZIP
#define UNZ_MAXFILENAMEINZIP (256)
#endif

#ifndef ALLOC
# define ALLOC(size) (malloc(size))
#endif
#ifndef TRYFREE
# define TRYFREE(p) {if (p) free(p);}
#endif

#define SIZECENTRALDIRITEM (0x2e)
#define SIZEZIPLOCALHEADER (0x1e)


const char unz_copyright[] =
   " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";

/* unz_file_info_interntal contain internal info about a file in zipfile*/
M
Mark Adler 已提交
126
typedef struct unz_file_info64_internal_s
M
Mark Adler 已提交
127
{
M
Mark Adler 已提交
128 129
    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
} unz_file_info64_internal;
M
Mark Adler 已提交
130 131 132 133 134 135 136 137 138


/* file_in_zip_read_info_s contain internal information about a file in zipfile,
    when reading and decompress it */
typedef struct
{
    char  *read_buffer;         /* internal buffer for compressed data */
    z_stream stream;            /* zLib stream structure for inflate */

M
Mark Adler 已提交
139 140 141 142 143
#ifdef HAVE_BZIP2
    bz_stream bstream;          /* bzLib stream structure for bziped */
#endif

    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
M
Mark Adler 已提交
144 145
    uLong stream_initialised;   /* flag set if stream structure is initialised*/

M
Mark Adler 已提交
146
    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
M
Mark Adler 已提交
147
    uInt  size_local_extrafield;/* size of the local extra field */
M
Mark Adler 已提交
148 149
    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
    ZPOS64_T total_out_64;
M
Mark Adler 已提交
150 151 152

    uLong crc32;                /* crc32 of all data uncompressed */
    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
M
Mark Adler 已提交
153 154 155
    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
    zlib_filefunc64_32_def z_filefunc;
M
Mark Adler 已提交
156 157
    voidpf filestream;        /* io structore of the zipfile */
    uLong compression_method;   /* compression method (0==store) */
M
Mark Adler 已提交
158
    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
M
Mark Adler 已提交
159
    int   raw;
M
Mark Adler 已提交
160
} file_in_zip64_read_info_s;
M
Mark Adler 已提交
161 162


M
Mark Adler 已提交
163
/* unz64_s contain internal information about the zipfile
M
Mark Adler 已提交
164 165 166
*/
typedef struct
{
M
Mark Adler 已提交
167 168
    zlib_filefunc64_32_def z_filefunc;
    int is64bitOpenFunction;
M
Mark Adler 已提交
169
    voidpf filestream;        /* io structore of the zipfile */
M
Mark Adler 已提交
170 171 172 173 174 175 176 177 178
    unz_global_info64 gi;       /* public global information */
    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
    ZPOS64_T num_file;             /* number of the current file in the zipfile*/
    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/

    ZPOS64_T size_central_dir;     /* size of the central directory  */
    ZPOS64_T offset_central_dir;   /* offset of start of central directory with
M
Mark Adler 已提交
179 180
                                   respect to the starting disk number */

M
Mark Adler 已提交
181 182 183
    unz_file_info64 cur_file_info; /* public info about the current file in zip*/
    unz_file_info64_internal cur_file_info_internal; /* private info about it*/
    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
M
Mark Adler 已提交
184 185
                                        file if we are decompressing it */
    int encrypted;
M
Mark Adler 已提交
186 187 188

    int isZip64;

M
Mark Adler 已提交
189 190 191 192
#    ifndef NOUNCRYPT
    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
    const unsigned long* pcrc_32_tab;
#    endif
M
Mark Adler 已提交
193
} unz64_s;
M
Mark Adler 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206


#ifndef NOUNCRYPT
#include "crypt.h"
#endif

/* ===========================================================================
     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
   for end of file.
   IN assertion: the stream s has been sucessfully opened for reading.
*/


M
Mark Adler 已提交
207 208
local int unz64local_getByte OF((
    const zlib_filefunc64_32_def* pzlib_filefunc_def,
M
Mark Adler 已提交
209 210 211
    voidpf filestream,
    int *pi));

M
Mark Adler 已提交
212
local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
M
Mark Adler 已提交
213 214
{
    unsigned char c;
M
Mark Adler 已提交
215
    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
M
Mark Adler 已提交
216 217 218 219 220 221 222
    if (err==1)
    {
        *pi = (int)c;
        return UNZ_OK;
    }
    else
    {
M
Mark Adler 已提交
223
        if (ZERROR64(*pzlib_filefunc_def,filestream))
M
Mark Adler 已提交
224 225 226 227 228 229 230 231 232 233
            return UNZ_ERRNO;
        else
            return UNZ_EOF;
    }
}


/* ===========================================================================
   Reads a long in LSB order from the given gz_stream. Sets
*/
M
Mark Adler 已提交
234 235
local int unz64local_getShort OF((
    const zlib_filefunc64_32_def* pzlib_filefunc_def,
M
Mark Adler 已提交
236 237 238
    voidpf filestream,
    uLong *pX));

M
Mark Adler 已提交
239 240 241
local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
                             voidpf filestream,
                             uLong *pX)
M
Mark Adler 已提交
242 243
{
    uLong x ;
M
Mark Adler 已提交
244
    int i = 0;
M
Mark Adler 已提交
245 246
    int err;

M
Mark Adler 已提交
247
    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
M
Mark Adler 已提交
248 249 250
    x = (uLong)i;

    if (err==UNZ_OK)
M
Mark Adler 已提交
251 252
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((uLong)i)<<8;
M
Mark Adler 已提交
253 254 255 256 257 258 259 260

    if (err==UNZ_OK)
        *pX = x;
    else
        *pX = 0;
    return err;
}

M
Mark Adler 已提交
261 262
local int unz64local_getLong OF((
    const zlib_filefunc64_32_def* pzlib_filefunc_def,
M
Mark Adler 已提交
263 264 265
    voidpf filestream,
    uLong *pX));

M
Mark Adler 已提交
266 267 268
local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
                            voidpf filestream,
                            uLong *pX)
M
Mark Adler 已提交
269 270
{
    uLong x ;
M
Mark Adler 已提交
271
    int i = 0;
M
Mark Adler 已提交
272 273
    int err;

M
Mark Adler 已提交
274
    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
M
Mark Adler 已提交
275 276 277
    x = (uLong)i;

    if (err==UNZ_OK)
M
Mark Adler 已提交
278 279
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((uLong)i)<<8;
M
Mark Adler 已提交
280 281

    if (err==UNZ_OK)
M
Mark Adler 已提交
282 283
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((uLong)i)<<16;
M
Mark Adler 已提交
284 285

    if (err==UNZ_OK)
M
Mark Adler 已提交
286
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
M
Mark Adler 已提交
287 288 289 290 291 292 293 294 295
    x += ((uLong)i)<<24;

    if (err==UNZ_OK)
        *pX = x;
    else
        *pX = 0;
    return err;
}

M
Mark Adler 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
local int unz64local_getLong64 OF((
    const zlib_filefunc64_32_def* pzlib_filefunc_def,
    voidpf filestream,
    ZPOS64_T *pX));


local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
                            voidpf filestream,
                            ZPOS64_T *pX)
{
    ZPOS64_T x ;
    int i = 0;
    int err;

    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x = (ZPOS64_T)i;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<8;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<16;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<24;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<32;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<40;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<48;

    if (err==UNZ_OK)
        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
    x |= ((ZPOS64_T)i)<<56;

    if (err==UNZ_OK)
        *pX = x;
    else
        *pX = 0;
    return err;
}
M
Mark Adler 已提交
347 348

/* My own strcmpi / strcasecmp */
M
Mark Adler 已提交
349
local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
M
Mark Adler 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
{
    for (;;)
    {
        char c1=*(fileName1++);
        char c2=*(fileName2++);
        if ((c1>='a') && (c1<='z'))
            c1 -= 0x20;
        if ((c2>='a') && (c2<='z'))
            c2 -= 0x20;
        if (c1=='\0')
            return ((c2=='\0') ? 0 : -1);
        if (c2=='\0')
            return 1;
        if (c1<c2)
            return -1;
        if (c1>c2)
            return 1;
    }
}


#ifdef  CASESENSITIVITYDEFAULT_NO
#define CASESENSITIVITYDEFAULTVALUE 2
#else
#define CASESENSITIVITYDEFAULTVALUE 1
#endif

#ifndef STRCMPCASENOSENTIVEFUNCTION
#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
#endif

/*
   Compare two filename (fileName1,fileName2).
   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
                                                                or strcasecmp)
   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
        (like 1 on Unix, 2 on Windows)

*/
M
Mark Adler 已提交
390 391 392 393
extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
                                                 const char*  fileName2,
                                                 int iCaseSensitivity)

M
Mark Adler 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
{
    if (iCaseSensitivity==0)
        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;

    if (iCaseSensitivity==1)
        return strcmp(fileName1,fileName2);

    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
}

#ifndef BUFREADCOMMENT
#define BUFREADCOMMENT (0x400)
#endif

/*
  Locate the Central directory of a zipfile (at the end, just before
    the global comment)
*/
M
Mark Adler 已提交
412 413
local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
M
Mark Adler 已提交
414 415
{
    unsigned char* buf;
M
Mark Adler 已提交
416 417 418 419
    ZPOS64_T uSizeFile;
    ZPOS64_T uBackRead;
    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
    ZPOS64_T uPosFound=0;
M
Mark Adler 已提交
420

M
Mark Adler 已提交
421
    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
M
Mark Adler 已提交
422 423 424
        return 0;


M
Mark Adler 已提交
425
    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
M
Mark Adler 已提交
426 427 428 429 430 431 432 433 434 435 436

    if (uMaxBack>uSizeFile)
        uMaxBack = uSizeFile;

    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
    if (buf==NULL)
        return 0;

    uBackRead = 4;
    while (uBackRead<uMaxBack)
    {
M
Mark Adler 已提交
437 438
        uLong uReadSize;
        ZPOS64_T uReadPos ;
M
Mark Adler 已提交
439 440 441 442 443 444 445 446
        int i;
        if (uBackRead+BUFREADCOMMENT>uMaxBack)
            uBackRead = uMaxBack;
        else
            uBackRead+=BUFREADCOMMENT;
        uReadPos = uSizeFile-uBackRead ;

        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
M
Mark Adler 已提交
447 448
                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
M
Mark Adler 已提交
449 450
            break;

M
Mark Adler 已提交
451
        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
M
Mark Adler 已提交
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
            break;

        for (i=(int)uReadSize-3; (i--)>0;)
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
            {
                uPosFound = uReadPos+i;
                break;
            }

        if (uPosFound!=0)
            break;
    }
    TRYFREE(buf);
    return uPosFound;
}

M
Mark Adler 已提交
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486

/*
  Locate the Central directory 64 of a zipfile (at the end, just before
    the global comment)
*/
local ZPOS64_T unz64local_SearchCentralDir64 OF((
    const zlib_filefunc64_32_def* pzlib_filefunc_def,
    voidpf filestream));

local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
                                      voidpf filestream)
{
    unsigned char* buf;
    ZPOS64_T uSizeFile;
    ZPOS64_T uBackRead;
    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
    ZPOS64_T uPosFound=0;
    uLong uL;
M
Mark Adler 已提交
487
                ZPOS64_T relativeOffset;
M
Mark Adler 已提交
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574

    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
        return 0;


    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);

    if (uMaxBack>uSizeFile)
        uMaxBack = uSizeFile;

    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
    if (buf==NULL)
        return 0;

    uBackRead = 4;
    while (uBackRead<uMaxBack)
    {
        uLong uReadSize;
        ZPOS64_T uReadPos;
        int i;
        if (uBackRead+BUFREADCOMMENT>uMaxBack)
            uBackRead = uMaxBack;
        else
            uBackRead+=BUFREADCOMMENT;
        uReadPos = uSizeFile-uBackRead ;

        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
            break;

        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
            break;

        for (i=(int)uReadSize-3; (i--)>0;)
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
            {
                uPosFound = uReadPos+i;
                break;
            }

        if (uPosFound!=0)
            break;
    }
    TRYFREE(buf);
    if (uPosFound == 0)
        return 0;

    /* Zip64 end of central directory locator */
    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
        return 0;

    /* the signature, already checked */
    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
        return 0;

    /* number of the disk with the start of the zip64 end of  central directory */
    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
        return 0;
    if (uL != 0)
        return 0;

    /* relative offset of the zip64 end of central directory record */
    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
        return 0;

    /* total number of disks */
    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
        return 0;
    if (uL != 1)
        return 0;

    /* Goto end of central directory record */
    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
        return 0;

     /* the signature */
    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
        return 0;

    if (uL != 0x06064b50)
        return 0;

    return relativeOffset;
}

M
Mark Adler 已提交
575 576 577 578 579 580 581 582 583
/*
  Open a Zip file. path contain the full pathname (by example,
     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
     "zlib/zlib114.zip".
     If the zipfile cannot be opened (file doesn't exist or in not valid), the
       return value is NULL.
     Else, the return value is a unzFile Handle, usable with other function
       of this unzip package.
*/
M
Mark Adler 已提交
584 585 586
local unzFile unzOpenInternal (const void *path,
                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
                               int is64bitOpenFunction)
M
Mark Adler 已提交
587
{
M
Mark Adler 已提交
588 589 590 591
    unz64_s us;
    unz64_s *s;
    ZPOS64_T central_pos;
    uLong   uL;
M
Mark Adler 已提交
592 593 594 595 596

    uLong number_disk;          /* number of the current dist, used for
                                   spaning ZIP, unsupported, always 0*/
    uLong number_disk_with_CD;  /* number the the disk with central dir, used
                                   for spaning ZIP, unsupported, always 0*/
M
Mark Adler 已提交
597
    ZPOS64_T number_entry_CD;      /* total number of entries in
M
Mark Adler 已提交
598 599 600 601 602 603 604 605
                                   the central dir
                                   (same than number_entry on nospan) */

    int err=UNZ_OK;

    if (unz_copyright[0]!=' ')
        return NULL;

M
Mark Adler 已提交
606 607 608 609
    us.z_filefunc.zseek32_file = NULL;
    us.z_filefunc.ztell32_file = NULL;
    if (pzlib_filefunc64_32_def==NULL)
        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
M
Mark Adler 已提交
610
    else
M
Mark Adler 已提交
611 612 613 614
        us.z_filefunc = *pzlib_filefunc64_32_def;
    us.is64bitOpenFunction = is64bitOpenFunction;


M
Mark Adler 已提交
615

M
Mark Adler 已提交
616
    us.filestream = ZOPEN64(us.z_filefunc,
M
Mark Adler 已提交
617 618 619 620 621 622
                                                 path,
                                                 ZLIB_FILEFUNC_MODE_READ |
                                                 ZLIB_FILEFUNC_MODE_EXISTING);
    if (us.filestream==NULL)
        return NULL;

M
Mark Adler 已提交
623 624 625 626 627 628 629
    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
    if (central_pos)
    {
        uLong uS;
        ZPOS64_T uL64;

        us.isZip64 = 1;
M
Mark Adler 已提交
630

M
Mark Adler 已提交
631
        if (ZSEEK64(us.z_filefunc, us.filestream,
M
Mark Adler 已提交
632 633 634
                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
        err=UNZ_ERRNO;

M
Mark Adler 已提交
635 636 637
        /* the signature, already checked */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
638

M
Mark Adler 已提交
639 640 641
        /* size of zip64 end of central directory record */
        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
642

M
Mark Adler 已提交
643 644 645
        /* version made by */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
646

M
Mark Adler 已提交
647 648 649
        /* version needed to extract */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
650

M
Mark Adler 已提交
651 652 653
        /* number of this disk */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
654

M
Mark Adler 已提交
655 656 657
        /* number of the disk with the start of the central directory */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
658

M
Mark Adler 已提交
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
        /* total number of entries in the central directory on this disk */
        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
            err=UNZ_ERRNO;

        /* total number of entries in the central directory */
        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
            err=UNZ_ERRNO;

        if ((number_entry_CD!=us.gi.number_entry) ||
            (number_disk_with_CD!=0) ||
            (number_disk!=0))
            err=UNZ_BADZIPFILE;

        /* size of the central directory */
        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
675

M
Mark Adler 已提交
676
        /* offset of start of central directory with respect to the
M
Mark Adler 已提交
677
          starting disk number */
M
Mark Adler 已提交
678 679
        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
            err=UNZ_ERRNO;
M
Mark Adler 已提交
680

M
Mark Adler 已提交
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
        us.gi.size_comment = 0;
    }
    else
    {
        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
        if (central_pos==0)
            err=UNZ_ERRNO;

        us.isZip64 = 0;

        if (ZSEEK64(us.z_filefunc, us.filestream,
                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
            err=UNZ_ERRNO;

        /* the signature, already checked */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;

        /* number of this disk */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
            err=UNZ_ERRNO;

        /* number of the disk with the start of the central directory */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
            err=UNZ_ERRNO;

        /* total number of entries in the central dir on this disk */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;
        us.gi.number_entry = uL;

        /* total number of entries in the central dir */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;
        number_entry_CD = uL;

        if ((number_entry_CD!=us.gi.number_entry) ||
            (number_disk_with_CD!=0) ||
            (number_disk!=0))
            err=UNZ_BADZIPFILE;

        /* size of the central directory */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;
        us.size_central_dir = uL;

        /* offset of start of central directory with respect to the
            starting disk number */
        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
            err=UNZ_ERRNO;
        us.offset_central_dir = uL;

        /* zipfile comment length */
        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
            err=UNZ_ERRNO;
    }
M
Mark Adler 已提交
737 738 739 740 741 742 743

    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
        (err==UNZ_OK))
        err=UNZ_BADZIPFILE;

    if (err!=UNZ_OK)
    {
M
Mark Adler 已提交
744
        ZCLOSE64(us.z_filefunc, us.filestream);
M
Mark Adler 已提交
745 746 747 748 749 750 751 752 753 754
        return NULL;
    }

    us.byte_before_the_zipfile = central_pos -
                            (us.offset_central_dir+us.size_central_dir);
    us.central_pos = central_pos;
    us.pfile_in_zip_read = NULL;
    us.encrypted = 0;


M
Mark Adler 已提交
755 756 757 758 759 760
    s=(unz64_s*)ALLOC(sizeof(unz64_s));
    if( s != NULL)
    {
        *s=us;
        unzGoToFirstFile((unzFile)s);
    }
M
Mark Adler 已提交
761 762 763 764
    return (unzFile)s;
}


M
Mark Adler 已提交
765 766
extern unzFile ZEXPORT unzOpen2 (const char *path,
                                        zlib_filefunc_def* pzlib_filefunc32_def)
M
Mark Adler 已提交
767
{
M
Mark Adler 已提交
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
    if (pzlib_filefunc32_def != NULL)
    {
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
    }
    else
        return unzOpenInternal(path, NULL, 0);
}

extern unzFile ZEXPORT unzOpen2_64 (const void *path,
                                     zlib_filefunc64_def* pzlib_filefunc_def)
{
    if (pzlib_filefunc_def != NULL)
    {
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
    }
    else
        return unzOpenInternal(path, NULL, 1);
}

extern unzFile ZEXPORT unzOpen (const char *path)
{
    return unzOpenInternal(path, NULL, 0);
}

extern unzFile ZEXPORT unzOpen64 (const void *path)
{
    return unzOpenInternal(path, NULL, 1);
M
Mark Adler 已提交
801 802 803 804 805 806 807
}

/*
  Close a ZipFile opened with unzipOpen.
  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
  return UNZ_OK if there is no problem. */
M
Mark Adler 已提交
808
extern int ZEXPORT unzClose (unzFile file)
M
Mark Adler 已提交
809
{
M
Mark Adler 已提交
810
    unz64_s* s;
M
Mark Adler 已提交
811 812
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
813
    s=(unz64_s*)file;
M
Mark Adler 已提交
814 815 816 817

    if (s->pfile_in_zip_read!=NULL)
        unzCloseCurrentFile(file);

M
Mark Adler 已提交
818
    ZCLOSE64(s->z_filefunc, s->filestream);
M
Mark Adler 已提交
819 820 821 822 823 824 825 826 827
    TRYFREE(s);
    return UNZ_OK;
}


/*
  Write info about the ZipFile in the *pglobal_info structure.
  No preparation of the structure is needed
  return UNZ_OK if there is no problem. */
M
Mark Adler 已提交
828
extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
M
Mark Adler 已提交
829
{
M
Mark Adler 已提交
830
    unz64_s* s;
M
Mark Adler 已提交
831 832
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
833
    s=(unz64_s*)file;
M
Mark Adler 已提交
834 835 836 837
    *pglobal_info=s->gi;
    return UNZ_OK;
}

M
Mark Adler 已提交
838 839 840 841 842 843 844 845 846 847 848
extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
{
    unz64_s* s;
    if (file==NULL)
        return UNZ_PARAMERROR;
    s=(unz64_s*)file;
    /* to do : check if number_entry is not truncated */
    pglobal_info32->number_entry = (uLong)s->gi.number_entry;
    pglobal_info32->size_comment = s->gi.size_comment;
    return UNZ_OK;
}
M
Mark Adler 已提交
849 850 851
/*
   Translate date/time from Dos format to tm_unz (readable more easilty)
*/
M
Mark Adler 已提交
852
local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
M
Mark Adler 已提交
853
{
M
Mark Adler 已提交
854 855
    ZPOS64_T uDate;
    uDate = (ZPOS64_T)(ulDosDate>>16);
M
Mark Adler 已提交
856 857 858 859 860 861 862 863 864 865 866 867
    ptm->tm_mday = (uInt)(uDate&0x1f) ;
    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;

    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
}

/*
  Get Info about the current file in the zipfile, with internal only info
*/
M
Mark Adler 已提交
868 869 870
local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
                                                  unz_file_info64 *pfile_info,
                                                  unz_file_info64_internal
M
Mark Adler 已提交
871 872 873 874 875 876 877 878
                                                  *pfile_info_internal,
                                                  char *szFileName,
                                                  uLong fileNameBufferSize,
                                                  void *extraField,
                                                  uLong extraFieldBufferSize,
                                                  char *szComment,
                                                  uLong commentBufferSize));

M
Mark Adler 已提交
879 880 881 882 883 884 885 886 887 888
local int unz64local_GetCurrentFileInfoInternal (unzFile file,
                                                  unz_file_info64 *pfile_info,
                                                  unz_file_info64_internal
                                                  *pfile_info_internal,
                                                  char *szFileName,
                                                  uLong fileNameBufferSize,
                                                  void *extraField,
                                                  uLong extraFieldBufferSize,
                                                  char *szComment,
                                                  uLong commentBufferSize)
M
Mark Adler 已提交
889
{
M
Mark Adler 已提交
890 891 892
    unz64_s* s;
    unz_file_info64 file_info;
    unz_file_info64_internal file_info_internal;
M
Mark Adler 已提交
893 894 895
    int err=UNZ_OK;
    uLong uMagic;
    long lSeek=0;
M
Mark Adler 已提交
896
    uLong uL;
M
Mark Adler 已提交
897 898 899

    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
900 901
    s=(unz64_s*)file;
    if (ZSEEK64(s->z_filefunc, s->filestream,
M
Mark Adler 已提交
902 903 904 905 906 907 908
              s->pos_in_central_dir+s->byte_before_the_zipfile,
              ZLIB_FILEFUNC_SEEK_SET)!=0)
        err=UNZ_ERRNO;


    /* we check the magic */
    if (err==UNZ_OK)
M
Mark Adler 已提交
909 910
    {
        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
M
Mark Adler 已提交
911 912 913
            err=UNZ_ERRNO;
        else if (uMagic!=0x02014b50)
            err=UNZ_BADZIPFILE;
M
Mark Adler 已提交
914
    }
M
Mark Adler 已提交
915

M
Mark Adler 已提交
916
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
M
Mark Adler 已提交
917 918
        err=UNZ_ERRNO;

M
Mark Adler 已提交
919
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
M
Mark Adler 已提交
920 921
        err=UNZ_ERRNO;

M
Mark Adler 已提交
922
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
M
Mark Adler 已提交
923 924
        err=UNZ_ERRNO;

M
Mark Adler 已提交
925
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
M
Mark Adler 已提交
926 927
        err=UNZ_ERRNO;

M
Mark Adler 已提交
928
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
M
Mark Adler 已提交
929 930
        err=UNZ_ERRNO;

M
Mark Adler 已提交
931
    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
M
Mark Adler 已提交
932

M
Mark Adler 已提交
933
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
M
Mark Adler 已提交
934 935
        err=UNZ_ERRNO;

M
Mark Adler 已提交
936
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
M
Mark Adler 已提交
937
        err=UNZ_ERRNO;
M
Mark Adler 已提交
938
    file_info.compressed_size = uL;
M
Mark Adler 已提交
939

M
Mark Adler 已提交
940
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
M
Mark Adler 已提交
941
        err=UNZ_ERRNO;
M
Mark Adler 已提交
942
    file_info.uncompressed_size = uL;
M
Mark Adler 已提交
943

M
Mark Adler 已提交
944
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
M
Mark Adler 已提交
945 946
        err=UNZ_ERRNO;

M
Mark Adler 已提交
947
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
M
Mark Adler 已提交
948 949
        err=UNZ_ERRNO;

M
Mark Adler 已提交
950
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
M
Mark Adler 已提交
951 952
        err=UNZ_ERRNO;

M
Mark Adler 已提交
953
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
M
Mark Adler 已提交
954 955
        err=UNZ_ERRNO;

M
Mark Adler 已提交
956
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
M
Mark Adler 已提交
957 958
        err=UNZ_ERRNO;

M
Mark Adler 已提交
959
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
M
Mark Adler 已提交
960 961
        err=UNZ_ERRNO;

M
Mark Adler 已提交
962
                // relative offset of local header
M
Mark Adler 已提交
963
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
M
Mark Adler 已提交
964
        err=UNZ_ERRNO;
M
Mark Adler 已提交
965
    file_info_internal.offset_curfile = uL;
M
Mark Adler 已提交
966 967 968 969 970 971 972 973 974 975 976 977 978 979

    lSeek+=file_info.size_filename;
    if ((err==UNZ_OK) && (szFileName!=NULL))
    {
        uLong uSizeRead ;
        if (file_info.size_filename<fileNameBufferSize)
        {
            *(szFileName+file_info.size_filename)='\0';
            uSizeRead = file_info.size_filename;
        }
        else
            uSizeRead = fileNameBufferSize;

        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
M
Mark Adler 已提交
980
            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
M
Mark Adler 已提交
981 982 983 984
                err=UNZ_ERRNO;
        lSeek -= uSizeRead;
    }

M
Mark Adler 已提交
985
    // Read extrafield
M
Mark Adler 已提交
986 987
    if ((err==UNZ_OK) && (extraField!=NULL))
    {
M
Mark Adler 已提交
988
        ZPOS64_T uSizeRead ;
M
Mark Adler 已提交
989 990 991 992 993 994
        if (file_info.size_file_extra<extraFieldBufferSize)
            uSizeRead = file_info.size_file_extra;
        else
            uSizeRead = extraFieldBufferSize;

        if (lSeek!=0)
M
Mark Adler 已提交
995 996
        {
            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
M
Mark Adler 已提交
997 998 999
                lSeek=0;
            else
                err=UNZ_ERRNO;
M
Mark Adler 已提交
1000 1001
        }

M
Mark Adler 已提交
1002
        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
M
Mark Adler 已提交
1003
            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
M
Mark Adler 已提交
1004
                err=UNZ_ERRNO;
M
Mark Adler 已提交
1005 1006

        lSeek += file_info.size_file_extra - (uLong)uSizeRead;
M
Mark Adler 已提交
1007 1008
    }
    else
M
Mark Adler 已提交
1009 1010 1011 1012 1013
        lSeek += file_info.size_file_extra;


    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
    {
M
Mark Adler 已提交
1014
                                uLong acc = 0;
M
Mark Adler 已提交
1015

M
Mark Adler 已提交
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
        // since lSeek now points to after the extra field we need to move back
        lSeek -= file_info.size_file_extra;

        if (lSeek!=0)
        {
            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
                lSeek=0;
            else
                err=UNZ_ERRNO;
        }

        while(acc < file_info.size_file_extra)
        {
            uLong headerId;
M
Mark Adler 已提交
1030
                                                uLong dataSize;
M
Mark Adler 已提交
1031

M
Mark Adler 已提交
1032 1033 1034 1035 1036 1037 1038 1039 1040
            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
                err=UNZ_ERRNO;

            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
                err=UNZ_ERRNO;

            /* ZIP64 extra fields */
            if (headerId == 0x0001)
            {
M
Mark Adler 已提交
1041 1042
                                                        uLong uL;

1043
                                                                if(file_info.uncompressed_size == MAXU32)
M
Mark Adler 已提交
1044 1045 1046 1047 1048
                                                                {
                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
                                                                                        err=UNZ_ERRNO;
                                                                }

1049
                                                                if(file_info.compressed_size == MAXU32)
M
Mark Adler 已提交
1050 1051 1052 1053 1054
                                                                {
                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
                                                                                  err=UNZ_ERRNO;
                                                                }

1055
                                                                if(file_info_internal.offset_curfile == MAXU32)
M
Mark Adler 已提交
1056 1057 1058 1059 1060 1061
                                                                {
                                                                        /* Relative Header offset */
                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
                                                                                err=UNZ_ERRNO;
                                                                }

1062
                                                                if(file_info.disk_num_start == MAXU32)
M
Mark Adler 已提交
1063 1064 1065 1066 1067
                                                                {
                                                                        /* Disk Start Number */
                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
                                                                                err=UNZ_ERRNO;
                                                                }
M
Mark Adler 已提交
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

            }
            else
            {
                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
                    err=UNZ_ERRNO;
            }

            acc += 2 + 2 + dataSize;
        }
    }
M
Mark Adler 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091

    if ((err==UNZ_OK) && (szComment!=NULL))
    {
        uLong uSizeRead ;
        if (file_info.size_file_comment<commentBufferSize)
        {
            *(szComment+file_info.size_file_comment)='\0';
            uSizeRead = file_info.size_file_comment;
        }
        else
            uSizeRead = commentBufferSize;

        if (lSeek!=0)
M
Mark Adler 已提交
1092 1093
        {
            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
M
Mark Adler 已提交
1094 1095 1096
                lSeek=0;
            else
                err=UNZ_ERRNO;
M
Mark Adler 已提交
1097 1098
        }

M
Mark Adler 已提交
1099
        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
M
Mark Adler 已提交
1100
            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
M
Mark Adler 已提交
1101 1102 1103 1104 1105 1106
                err=UNZ_ERRNO;
        lSeek+=file_info.size_file_comment - uSizeRead;
    }
    else
        lSeek+=file_info.size_file_comment;

M
Mark Adler 已提交
1107

M
Mark Adler 已提交
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
    if ((err==UNZ_OK) && (pfile_info!=NULL))
        *pfile_info=file_info;

    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
        *pfile_info_internal=file_info_internal;

    return err;
}



/*
  Write info about the ZipFile in the *pglobal_info structure.
  No preparation of the structure is needed
  return UNZ_OK if there is no problem.
*/
M
Mark Adler 已提交
1124 1125 1126 1127 1128
extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
                                          unz_file_info64 * pfile_info,
                                          char * szFileName, uLong fileNameBufferSize,
                                          void *extraField, uLong extraFieldBufferSize,
                                          char* szComment,  uLong commentBufferSize)
M
Mark Adler 已提交
1129
{
M
Mark Adler 已提交
1130
    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
M
Mark Adler 已提交
1131 1132 1133 1134 1135
                                                szFileName,fileNameBufferSize,
                                                extraField,extraFieldBufferSize,
                                                szComment,commentBufferSize);
}

M
Mark Adler 已提交
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
                                          unz_file_info * pfile_info,
                                          char * szFileName, uLong fileNameBufferSize,
                                          void *extraField, uLong extraFieldBufferSize,
                                          char* szComment,  uLong commentBufferSize)
{
    int err;
    unz_file_info64 file_info64;
    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
                                                szFileName,fileNameBufferSize,
                                                extraField,extraFieldBufferSize,
                                                szComment,commentBufferSize);
M
Mark Adler 已提交
1148
    if ((err==UNZ_OK) && (pfile_info != NULL))
M
Mark Adler 已提交
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
    {
        pfile_info->version = file_info64.version;
        pfile_info->version_needed = file_info64.version_needed;
        pfile_info->flag = file_info64.flag;
        pfile_info->compression_method = file_info64.compression_method;
        pfile_info->dosDate = file_info64.dosDate;
        pfile_info->crc = file_info64.crc;

        pfile_info->size_filename = file_info64.size_filename;
        pfile_info->size_file_extra = file_info64.size_file_extra;
        pfile_info->size_file_comment = file_info64.size_file_comment;

        pfile_info->disk_num_start = file_info64.disk_num_start;
        pfile_info->internal_fa = file_info64.internal_fa;
        pfile_info->external_fa = file_info64.external_fa;

        pfile_info->tmu_date = file_info64.tmu_date,


        pfile_info->compressed_size = (uLong)file_info64.compressed_size;
        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;

    }
    return err;
}
M
Mark Adler 已提交
1174 1175 1176 1177
/*
  Set the current file of the zipfile to the first file.
  return UNZ_OK if there is no problem
*/
M
Mark Adler 已提交
1178
extern int ZEXPORT unzGoToFirstFile (unzFile file)
M
Mark Adler 已提交
1179 1180
{
    int err=UNZ_OK;
M
Mark Adler 已提交
1181
    unz64_s* s;
M
Mark Adler 已提交
1182 1183
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1184
    s=(unz64_s*)file;
M
Mark Adler 已提交
1185 1186
    s->pos_in_central_dir=s->offset_central_dir;
    s->num_file=0;
M
Mark Adler 已提交
1187
    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
M
Mark Adler 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
                                             &s->cur_file_info_internal,
                                             NULL,0,NULL,0,NULL,0);
    s->current_file_ok = (err == UNZ_OK);
    return err;
}

/*
  Set the current file of the zipfile to the next file.
  return UNZ_OK if there is no problem
  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
M
Mark Adler 已提交
1199
extern int ZEXPORT unzGoToNextFile (unzFile  file)
M
Mark Adler 已提交
1200
{
M
Mark Adler 已提交
1201
    unz64_s* s;
M
Mark Adler 已提交
1202 1203 1204 1205
    int err;

    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1206
    s=(unz64_s*)file;
M
Mark Adler 已提交
1207 1208 1209 1210 1211 1212 1213 1214 1215
    if (!s->current_file_ok)
        return UNZ_END_OF_LIST_OF_FILE;
    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
      if (s->num_file+1==s->gi.number_entry)
        return UNZ_END_OF_LIST_OF_FILE;

    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
    s->num_file++;
M
Mark Adler 已提交
1216
    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
M
Mark Adler 已提交
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
                                               &s->cur_file_info_internal,
                                               NULL,0,NULL,0,NULL,0);
    s->current_file_ok = (err == UNZ_OK);
    return err;
}


/*
  Try locate the file szFileName in the zipfile.
  For the iCaseSensitivity signification, see unzipStringFileNameCompare

  return value :
  UNZ_OK if the file is found. It becomes the current file.
  UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
M
Mark Adler 已提交
1232
extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
M
Mark Adler 已提交
1233
{
M
Mark Adler 已提交
1234
    unz64_s* s;
M
Mark Adler 已提交
1235 1236 1237 1238 1239
    int err;

    /* We remember the 'current' position in the file so that we can jump
     * back there if we fail.
     */
M
Mark Adler 已提交
1240 1241 1242 1243
    unz_file_info64 cur_file_infoSaved;
    unz_file_info64_internal cur_file_info_internalSaved;
    ZPOS64_T num_fileSaved;
    ZPOS64_T pos_in_central_dirSaved;
M
Mark Adler 已提交
1244 1245 1246 1247 1248 1249 1250 1251


    if (file==NULL)
        return UNZ_PARAMERROR;

    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
        return UNZ_PARAMERROR;

M
Mark Adler 已提交
1252
    s=(unz64_s*)file;
M
Mark Adler 已提交
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
    if (!s->current_file_ok)
        return UNZ_END_OF_LIST_OF_FILE;

    /* Save the current state */
    num_fileSaved = s->num_file;
    pos_in_central_dirSaved = s->pos_in_central_dir;
    cur_file_infoSaved = s->cur_file_info;
    cur_file_info_internalSaved = s->cur_file_info_internal;

    err = unzGoToFirstFile(file);

    while (err == UNZ_OK)
    {
        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
M
Mark Adler 已提交
1267
        err = unzGetCurrentFileInfo64(file,NULL,
M
Mark Adler 已提交
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
                                    NULL,0,NULL,0);
        if (err == UNZ_OK)
        {
            if (unzStringFileNameCompare(szCurrentFileName,
                                            szFileName,iCaseSensitivity)==0)
                return UNZ_OK;
            err = unzGoToNextFile(file);
        }
    }

    /* We failed, so restore the state of the 'current file' to where we
     * were.
     */
    s->num_file = num_fileSaved ;
    s->pos_in_central_dir = pos_in_central_dirSaved ;
    s->cur_file_info = cur_file_infoSaved;
    s->cur_file_info_internal = cur_file_info_internalSaved;
    return err;
}


/*
///////////////////////////////////////////
// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
// I need random access
//
// Further optimization could be realized by adding an ability
// to cache the directory in memory. The goal being a single
// comprehensive file read to put the file I need in a memory.
*/

/*
typedef struct unz_file_pos_s
{
M
Mark Adler 已提交
1303 1304
    ZPOS64_T pos_in_zip_directory;   // offset in file
    ZPOS64_T num_of_file;            // # of file
M
Mark Adler 已提交
1305 1306 1307
} unz_file_pos;
*/

M
Mark Adler 已提交
1308
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
M
Mark Adler 已提交
1309
{
M
Mark Adler 已提交
1310
    unz64_s* s;
M
Mark Adler 已提交
1311 1312 1313

    if (file==NULL || file_pos==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1314
    s=(unz64_s*)file;
M
Mark Adler 已提交
1315 1316 1317 1318 1319 1320 1321 1322 1323
    if (!s->current_file_ok)
        return UNZ_END_OF_LIST_OF_FILE;

    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
    file_pos->num_of_file           = s->num_file;

    return UNZ_OK;
}

M
Mark Adler 已提交
1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
extern int ZEXPORT unzGetFilePos(
    unzFile file,
    unz_file_pos* file_pos)
{
    unz64_file_pos file_pos64;
    int err = unzGetFilePos64(file,&file_pos64);
    if (err==UNZ_OK)
    {
        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
        file_pos->num_of_file = (uLong)file_pos64.num_of_file;
    }
    return err;
}

extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
M
Mark Adler 已提交
1339
{
M
Mark Adler 已提交
1340
    unz64_s* s;
M
Mark Adler 已提交
1341 1342 1343 1344
    int err;

    if (file==NULL || file_pos==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1345
    s=(unz64_s*)file;
M
Mark Adler 已提交
1346 1347 1348 1349 1350 1351

    /* jump to the right spot */
    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
    s->num_file           = file_pos->num_of_file;

    /* set the current file */
M
Mark Adler 已提交
1352
    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
M
Mark Adler 已提交
1353 1354 1355 1356 1357 1358 1359
                                               &s->cur_file_info_internal,
                                               NULL,0,NULL,0,NULL,0);
    /* return results */
    s->current_file_ok = (err == UNZ_OK);
    return err;
}

M
Mark Adler 已提交
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
extern int ZEXPORT unzGoToFilePos(
    unzFile file,
    unz_file_pos* file_pos)
{
    unz64_file_pos file_pos64;
    if (file_pos == NULL)
        return UNZ_PARAMERROR;

    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
    file_pos64.num_of_file = file_pos->num_of_file;
    return unzGoToFilePos64(file,&file_pos64);
}

M
Mark Adler 已提交
1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
/*
// Unzip Helper Functions - should be here?
///////////////////////////////////////////
*/

/*
  Read the local header of the current zipfile
  Check the coherency of the local header and info in the end of central
        directory about this file
  store in *piSizeVar the size of extra info in local header
        (filename and size of extra field data)
*/
M
Mark Adler 已提交
1385 1386 1387
local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
                                                    ZPOS64_T * poffset_local_extrafield,
                                                    uInt  * psize_local_extrafield)
M
Mark Adler 已提交
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397
{
    uLong uMagic,uData,uFlags;
    uLong size_filename;
    uLong size_extra_field;
    int err=UNZ_OK;

    *piSizeVar = 0;
    *poffset_local_extrafield = 0;
    *psize_local_extrafield = 0;

M
Mark Adler 已提交
1398
    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
M
Mark Adler 已提交
1399 1400 1401 1402 1403
                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
        return UNZ_ERRNO;


    if (err==UNZ_OK)
M
Mark Adler 已提交
1404 1405
    {
        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
M
Mark Adler 已提交
1406 1407 1408
            err=UNZ_ERRNO;
        else if (uMagic!=0x04034b50)
            err=UNZ_BADZIPFILE;
M
Mark Adler 已提交
1409
    }
M
Mark Adler 已提交
1410

M
Mark Adler 已提交
1411
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
M
Mark Adler 已提交
1412 1413 1414 1415 1416
        err=UNZ_ERRNO;
/*
    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
        err=UNZ_BADZIPFILE;
*/
M
Mark Adler 已提交
1417
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
M
Mark Adler 已提交
1418 1419
        err=UNZ_ERRNO;

M
Mark Adler 已提交
1420
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
M
Mark Adler 已提交
1421 1422 1423 1424 1425
        err=UNZ_ERRNO;
    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
        err=UNZ_BADZIPFILE;

    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
M
Mark Adler 已提交
1426 1427 1428
/* #ifdef HAVE_BZIP2 */
                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
/* #endif */
M
Mark Adler 已提交
1429 1430 1431
                         (s->cur_file_info.compression_method!=Z_DEFLATED))
        err=UNZ_BADZIPFILE;

M
Mark Adler 已提交
1432
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
M
Mark Adler 已提交
1433 1434
        err=UNZ_ERRNO;

M
Mark Adler 已提交
1435
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
M
Mark Adler 已提交
1436
        err=UNZ_ERRNO;
M
Mark Adler 已提交
1437
    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
M
Mark Adler 已提交
1438 1439
        err=UNZ_BADZIPFILE;

M
Mark Adler 已提交
1440
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
M
Mark Adler 已提交
1441
        err=UNZ_ERRNO;
M
Mark Adler 已提交
1442
    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
M
Mark Adler 已提交
1443 1444
        err=UNZ_BADZIPFILE;

M
Mark Adler 已提交
1445
    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
M
Mark Adler 已提交
1446
        err=UNZ_ERRNO;
M
Mark Adler 已提交
1447
    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
M
Mark Adler 已提交
1448 1449
        err=UNZ_BADZIPFILE;

M
Mark Adler 已提交
1450
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
M
Mark Adler 已提交
1451 1452 1453 1454 1455 1456
        err=UNZ_ERRNO;
    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
        err=UNZ_BADZIPFILE;

    *piSizeVar += (uInt)size_filename;

M
Mark Adler 已提交
1457
    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
M
Mark Adler 已提交
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
        err=UNZ_ERRNO;
    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
                                    SIZEZIPLOCALHEADER + size_filename;
    *psize_local_extrafield = (uInt)size_extra_field;

    *piSizeVar += (uInt)size_extra_field;

    return err;
}

/*
  Open for reading data the current file in the zipfile.
  If there is no error and the file is opened, the return value is UNZ_OK.
*/
M
Mark Adler 已提交
1472 1473
extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
                                            int* level, int raw, const char* password)
M
Mark Adler 已提交
1474 1475 1476
{
    int err=UNZ_OK;
    uInt iSizeVar;
M
Mark Adler 已提交
1477 1478 1479
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
M
Mark Adler 已提交
1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
    uInt  size_local_extrafield;    /* size of the local extra field */
#    ifndef NOUNCRYPT
    char source[12];
#    else
    if (password != NULL)
        return UNZ_PARAMERROR;
#    endif

    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1490
    s=(unz64_s*)file;
M
Mark Adler 已提交
1491 1492 1493 1494 1495 1496
    if (!s->current_file_ok)
        return UNZ_PARAMERROR;

    if (s->pfile_in_zip_read != NULL)
        unzCloseCurrentFile(file);

M
Mark Adler 已提交
1497
    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
M
Mark Adler 已提交
1498 1499
        return UNZ_BADZIPFILE;

M
Mark Adler 已提交
1500
    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
M
Mark Adler 已提交
1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
    if (pfile_in_zip_read_info==NULL)
        return UNZ_INTERNALERROR;

    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
    pfile_in_zip_read_info->pos_local_extrafield=0;
    pfile_in_zip_read_info->raw=raw;

    if (pfile_in_zip_read_info->read_buffer==NULL)
    {
        TRYFREE(pfile_in_zip_read_info);
        return UNZ_INTERNALERROR;
    }

    pfile_in_zip_read_info->stream_initialised=0;

    if (method!=NULL)
        *method = (int)s->cur_file_info.compression_method;

    if (level!=NULL)
    {
        *level = 6;
        switch (s->cur_file_info.flag & 0x06)
        {
          case 6 : *level = 1; break;
          case 4 : *level = 2; break;
          case 2 : *level = 9; break;
        }
    }

    if ((s->cur_file_info.compression_method!=0) &&
M
Mark Adler 已提交
1533 1534 1535
/* #ifdef HAVE_BZIP2 */
        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
/* #endif */
M
Mark Adler 已提交
1536
        (s->cur_file_info.compression_method!=Z_DEFLATED))
M
Mark Adler 已提交
1537

M
Mark Adler 已提交
1538 1539 1540 1541
        err=UNZ_BADZIPFILE;

    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
    pfile_in_zip_read_info->crc32=0;
M
Mark Adler 已提交
1542 1543
    pfile_in_zip_read_info->total_out_64=0;
    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
M
Mark Adler 已提交
1544 1545 1546 1547 1548 1549
    pfile_in_zip_read_info->filestream=s->filestream;
    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

    pfile_in_zip_read_info->stream.total_out = 0;

M
Mark Adler 已提交
1550
    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
M
Mark Adler 已提交
1551
    {
M
Mark Adler 已提交
1552 1553 1554 1555 1556 1557
#ifdef HAVE_BZIP2
      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
      pfile_in_zip_read_info->bstream.state = (voidpf)0;

M
Mark Adler 已提交
1558 1559 1560 1561 1562 1563
      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
      pfile_in_zip_read_info->stream.zfree = (free_func)0;
      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
      pfile_in_zip_read_info->stream.avail_in = 0;

M
Mark Adler 已提交
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
      if (err == Z_OK)
        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
      else
      {
        TRYFREE(pfile_in_zip_read_info);
        return err;
      }
#else
      pfile_in_zip_read_info->raw=1;
#endif
    }
    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
    {
      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
      pfile_in_zip_read_info->stream.zfree = (free_func)0;
      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
      pfile_in_zip_read_info->stream.next_in = 0;
      pfile_in_zip_read_info->stream.avail_in = 0;

M
Mark Adler 已提交
1584 1585
      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
      if (err == Z_OK)
M
Mark Adler 已提交
1586
        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
M
Mark Adler 已提交
1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
      else
      {
        TRYFREE(pfile_in_zip_read_info);
        return err;
      }
        /* windowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
         * size of both compressed and uncompressed data
         */
    }
    pfile_in_zip_read_info->rest_read_compressed =
            s->cur_file_info.compressed_size ;
    pfile_in_zip_read_info->rest_read_uncompressed =
            s->cur_file_info.uncompressed_size ;


    pfile_in_zip_read_info->pos_in_zipfile =
            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
              iSizeVar;

    pfile_in_zip_read_info->stream.avail_in = (uInt)0;

    s->pfile_in_zip_read = pfile_in_zip_read_info;
M
Mark Adler 已提交
1613
                s->encrypted = 0;
M
Mark Adler 已提交
1614

M
Mark Adler 已提交
1615 1616 1617 1618 1619 1620
#    ifndef NOUNCRYPT
    if (password != NULL)
    {
        int i;
        s->pcrc_32_tab = get_crc_table();
        init_keys(password,s->keys,s->pcrc_32_tab);
M
Mark Adler 已提交
1621
        if (ZSEEK64(s->z_filefunc, s->filestream,
M
Mark Adler 已提交
1622 1623 1624 1625
                  s->pfile_in_zip_read->pos_in_zipfile +
                     s->pfile_in_zip_read->byte_before_the_zipfile,
                  SEEK_SET)!=0)
            return UNZ_INTERNALERROR;
M
Mark Adler 已提交
1626
        if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
M
Mark Adler 已提交
1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
            return UNZ_INTERNALERROR;

        for (i = 0; i<12; i++)
            zdecode(s->keys,s->pcrc_32_tab,source[i]);

        s->pfile_in_zip_read->pos_in_zipfile+=12;
        s->encrypted=1;
    }
#    endif


    return UNZ_OK;
}

M
Mark Adler 已提交
1641
extern int ZEXPORT unzOpenCurrentFile (unzFile file)
M
Mark Adler 已提交
1642 1643 1644 1645
{
    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
}

M
Mark Adler 已提交
1646
extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
M
Mark Adler 已提交
1647 1648 1649 1650
{
    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
}

M
Mark Adler 已提交
1651
extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
M
Mark Adler 已提交
1652 1653 1654 1655
{
    return unzOpenCurrentFile3(file, method, level, raw, NULL);
}

M
Mark Adler 已提交
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673
/** Addition for GDAL : START */

extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
{
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
    s=(unz64_s*)file;
    if (file==NULL)
        return 0; //UNZ_PARAMERROR;
    pfile_in_zip_read_info=s->pfile_in_zip_read;
    if (pfile_in_zip_read_info==NULL)
        return 0; //UNZ_PARAMERROR;
    return pfile_in_zip_read_info->pos_in_zipfile +
                         pfile_in_zip_read_info->byte_before_the_zipfile;
}

/** Addition for GDAL : END */

M
Mark Adler 已提交
1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
/*
  Read bytes from the current file.
  buf contain buffer where data must be copied
  len the size of buf.

  return the number of byte copied if somes bytes are copied
  return 0 if the end of file was reached
  return <0 with error code if there is an error
    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
M
Mark Adler 已提交
1684
extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
M
Mark Adler 已提交
1685 1686 1687
{
    int err=UNZ_OK;
    uInt iRead = 0;
M
Mark Adler 已提交
1688 1689
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
M
Mark Adler 已提交
1690 1691
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1692
    s=(unz64_s*)file;
M
Mark Adler 已提交
1693 1694 1695 1696 1697 1698
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;


1699
    if (pfile_in_zip_read_info->read_buffer == NULL)
M
Mark Adler 已提交
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729
        return UNZ_END_OF_LIST_OF_FILE;
    if (len==0)
        return 0;

    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;

    pfile_in_zip_read_info->stream.avail_out = (uInt)len;

    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
        (!(pfile_in_zip_read_info->raw)))
        pfile_in_zip_read_info->stream.avail_out =
            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;

    if ((len>pfile_in_zip_read_info->rest_read_compressed+
           pfile_in_zip_read_info->stream.avail_in) &&
         (pfile_in_zip_read_info->raw))
        pfile_in_zip_read_info->stream.avail_out =
            (uInt)pfile_in_zip_read_info->rest_read_compressed+
            pfile_in_zip_read_info->stream.avail_in;

    while (pfile_in_zip_read_info->stream.avail_out>0)
    {
        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
            (pfile_in_zip_read_info->rest_read_compressed>0))
        {
            uInt uReadThis = UNZ_BUFSIZE;
            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
            if (uReadThis == 0)
                return UNZ_EOF;
M
Mark Adler 已提交
1730
            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
M
Mark Adler 已提交
1731 1732 1733 1734 1735
                      pfile_in_zip_read_info->filestream,
                      pfile_in_zip_read_info->pos_in_zipfile +
                         pfile_in_zip_read_info->byte_before_the_zipfile,
                         ZLIB_FILEFUNC_SEEK_SET)!=0)
                return UNZ_ERRNO;
M
Mark Adler 已提交
1736
            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
M
Mark Adler 已提交
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
                      pfile_in_zip_read_info->filestream,
                      pfile_in_zip_read_info->read_buffer,
                      uReadThis)!=uReadThis)
                return UNZ_ERRNO;


#            ifndef NOUNCRYPT
            if(s->encrypted)
            {
                uInt i;
                for(i=0;i<uReadThis;i++)
                  pfile_in_zip_read_info->read_buffer[i] =
                      zdecode(s->keys,s->pcrc_32_tab,
                              pfile_in_zip_read_info->read_buffer[i]);
            }
#            endif


            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;

            pfile_in_zip_read_info->stream.next_in =
                (Bytef*)pfile_in_zip_read_info->read_buffer;
            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
        }

        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
        {
            uInt uDoCopy,i ;

            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
                return (iRead==0) ? UNZ_EOF : iRead;

            if (pfile_in_zip_read_info->stream.avail_out <
                            pfile_in_zip_read_info->stream.avail_in)
                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
            else
                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;

            for (i=0;i<uDoCopy;i++)
                *(pfile_in_zip_read_info->stream.next_out+i) =
                        *(pfile_in_zip_read_info->stream.next_in+i);

M
Mark Adler 已提交
1782 1783
            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;

M
Mark Adler 已提交
1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
                                pfile_in_zip_read_info->stream.next_out,
                                uDoCopy);
            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
            pfile_in_zip_read_info->stream.next_out += uDoCopy;
            pfile_in_zip_read_info->stream.next_in += uDoCopy;
            pfile_in_zip_read_info->stream.total_out += uDoCopy;
            iRead += uDoCopy;
        }
M
Mark Adler 已提交
1795
        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
M
Mark Adler 已提交
1796
        {
M
Mark Adler 已提交
1797
#ifdef HAVE_BZIP2
M
Mark Adler 已提交
1798 1799 1800
            uLong uTotalOutBefore,uTotalOutAfter;
            const Bytef *bufBefore;
            uLong uOutThis;
M
Mark Adler 已提交
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830

            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;

            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;

            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);

            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
            uOutThis = uTotalOutAfter-uTotalOutBefore;

            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;

            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);

            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
M
Mark Adler 已提交
1831

M
Mark Adler 已提交
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842
            if (err==BZ_STREAM_END)
              return (iRead==0) ? UNZ_EOF : iRead;
            if (err!=BZ_OK)
              break;
#endif
        } // end Z_BZIP2ED
        else
        {
            ZPOS64_T uTotalOutBefore,uTotalOutAfter;
            const Bytef *bufBefore;
            ZPOS64_T uOutThis;
M
Mark Adler 已提交
1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861
            int flush=Z_SYNC_FLUSH;

            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
            bufBefore = pfile_in_zip_read_info->stream.next_out;

            /*
            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
                     pfile_in_zip_read_info->stream.avail_out) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
                flush = Z_FINISH;
            */
            err=inflate(&pfile_in_zip_read_info->stream,flush);

            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
              err = Z_DATA_ERROR;

            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
            uOutThis = uTotalOutAfter-uTotalOutBefore;

M
Mark Adler 已提交
1862 1863
            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;

M
Mark Adler 已提交
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888
            pfile_in_zip_read_info->crc32 =
                crc32(pfile_in_zip_read_info->crc32,bufBefore,
                        (uInt)(uOutThis));

            pfile_in_zip_read_info->rest_read_uncompressed -=
                uOutThis;

            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);

            if (err==Z_STREAM_END)
                return (iRead==0) ? UNZ_EOF : iRead;
            if (err!=Z_OK)
                break;
        }
    }

    if (err==Z_OK)
        return iRead;
    return err;
}


/*
  Give the current position in uncompressed data
*/
M
Mark Adler 已提交
1889
extern z_off_t ZEXPORT unztell (unzFile file)
M
Mark Adler 已提交
1890
{
M
Mark Adler 已提交
1891 1892
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
M
Mark Adler 已提交
1893 1894
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1895
    s=(unz64_s*)file;
M
Mark Adler 已提交
1896 1897 1898 1899 1900 1901 1902 1903
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;

    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
}

M
Mark Adler 已提交
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
{

    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
    if (file==NULL)
        return (ZPOS64_T)-1;
    s=(unz64_s*)file;
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return (ZPOS64_T)-1;

    return pfile_in_zip_read_info->total_out_64;
}

M
Mark Adler 已提交
1920 1921 1922 1923

/*
  return 1 if the end of file was reached, 0 elsewhere
*/
M
Mark Adler 已提交
1924
extern int ZEXPORT unzeof (unzFile file)
M
Mark Adler 已提交
1925
{
M
Mark Adler 已提交
1926 1927
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
M
Mark Adler 已提交
1928 1929
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1930
    s=(unz64_s*)file;
M
Mark Adler 已提交
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;

    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
        return 1;
    else
        return 0;
}



/*
M
Mark Adler 已提交
1945 1946 1947
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
M
Mark Adler 已提交
1948 1949 1950 1951 1952 1953 1954 1955

  if buf==NULL, it return the size of the local extra field that can be read

  if buf!=NULL, len is the size of the buffer, the extra header is copied in
    buf.
  the return value is the number of bytes copied in buf, or (if <0)
    the error code
*/
M
Mark Adler 已提交
1956
extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
M
Mark Adler 已提交
1957
{
M
Mark Adler 已提交
1958 1959
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
M
Mark Adler 已提交
1960
    uInt read_now;
M
Mark Adler 已提交
1961
    ZPOS64_T size_to_read;
M
Mark Adler 已提交
1962 1963 1964

    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
1965
    s=(unz64_s*)file;
M
Mark Adler 已提交
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;

    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
                pfile_in_zip_read_info->pos_local_extrafield);

    if (buf==NULL)
        return (int)size_to_read;

    if (len>size_to_read)
        read_now = (uInt)size_to_read;
    else
        read_now = (uInt)len ;

    if (read_now==0)
        return 0;

M
Mark Adler 已提交
1985
    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
M
Mark Adler 已提交
1986 1987 1988 1989 1990 1991
              pfile_in_zip_read_info->filestream,
              pfile_in_zip_read_info->offset_local_extrafield +
              pfile_in_zip_read_info->pos_local_extrafield,
              ZLIB_FILEFUNC_SEEK_SET)!=0)
        return UNZ_ERRNO;

M
Mark Adler 已提交
1992
    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
M
Mark Adler 已提交
1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
              pfile_in_zip_read_info->filestream,
              buf,read_now)!=read_now)
        return UNZ_ERRNO;

    return (int)read_now;
}

/*
  Close the file in zip opened with unzipOpenCurrentFile
  Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
M
Mark Adler 已提交
2004
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
M
Mark Adler 已提交
2005 2006 2007
{
    int err=UNZ_OK;

M
Mark Adler 已提交
2008 2009
    unz64_s* s;
    file_in_zip64_read_info_s* pfile_in_zip_read_info;
M
Mark Adler 已提交
2010 2011
    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
2012
    s=(unz64_s*)file;
M
Mark Adler 已提交
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;


    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
        (!pfile_in_zip_read_info->raw))
    {
        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
            err=UNZ_CRCERROR;
    }


    TRYFREE(pfile_in_zip_read_info->read_buffer);
    pfile_in_zip_read_info->read_buffer = NULL;
M
Mark Adler 已提交
2029
    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
M
Mark Adler 已提交
2030
        inflateEnd(&pfile_in_zip_read_info->stream);
M
Mark Adler 已提交
2031 2032 2033 2034 2035
#ifdef HAVE_BZIP2
    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
#endif

M
Mark Adler 已提交
2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050

    pfile_in_zip_read_info->stream_initialised = 0;
    TRYFREE(pfile_in_zip_read_info);

    s->pfile_in_zip_read=NULL;

    return err;
}


/*
  Get the global comment string of the ZipFile, in the szComment buffer.
  uSizeBuf is the size of the szComment buffer.
  return the number of byte copied or an error code <0
*/
M
Mark Adler 已提交
2051
extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
M
Mark Adler 已提交
2052
{
M
Mark Adler 已提交
2053
    unz64_s* s;
M
Mark Adler 已提交
2054 2055
    uLong uReadThis ;
    if (file==NULL)
M
Mark Adler 已提交
2056
        return (int)UNZ_PARAMERROR;
M
Mark Adler 已提交
2057
    s=(unz64_s*)file;
M
Mark Adler 已提交
2058 2059 2060 2061 2062

    uReadThis = uSizeBuf;
    if (uReadThis>s->gi.size_comment)
        uReadThis = s->gi.size_comment;

M
Mark Adler 已提交
2063
    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
M
Mark Adler 已提交
2064 2065 2066 2067 2068
        return UNZ_ERRNO;

    if (uReadThis>0)
    {
      *szComment='\0';
M
Mark Adler 已提交
2069
      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
M
Mark Adler 已提交
2070 2071 2072 2073 2074 2075 2076 2077 2078
        return UNZ_ERRNO;
    }

    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
        *(szComment+s->gi.size_comment)='\0';
    return (int)uReadThis;
}

/* Additions by RX '2004 */
M
Mark Adler 已提交
2079
extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
M
Mark Adler 已提交
2080
{
M
Mark Adler 已提交
2081
    unz64_s* s;
M
Mark Adler 已提交
2082 2083

    if (file==NULL)
M
Mark Adler 已提交
2084 2085
          return 0; //UNZ_PARAMERROR;
    s=(unz64_s*)file;
M
Mark Adler 已提交
2086 2087 2088 2089 2090 2091 2092 2093
    if (!s->current_file_ok)
      return 0;
    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
      if (s->num_file==s->gi.number_entry)
         return 0;
    return s->pos_in_central_dir;
}

M
Mark Adler 已提交
2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
extern uLong ZEXPORT unzGetOffset (unzFile file)
{
    ZPOS64_T offset64;

    if (file==NULL)
          return 0; //UNZ_PARAMERROR;
    offset64 = unzGetOffset64(file);
    return (uLong)offset64;
}

extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
M
Mark Adler 已提交
2105
{
M
Mark Adler 已提交
2106
    unz64_s* s;
M
Mark Adler 已提交
2107 2108 2109 2110
    int err;

    if (file==NULL)
        return UNZ_PARAMERROR;
M
Mark Adler 已提交
2111
    s=(unz64_s*)file;
M
Mark Adler 已提交
2112 2113 2114

    s->pos_in_central_dir = pos;
    s->num_file = s->gi.number_entry;      /* hack */
M
Mark Adler 已提交
2115
    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
M
Mark Adler 已提交
2116 2117 2118 2119 2120
                                              &s->cur_file_info_internal,
                                              NULL,0,NULL,0,NULL,0);
    s->current_file_ok = (err == UNZ_OK);
    return err;
}
M
Mark Adler 已提交
2121 2122 2123 2124 2125

extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
{
    return unzSetOffset64(file,pos);
}