LCOV - code coverage report
Current view: top level - port - cpl_minizip_unzip.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 516 906 57.0 %
Date: 2025-01-18 12:42:00 Functions: 23 36 63.9 %

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

Generated by: LCOV version 1.14