LCOV - code coverage report
Current view: top level - port - cpl_minizip_unzip.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 516 905 57.0 %
Date: 2025-09-10 17:48:50 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     2550500 : static int unzlocal_getByte(const zlib_filefunc_def *pzlib_filefunc_def,
     174             :                             voidpf filestream, int *pi)
     175             : {
     176     2550500 :     unsigned char c = 0;
     177             :     const int err =
     178     2550500 :         static_cast<int>(ZREAD(*pzlib_filefunc_def, filestream, &c, 1));
     179     2550500 :     if (err == 1)
     180             :     {
     181     2550470 :         *pi = static_cast<int>(c);
     182     2550470 :         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      574182 : static int unzlocal_getShort(const zlib_filefunc_def *pzlib_filefunc_def,
     197             :                              voidpf filestream, uLong *pX)
     198             : {
     199      574182 :     int i = 0;
     200      574182 :     int err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     201      574182 :     uLong x = static_cast<uLong>(i);
     202             : 
     203      574182 :     if (err == UNZ_OK)
     204      574182 :         err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     205      574182 :     x += static_cast<uLong>(i) << 8;
     206             : 
     207      574182 :     if (err == UNZ_OK)
     208      574182 :         *pX = x;
     209             :     else
     210           0 :         *pX = 0;
     211      574182 :     return err;
     212             : }
     213             : 
     214      350383 : static int unzlocal_getLong(const zlib_filefunc_def *pzlib_filefunc_def,
     215             :                             voidpf filestream, uLong *pX)
     216             : {
     217      350383 :     int i = 0;
     218      350383 :     int err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     219      350383 :     uLong x = static_cast<uLong>(i);
     220             : 
     221      350383 :     if (err == UNZ_OK)
     222      350383 :         err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     223      350383 :     x += static_cast<uLong>(i) << 8;
     224             : 
     225      350383 :     if (err == UNZ_OK)
     226      350383 :         err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     227      350383 :     x += static_cast<uLong>(i) << 16;
     228             : 
     229      350383 :     if (err == UNZ_OK)
     230      350383 :         err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i);
     231      350383 :     x += static_cast<uLong>(i) << 24;
     232             : 
     233      350383 :     if (err == UNZ_OK)
     234      350383 :         *pX = x;
     235             :     else
     236           0 :         *pX = 0;
     237      350383 :     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        5290 : unzlocal_SearchCentralDir(const zlib_filefunc_def *pzlib_filefunc_def,
     348             :                           voidpf filestream)
     349             : {
     350        5290 :     if (ZSEEK(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
     351           0 :         return 0;
     352             : 
     353             :     unsigned char *buf =
     354        5290 :         static_cast<unsigned char *>(ALLOC(BUFREADCOMMENT + 4));
     355        5290 :     if (buf == nullptr)
     356           0 :         return 0;
     357             : 
     358        5290 :     const uLong64 uSizeFile = ZTELL(*pzlib_filefunc_def, filestream);
     359             : 
     360        5290 :     uLong64 uMaxBack = 0xffff; /* maximum size of global comment */
     361        5290 :     if (uMaxBack > uSizeFile)
     362        2165 :         uMaxBack = uSizeFile;
     363             : 
     364        5290 :     uLong64 uPosFound = 0;
     365        5290 :     uLong64 uBackRead = 4;
     366        5293 :     while (uBackRead < uMaxBack)
     367             :     {
     368        5289 :         if (uBackRead + BUFREADCOMMENT > uMaxBack)
     369         295 :             uBackRead = uMaxBack;
     370             :         else
     371        4994 :             uBackRead += BUFREADCOMMENT;
     372        5289 :         const uLong64 uReadPos = uSizeFile - uBackRead;
     373             : 
     374        5289 :         const uLong uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos))
     375             :                                     ? (BUFREADCOMMENT + 4)
     376             :                                     : static_cast<uLong>(uSizeFile - uReadPos);
     377        5289 :         if (ZSEEK(*pzlib_filefunc_def, filestream, uReadPos,
     378        5289 :                   ZLIB_FILEFUNC_SEEK_SET) != 0)
     379           0 :             break;
     380             : 
     381        5289 :         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      100491 :         for (int i = static_cast<int>(uReadSize) - 3; (i--) > 0;)
     386      100491 :             if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) &&
     387        5289 :                 ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06))
     388             :             {
     389        5289 :                 uPosFound = uReadPos + i;
     390        5289 :                 break;
     391             :             }
     392             : 
     393        5289 :         if (uPosFound != 0)
     394        5286 :             break;
     395             :     }
     396        5290 :     TRYFREE(buf);
     397        5290 :     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        5294 : unzlocal_SearchCentralDir64(const zlib_filefunc_def *pzlib_filefunc_def,
     406             :                             voidpf filestream)
     407             : {
     408             :     unsigned char *buf;
     409             :     uLong64 uSizeFile;
     410             :     uLong64 uBackRead;
     411        5294 :     uLong64 uMaxBack = 0xffff; /* maximum size of global comment */
     412        5294 :     uLong64 uPosFound = 0;
     413             :     uLong uL;
     414             : 
     415        5294 :     if (ZSEEK(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
     416           0 :         return 0;
     417             : 
     418        5294 :     uSizeFile = ZTELL(*pzlib_filefunc_def, filestream);
     419             : 
     420        5294 :     if (uMaxBack > uSizeFile)
     421        2165 :         uMaxBack = uSizeFile;
     422             : 
     423        5294 :     buf = static_cast<unsigned char *>(ALLOC(BUFREADCOMMENT + 4));
     424        5294 :     if (buf == nullptr)
     425           0 :         return 0;
     426             : 
     427        5294 :     uBackRead = 4;
     428      250513 :     while (uBackRead < uMaxBack)
     429             :     {
     430             :         uLong uReadSize;
     431             :         uLong64 uReadPos;
     432      245223 :         if (uBackRead + BUFREADCOMMENT > uMaxBack)
     433        5289 :             uBackRead = uMaxBack;
     434             :         else
     435      239934 :             uBackRead += BUFREADCOMMENT;
     436      245223 :         uReadPos = uSizeFile - uBackRead;
     437             : 
     438      245223 :         uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos))
     439             :                         ? (BUFREADCOMMENT + 4)
     440             :                         : static_cast<uLong>(uSizeFile - uReadPos);
     441      245223 :         if (ZSEEK(*pzlib_filefunc_def, filestream, uReadPos,
     442      245223 :                   ZLIB_FILEFUNC_SEEK_SET) != 0)
     443           0 :             break;
     444             : 
     445      245223 :         if (ZREAD(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize)
     446           0 :             break;
     447             : 
     448   251423000 :         for (int i = static_cast<int>(uReadSize) - 3; (i--) > 0;)
     449   251177000 :             if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) &&
     450     1106980 :                 ((*(buf + i + 2)) == 0x06) && ((*(buf + i + 3)) == 0x07))
     451             :             {
     452           4 :                 uPosFound = uReadPos + i;
     453           4 :                 break;
     454             :             }
     455             : 
     456      245223 :         if (uPosFound != 0)
     457           4 :             break;
     458             :     }
     459        5294 :     TRYFREE(buf);
     460        5294 :     if (uPosFound == 0)
     461        5290 :         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        5294 : 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        5294 :     int err = UNZ_OK;
     534             : 
     535        5294 :     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        5294 :     central_pos = (unz_copyright[0] != ' ');
     540             : 
     541        5294 :     if (pzlib_filefunc_def == nullptr)
     542        5294 :         cpl_fill_fopen_filefunc(&us.z_filefunc);
     543             :     else
     544           0 :         us.z_filefunc = *pzlib_filefunc_def;
     545             : 
     546        5294 :     us.filestream = (*(us.z_filefunc.zopen_file))(
     547             :         us.z_filefunc.opaque, path,
     548             :         ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
     549        5294 :     if (us.filestream == nullptr)
     550           0 :         return nullptr;
     551             : 
     552        5294 :     central_pos += unzlocal_SearchCentralDir64(&us.z_filefunc, us.filestream);
     553        5294 :     if (central_pos)
     554             :     {
     555             :         uLong uS;
     556             :         uLong64 uL64;
     557             : 
     558           4 :         us.isZip64 = 1;
     559             : 
     560           4 :         if (ZSEEK(us.z_filefunc, us.filestream, central_pos,
     561           4 :                   ZLIB_FILEFUNC_SEEK_SET) != 0)
     562           0 :             err = UNZ_ERRNO;
     563             : 
     564             :         /* the signature, already checked */
     565           4 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     566           0 :             err = UNZ_ERRNO;
     567             : 
     568             :         /* size of zip64 end of central directory record */
     569           4 :         if (unzlocal_getLong64(&us.z_filefunc, us.filestream, &uL64) != UNZ_OK)
     570           0 :             err = UNZ_ERRNO;
     571             : 
     572             :         /* version made by */
     573           4 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream, &uS) != UNZ_OK)
     574           0 :             err = UNZ_ERRNO;
     575             : 
     576             :         /* version needed to extract */
     577           4 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream, &uS) != UNZ_OK)
     578           0 :             err = UNZ_ERRNO;
     579             : 
     580             :         /* number of this disk */
     581           4 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream, &number_disk) !=
     582             :             UNZ_OK)
     583           0 :             err = UNZ_ERRNO;
     584             : 
     585             :         /* number of the disk with the start of the central directory */
     586           4 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream,
     587           4 :                              &number_disk_with_CD) != UNZ_OK)
     588           0 :             err = UNZ_ERRNO;
     589             : 
     590             :         /* total number of entries in the central directory on this disk */
     591           4 :         if (unzlocal_getLong64(&us.z_filefunc, us.filestream,
     592           4 :                                &us.gi.number_entry) != UNZ_OK)
     593           0 :             err = UNZ_ERRNO;
     594             : 
     595             :         /* total number of entries in the central directory */
     596           4 :         if (unzlocal_getLong64(&us.z_filefunc, us.filestream,
     597           4 :                                &number_entry_CD) != UNZ_OK)
     598           0 :             err = UNZ_ERRNO;
     599             : 
     600           4 :         if ((number_entry_CD != us.gi.number_entry) ||
     601           4 :             (number_disk_with_CD != 0) || (number_disk != 0))
     602           0 :             err = UNZ_BADZIPFILE;
     603             : 
     604             :         /* size of the central directory */
     605           4 :         if (unzlocal_getLong64(&us.z_filefunc, us.filestream,
     606           4 :                                &us.size_central_dir) != UNZ_OK)
     607           0 :             err = UNZ_ERRNO;
     608             : 
     609             :         /* offset of start of central directory with respect to the
     610             :           starting disk number */
     611           4 :         if (unzlocal_getLong64(&us.z_filefunc, us.filestream,
     612           4 :                                &us.offset_central_dir) != UNZ_OK)
     613           0 :             err = UNZ_ERRNO;
     614             : 
     615           4 :         us.gi.size_comment = 0;
     616             :     }
     617             :     else
     618             :     {
     619        5290 :         central_pos = unzlocal_SearchCentralDir(&us.z_filefunc, us.filestream);
     620        5290 :         if (central_pos == 0)
     621           4 :             err = UNZ_ERRNO;
     622             : 
     623        5290 :         us.isZip64 = 0;
     624             : 
     625        5290 :         if (ZSEEK(us.z_filefunc, us.filestream, central_pos,
     626        5290 :                   ZLIB_FILEFUNC_SEEK_SET) != 0)
     627           0 :             err = UNZ_ERRNO;
     628             : 
     629             :         /* the signature, already checked */
     630        5290 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     631           0 :             err = UNZ_ERRNO;
     632             : 
     633             :         /* number of this disk */
     634        5290 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk) !=
     635             :             UNZ_OK)
     636           0 :             err = UNZ_ERRNO;
     637             : 
     638             :         /* number of the disk with the start of the central directory */
     639        5290 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream,
     640        5290 :                               &number_disk_with_CD) != UNZ_OK)
     641           0 :             err = UNZ_ERRNO;
     642             : 
     643             :         /* total number of entries in the central dir on this disk */
     644        5290 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     645           0 :             err = UNZ_ERRNO;
     646        5290 :         us.gi.number_entry = uL;
     647             : 
     648             :         /* total number of entries in the central dir */
     649        5290 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     650           0 :             err = UNZ_ERRNO;
     651        5290 :         number_entry_CD = uL;
     652             : 
     653        5290 :         if ((number_entry_CD != us.gi.number_entry) ||
     654        5290 :             (number_disk_with_CD != 0) || (number_disk != 0))
     655           0 :             err = UNZ_BADZIPFILE;
     656             : 
     657             :         /* size of the central directory */
     658        5290 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     659           0 :             err = UNZ_ERRNO;
     660        5290 :         us.size_central_dir = uL;
     661             : 
     662             :         /* offset of start of central directory with respect to the
     663             :             starting disk number */
     664        5290 :         if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
     665           0 :             err = UNZ_ERRNO;
     666        5290 :         us.offset_central_dir = uL;
     667             : 
     668             :         /* zipfile comment length */
     669        5290 :         if (unzlocal_getShort(&us.z_filefunc, us.filestream,
     670        5290 :                               &us.gi.size_comment) != UNZ_OK)
     671           0 :             err = UNZ_ERRNO;
     672             :     }
     673             : 
     674        5294 :     if ((central_pos < us.offset_central_dir + us.size_central_dir) &&
     675             :         (err == UNZ_OK))
     676           0 :         err = UNZ_BADZIPFILE;
     677             : 
     678        5294 :     if (err != UNZ_OK)
     679             :     {
     680           4 :         ZCLOSE(us.z_filefunc, us.filestream);
     681           4 :         return nullptr;
     682             :     }
     683             : 
     684        5290 :     us.byte_before_the_zipfile =
     685        5290 :         central_pos - (us.offset_central_dir + us.size_central_dir);
     686        5290 :     us.central_pos = central_pos;
     687        5290 :     us.pfile_in_zip_read = nullptr;
     688        5290 :     us.encrypted = 0;
     689        5290 :     us.num_file = 0;
     690        5290 :     us.pos_in_central_dir = 0;
     691        5290 :     us.current_file_ok = 0;
     692             : 
     693        5290 :     s = static_cast<unz_s *>(ALLOC(sizeof(unz_s)));
     694        5290 :     if (!s)
     695             :     {
     696           0 :         ZCLOSE(us.z_filefunc, us.filestream);
     697           0 :         return nullptr;
     698             :     }
     699        5290 :     *s = us;
     700        5290 :     cpl_unzGoToFirstFile(reinterpret_cast<unzFile>(s));
     701        5290 :     return reinterpret_cast<unzFile>(s);
     702             : }
     703             : 
     704        5294 : extern unzFile ZEXPORT cpl_unzOpen(const char *path)
     705             : {
     706        5294 :     return cpl_unzOpen2(path, nullptr);
     707             : }
     708             : 
     709             : /*
     710             :   Close a ZipFile opened with unzipOpen.
     711             :   If there is files inside the .Zip opened with unzipOpenCurrentFile (see
     712             :   later), these files MUST be closed with unzipCloseCurrentFile before call
     713             :   unzipClose. return UNZ_OK if there is no problem. */
     714        5290 : extern int ZEXPORT cpl_unzClose(unzFile file)
     715             : {
     716             :     unz_s *s;
     717        5290 :     if (file == nullptr)
     718           0 :         return UNZ_PARAMERROR;
     719        5290 :     s = reinterpret_cast<unz_s *>(file);
     720             : 
     721        5290 :     if (s->pfile_in_zip_read != nullptr)
     722           0 :         cpl_unzCloseCurrentFile(file);
     723             : 
     724        5290 :     ZCLOSE(s->z_filefunc, s->filestream);
     725        5290 :     TRYFREE(s);
     726        5290 :     return UNZ_OK;
     727             : }
     728             : 
     729             : /*
     730             :   Write info about the ZipFile in the *pglobal_info structure.
     731             :   No preparation of the structure is needed
     732             :   return UNZ_OK if there is no problem. */
     733           0 : extern int ZEXPORT cpl_unzGetGlobalInfo(unzFile file,
     734             :                                         unz_global_info *pglobal_info)
     735             : {
     736             :     unz_s *s;
     737           0 :     if (file == nullptr)
     738           0 :         return UNZ_PARAMERROR;
     739           0 :     s = reinterpret_cast<unz_s *>(file);
     740           0 :     *pglobal_info = s->gi;
     741           0 :     return UNZ_OK;
     742             : }
     743             : 
     744             : /*
     745             :    Translate date/time from Dos format to tm_unz (readable more easily).
     746             : */
     747       41834 : static void unzlocal_DosDateToTmuDate(uLong64 ulDosDate, tm_unz *ptm)
     748             : {
     749             :     uLong64 uDate;
     750       41834 :     uDate = static_cast<uLong64>(ulDosDate >> 16);
     751       41834 :     ptm->tm_mday = static_cast<uInt>(uDate & 0x1f);
     752       41834 :     ptm->tm_mon = static_cast<uInt>(((uDate)&0x1E0) / 0x20);
     753       41834 :     if (ptm->tm_mon)
     754       41829 :         ptm->tm_mon--;
     755       41834 :     ptm->tm_year = static_cast<uInt>(((uDate & 0x0FE00) / 0x0200) + 1980);
     756             : 
     757       41834 :     ptm->tm_hour = static_cast<uInt>((ulDosDate & 0xF800) / 0x800);
     758       41834 :     ptm->tm_min = static_cast<uInt>((ulDosDate & 0x7E0) / 0x20);
     759       41834 :     ptm->tm_sec = static_cast<uInt>(2 * (ulDosDate & 0x1f));
     760       41834 : }
     761             : 
     762             : /*
     763             :   Get Info about the current file in the zipfile, with internal only info
     764             : */
     765       41834 : static int unzlocal_GetCurrentFileInfoInternal(
     766             :     unzFile file, unz_file_info *pfile_info,
     767             :     unz_file_info_internal *pfile_info_internal, char *szFileName,
     768             :     uLong fileNameBufferSize, void * /* extraField */,
     769             :     uLong /* extraFieldBufferSize */, char * /* szComment */,
     770             :     uLong /* commentBufferSize */)
     771             : {
     772             :     unz_s *s;
     773             :     unz_file_info file_info;
     774             :     unz_file_info_internal file_info_internal;
     775       41834 :     int err = UNZ_OK;
     776             :     uLong uMagic;
     777       41834 :     long lSeek = 0;
     778             :     uLong uL;
     779       41834 :     bool bHasUTF8Filename = false;
     780             : 
     781       41834 :     if (file == nullptr)
     782           0 :         return UNZ_PARAMERROR;
     783       41834 :     s = reinterpret_cast<unz_s *>(file);
     784       41834 :     if (ZSEEK(s->z_filefunc, s->filestream,
     785             :               s->pos_in_central_dir + s->byte_before_the_zipfile,
     786       41834 :               ZLIB_FILEFUNC_SEEK_SET) != 0)
     787           0 :         err = UNZ_ERRNO;
     788             : 
     789             :     /* we check the magic */
     790       41834 :     if (err == UNZ_OK)
     791             :     {
     792       41834 :         if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
     793           0 :             err = UNZ_ERRNO;
     794       41834 :         else if (uMagic != 0x02014b50)
     795           0 :             err = UNZ_BADZIPFILE;
     796             :     }
     797             : 
     798       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) !=
     799             :         UNZ_OK)
     800           0 :         err = UNZ_ERRNO;
     801             : 
     802       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     803       41834 :                           &file_info.version_needed) != UNZ_OK)
     804           0 :         err = UNZ_ERRNO;
     805             : 
     806       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) !=
     807             :         UNZ_OK)
     808           0 :         err = UNZ_ERRNO;
     809             : 
     810       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     811       41834 :                           &file_info.compression_method) != UNZ_OK)
     812           0 :         err = UNZ_ERRNO;
     813             : 
     814       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) !=
     815             :         UNZ_OK)
     816           0 :         err = UNZ_ERRNO;
     817             : 
     818       41834 :     unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date);
     819             : 
     820       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) !=
     821             :         UNZ_OK)
     822           0 :         err = UNZ_ERRNO;
     823             : 
     824       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
     825           0 :         err = UNZ_ERRNO;
     826       41834 :     file_info.compressed_size = uL;
     827             : 
     828       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
     829           0 :         err = UNZ_ERRNO;
     830       41834 :     file_info.uncompressed_size = uL;
     831             : 
     832       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     833       41834 :                           &file_info.size_filename) != UNZ_OK)
     834           0 :         err = UNZ_ERRNO;
     835             : 
     836       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     837       41834 :                           &file_info.size_file_extra) != UNZ_OK)
     838           0 :         err = UNZ_ERRNO;
     839             : 
     840       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     841       41834 :                           &file_info.size_file_comment) != UNZ_OK)
     842           0 :         err = UNZ_ERRNO;
     843             : 
     844       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     845       41834 :                           &file_info.disk_num_start) != UNZ_OK)
     846           0 :         err = UNZ_ERRNO;
     847             : 
     848       41834 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream,
     849       41834 :                           &file_info.internal_fa) != UNZ_OK)
     850           0 :         err = UNZ_ERRNO;
     851             : 
     852       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream,
     853       41834 :                          &file_info.external_fa) != UNZ_OK)
     854           0 :         err = UNZ_ERRNO;
     855             : 
     856       41834 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
     857           0 :         err = UNZ_ERRNO;
     858       41834 :     file_info_internal.offset_curfile = uL;
     859             : 
     860       41834 :     lSeek += file_info.size_filename;
     861       41834 :     if ((err == UNZ_OK) && (szFileName != nullptr))
     862             :     {
     863       16172 :         uLong uSizeRead = 0;
     864       16172 :         if (file_info.size_filename < fileNameBufferSize)
     865             :         {
     866       16172 :             *(szFileName + file_info.size_filename) = '\0';
     867       16172 :             uSizeRead = file_info.size_filename;
     868             :         }
     869             :         else
     870           0 :             uSizeRead = fileNameBufferSize;
     871             : 
     872       16172 :         if ((file_info.size_filename > 0) && (fileNameBufferSize > 0))
     873             :         {
     874       16172 :             if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) !=
     875             :                 uSizeRead)
     876           0 :                 err = UNZ_ERRNO;
     877             :         }
     878       16172 :         lSeek -= uSizeRead;
     879             :     }
     880             : 
     881             : #if 0
     882             :     if ((err==UNZ_OK) && (extraField != nullptr))
     883             :     {
     884             :         uLong64 uSizeRead = 0;
     885             :         if (file_info.size_file_extra<extraFieldBufferSize)
     886             :             uSizeRead = file_info.size_file_extra;
     887             :         else
     888             :             uSizeRead = extraFieldBufferSize;
     889             : 
     890             :         if (lSeek!=0)
     891             :         {
     892             :             if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
     893             :                 lSeek=0;
     894             :             else
     895             :                 err=UNZ_ERRNO;
     896             :         }
     897             : 
     898             :         if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
     899             :             if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
     900             :                 err=UNZ_ERRNO;
     901             :         lSeek += file_info.size_file_extra - uSizeRead;
     902             :     }
     903             :     else
     904             :         lSeek+=file_info.size_file_extra;
     905             : #endif
     906       41834 :     if ((err == UNZ_OK) && (file_info.size_file_extra != 0))
     907             :     {
     908       32690 :         if (lSeek != 0)
     909             :         {
     910       20161 :             if (ZSEEK(s->z_filefunc, s->filestream, lSeek,
     911       20161 :                       ZLIB_FILEFUNC_SEEK_CUR) == 0)
     912             :             {
     913       20161 :                 lSeek = 0;
     914       20161 :                 CPL_IGNORE_RET_VAL(lSeek);
     915             :             }
     916             :             else
     917           0 :                 err = UNZ_ERRNO;
     918             :         }
     919             : 
     920       32690 :         uLong acc = 0;
     921       32690 :         file_info.file_extra_abs_offset = ZTELL(s->z_filefunc, s->filestream);
     922       97479 :         while (acc < file_info.size_file_extra)
     923             :         {
     924             :             uLong headerId;
     925       64789 :             if (unzlocal_getShort(&s->z_filefunc, s->filestream, &headerId) !=
     926             :                 UNZ_OK)
     927           0 :                 err = UNZ_ERRNO;
     928             : 
     929             :             uLong dataSize;
     930       64789 :             if (unzlocal_getShort(&s->z_filefunc, s->filestream, &dataSize) !=
     931             :                 UNZ_OK)
     932           0 :                 err = UNZ_ERRNO;
     933             : 
     934             :             /* ZIP64 extra fields */
     935       64789 :             if (headerId == 0x0001)
     936             :             {
     937             :                 uLong64 u64;
     938          36 :                 if (file_info.uncompressed_size == 0xFFFFFFFF)
     939             :                 {
     940          31 :                     if (unzlocal_getLong64(&s->z_filefunc, s->filestream,
     941          31 :                                            &u64) != UNZ_OK)
     942           0 :                         err = UNZ_ERRNO;
     943          31 :                     file_info.uncompressed_size = u64;
     944             :                 }
     945             : 
     946          36 :                 if (file_info.compressed_size == 0xFFFFFFFF)
     947             :                 {
     948          14 :                     if (unzlocal_getLong64(&s->z_filefunc, s->filestream,
     949          14 :                                            &u64) != UNZ_OK)
     950           0 :                         err = UNZ_ERRNO;
     951          14 :                     file_info.compressed_size = u64;
     952             :                 }
     953             : 
     954             :                 /* Relative Header offset */
     955          36 :                 if (file_info_internal.offset_curfile == 0xFFFFFFFF)
     956             :                 {
     957           5 :                     if (unzlocal_getLong64(&s->z_filefunc, s->filestream,
     958           5 :                                            &u64) != UNZ_OK)
     959           0 :                         err = UNZ_ERRNO;
     960           5 :                     file_info_internal.offset_curfile = u64;
     961             :                 }
     962             : 
     963             :                 /* Disk Start Number */
     964          36 :                 if (file_info.disk_num_start == 0xFFFF)
     965             :                 {
     966             :                     uLong uLstart;
     967           0 :                     if (unzlocal_getLong(&s->z_filefunc, s->filestream,
     968           0 :                                          &uLstart) != UNZ_OK)
     969           0 :                         err = UNZ_ERRNO;
     970           0 :                     file_info.disk_num_start = uLstart;
     971             :                 }
     972             :             }
     973             :             /* Info-ZIP Unicode Path Extra Field (0x7075) */
     974       64753 :             else if (headerId == 0x7075 && dataSize > 5 &&
     975          17 :                      file_info.size_filename <= fileNameBufferSize &&
     976             :                      szFileName != nullptr)
     977             :             {
     978           7 :                 int version = 0;
     979           7 :                 if (unzlocal_getByte(&s->z_filefunc, s->filestream, &version) !=
     980             :                     UNZ_OK)
     981           0 :                     err = UNZ_ERRNO;
     982           7 :                 if (version != 1)
     983             :                 {
     984             :                     /* If version != 1, ignore that extra field */
     985           0 :                     if (ZSEEK(s->z_filefunc, s->filestream, dataSize - 1,
     986           0 :                               ZLIB_FILEFUNC_SEEK_CUR) != 0)
     987           0 :                         err = UNZ_ERRNO;
     988             :                 }
     989             :                 else
     990             :                 {
     991             :                     uLong nameCRC32;
     992           7 :                     if (unzlocal_getLong(&s->z_filefunc, s->filestream,
     993           7 :                                          &nameCRC32) != UNZ_OK)
     994           0 :                         err = UNZ_ERRNO;
     995             : 
     996             :                     /* Check expected CRC for filename */
     997           7 :                     if (nameCRC32 ==
     998           7 :                         crc32(0, reinterpret_cast<const Bytef *>(szFileName),
     999           7 :                               static_cast<uInt>(file_info.size_filename)))
    1000             :                     {
    1001           7 :                         const uLong utf8Size = dataSize - 1 - 4;
    1002           7 :                         uLong uSizeRead = 0;
    1003             : 
    1004           7 :                         bHasUTF8Filename = true;
    1005             : 
    1006           7 :                         if (utf8Size < fileNameBufferSize)
    1007             :                         {
    1008           7 :                             *(szFileName + utf8Size) = '\0';
    1009           7 :                             uSizeRead = utf8Size;
    1010             :                         }
    1011             :                         else
    1012           0 :                             uSizeRead = fileNameBufferSize;
    1013             : 
    1014           7 :                         if (ZREAD(s->z_filefunc, s->filestream, szFileName,
    1015           7 :                                   uSizeRead) != uSizeRead)
    1016           0 :                             err = UNZ_ERRNO;
    1017           7 :                         else if (utf8Size > fileNameBufferSize)
    1018             :                         {
    1019           0 :                             if (ZSEEK(s->z_filefunc, s->filestream,
    1020             :                                       utf8Size - fileNameBufferSize,
    1021           0 :                                       ZLIB_FILEFUNC_SEEK_CUR) != 0)
    1022           0 :                                 err = UNZ_ERRNO;
    1023             :                         }
    1024             :                     }
    1025             :                     else
    1026             :                     {
    1027             :                         /* ignore unicode name if CRC mismatch */
    1028           0 :                         if (ZSEEK(s->z_filefunc, s->filestream,
    1029             :                                   dataSize - 1 - 4,
    1030           0 :                                   ZLIB_FILEFUNC_SEEK_CUR) != 0)
    1031           0 :                             err = UNZ_ERRNO;
    1032             :                     }
    1033           7 :                 }
    1034             :             }
    1035             :             else
    1036             :             {
    1037       64746 :                 if (ZSEEK(s->z_filefunc, s->filestream, dataSize,
    1038       64746 :                           ZLIB_FILEFUNC_SEEK_CUR) != 0)
    1039           0 :                     err = UNZ_ERRNO;
    1040             :             }
    1041             : 
    1042       64789 :             acc += 2 + 2 + dataSize;
    1043             :         }
    1044             :     }
    1045             : 
    1046       41834 :     if (!bHasUTF8Filename && szFileName != nullptr &&
    1047       16165 :         (file_info.flag & (1 << 11)) == 0 &&
    1048       15572 :         file_info.size_filename < fileNameBufferSize)
    1049             :     {
    1050       15572 :         const char *pszSrcEncoding = CPLGetConfigOption("CPL_ZIP_ENCODING",
    1051             : #if defined(_WIN32) && !defined(HAVE_ICONV)
    1052             :                                                         "CP_OEMCP"
    1053             : #else
    1054             :                                                         "CP437"
    1055             : #endif
    1056             :         );
    1057       15572 :         char *pszRecoded = CPLRecode(szFileName, pszSrcEncoding, CPL_ENC_UTF8);
    1058       15572 :         if (pszRecoded != nullptr && strlen(pszRecoded) < fileNameBufferSize)
    1059             :         {
    1060       15572 :             strcpy(szFileName, pszRecoded);
    1061             :         }
    1062       15572 :         CPLFree(pszRecoded);
    1063             :     }
    1064             : 
    1065             : #if 0
    1066             :     if ((err==UNZ_OK) && (szComment != nullptr))
    1067             :     {
    1068             :         uLong64 uSizeRead = 0;
    1069             :         if (file_info.size_file_comment<commentBufferSize)
    1070             :         {
    1071             :             *(szComment+file_info.size_file_comment)='\0';
    1072             :             uSizeRead = file_info.size_file_comment;
    1073             :         }
    1074             :         else
    1075             :             uSizeRead = commentBufferSize;
    1076             : 
    1077             :         if (lSeek!=0)
    1078             :         {
    1079             :             if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
    1080             :                 lSeek=0;
    1081             :             else
    1082             :                 err=UNZ_ERRNO;
    1083             :         }
    1084             : 
    1085             :         if ((file_info.size_file_comment>0) && (commentBufferSize>0))
    1086             :             if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
    1087             :                 err=UNZ_ERRNO;
    1088             :         lSeek+=file_info.size_file_comment - uSizeRead;
    1089             :     }
    1090             :     else
    1091             :         lSeek+=file_info.size_file_comment;
    1092             : #endif
    1093             : 
    1094       41834 :     if ((err == UNZ_OK) && (pfile_info != nullptr))
    1095       41834 :         *pfile_info = file_info;
    1096             : 
    1097       41834 :     if ((err == UNZ_OK) && (pfile_info_internal != nullptr))
    1098       21462 :         *pfile_info_internal = file_info_internal;
    1099             : 
    1100       41834 :     return err;
    1101             : }
    1102             : 
    1103             : /*
    1104             :   Write info about the ZipFile in the *pglobal_info structure.
    1105             :   No preparation of the structure is needed
    1106             :   return UNZ_OK if there is no problem.
    1107             : */
    1108       20372 : extern int ZEXPORT cpl_unzGetCurrentFileInfo(
    1109             :     unzFile file, unz_file_info *pfile_info, char *szFileName,
    1110             :     uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize,
    1111             :     char *szComment, uLong commentBufferSize)
    1112             : {
    1113       20372 :     return unzlocal_GetCurrentFileInfoInternal(
    1114             :         file, pfile_info, nullptr, szFileName, fileNameBufferSize, extraField,
    1115       20372 :         extraFieldBufferSize, szComment, commentBufferSize);
    1116             : }
    1117             : 
    1118             : /*
    1119             :   Set the current file of the zipfile to the first file.
    1120             :   return UNZ_OK if there is no problem
    1121             : */
    1122       11473 : extern int ZEXPORT cpl_unzGoToFirstFile(unzFile file)
    1123             : {
    1124       11473 :     int err = UNZ_OK;
    1125             :     unz_s *s;
    1126       11473 :     if (file == nullptr)
    1127           0 :         return UNZ_PARAMERROR;
    1128       11473 :     s = reinterpret_cast<unz_s *>(file);
    1129       11473 :     s->pos_in_central_dir = s->offset_central_dir;
    1130       11473 :     s->num_file = 0;
    1131       11473 :     err = unzlocal_GetCurrentFileInfoInternal(
    1132             :         file, &s->cur_file_info, &s->cur_file_info_internal, nullptr, 0,
    1133             :         nullptr, 0, nullptr, 0);
    1134       11473 :     s->current_file_ok = (err == UNZ_OK);
    1135       11473 :     return err;
    1136             : }
    1137             : 
    1138             : /*
    1139             :   Set the current file of the zipfile to the next file.
    1140             :   return UNZ_OK if there is no problem
    1141             :   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
    1142             : */
    1143        6446 : extern int ZEXPORT cpl_unzGoToNextFile(unzFile file)
    1144             : {
    1145             :     unz_s *s;
    1146             : 
    1147        6446 :     if (file == nullptr)
    1148           0 :         return UNZ_PARAMERROR;
    1149        6446 :     s = reinterpret_cast<unz_s *>(file);
    1150        6446 :     if (!s->current_file_ok)
    1151           0 :         return UNZ_END_OF_LIST_OF_FILE;
    1152        6446 :     if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
    1153        6446 :         if (s->num_file + 1 == s->gi.number_entry)
    1154         539 :             return UNZ_END_OF_LIST_OF_FILE;
    1155             : 
    1156        5907 :     s->pos_in_central_dir +=
    1157        5907 :         SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
    1158        5907 :         s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
    1159        5907 :     s->num_file++;
    1160        5907 :     int err = unzlocal_GetCurrentFileInfoInternal(
    1161             :         file, &s->cur_file_info, &s->cur_file_info_internal, nullptr, 0,
    1162             :         nullptr, 0, nullptr, 0);
    1163        5907 :     s->current_file_ok = (err == UNZ_OK);
    1164        5907 :     return err;
    1165             : }
    1166             : 
    1167             : /*
    1168             :   Try locate the file szFileName in the zipfile.
    1169             :   For the iCaseSensitivity signification, see unzipStringFileNameCompare
    1170             : 
    1171             :   return value :
    1172             :   UNZ_OK if the file is found. It becomes the current file.
    1173             :   UNZ_END_OF_LIST_OF_FILE if the file is not found
    1174             : */
    1175           0 : extern int ZEXPORT cpl_unzLocateFile(unzFile file, const char *szFileName,
    1176             :                                      int iCaseSensitivity)
    1177             : {
    1178             :     unz_s *s;
    1179             : 
    1180             :     /* We remember the 'current' position in the file so that we can jump
    1181             :      * back there if we fail.
    1182             :      */
    1183             :     unz_file_info cur_file_infoSaved;
    1184             :     unz_file_info_internal cur_file_info_internalSaved;
    1185             :     uLong64 num_fileSaved;
    1186             :     uLong64 pos_in_central_dirSaved;
    1187             : 
    1188           0 :     if (file == nullptr)
    1189           0 :         return UNZ_PARAMERROR;
    1190             : 
    1191           0 :     if (strlen(szFileName) >= UNZ_MAXFILENAMEINZIP)
    1192           0 :         return UNZ_PARAMERROR;
    1193             : 
    1194           0 :     s = reinterpret_cast<unz_s *>(file);
    1195           0 :     if (!s->current_file_ok)
    1196           0 :         return UNZ_END_OF_LIST_OF_FILE;
    1197             : 
    1198             :     /* Save the current state */
    1199           0 :     num_fileSaved = s->num_file;
    1200           0 :     pos_in_central_dirSaved = s->pos_in_central_dir;
    1201           0 :     cur_file_infoSaved = s->cur_file_info;
    1202           0 :     cur_file_info_internalSaved = s->cur_file_info_internal;
    1203             : 
    1204           0 :     int err = cpl_unzGoToFirstFile(file);
    1205             : 
    1206           0 :     while (err == UNZ_OK)
    1207             :     {
    1208             :         char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
    1209           0 :         err = cpl_unzGetCurrentFileInfo(file, nullptr, szCurrentFileName,
    1210             :                                         sizeof(szCurrentFileName) - 1, nullptr,
    1211             :                                         0, nullptr, 0);
    1212           0 :         if (err == UNZ_OK)
    1213             :         {
    1214           0 :             if (cpl_unzStringFileNameCompare(szCurrentFileName, szFileName,
    1215           0 :                                              iCaseSensitivity) == 0)
    1216           0 :                 return UNZ_OK;
    1217           0 :             err = cpl_unzGoToNextFile(file);
    1218             :         }
    1219             :     }
    1220             : 
    1221             :     /* We failed, so restore the state of the 'current file' to where we
    1222             :      * were.
    1223             :      */
    1224             :     // cppcheck-suppress redundantAssignment
    1225           0 :     s->num_file = num_fileSaved;
    1226           0 :     s->pos_in_central_dir = pos_in_central_dirSaved;
    1227           0 :     s->cur_file_info = cur_file_infoSaved;
    1228           0 :     s->cur_file_info_internal = cur_file_info_internalSaved;
    1229           0 :     return err;
    1230             : }
    1231             : 
    1232             : /*
    1233             : ///////////////////////////////////////////
    1234             : // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
    1235             : // I need random access
    1236             : //
    1237             : // Further optimization could be realized by adding an ability
    1238             : // to cache the directory in memory. The goal being a single
    1239             : // comprehensive file read to put the file I need in a memory.
    1240             : */
    1241             : 
    1242             : /*
    1243             : typedef struct unz_file_pos_s
    1244             : {
    1245             :     uLong64 pos_in_zip_directory;   // offset in file
    1246             :     uLong64 num_of_file;            // # of file
    1247             : } unz_file_pos;
    1248             : */
    1249             : 
    1250       15363 : extern int ZEXPORT cpl_unzGetFilePos(unzFile file, unz_file_pos *file_pos)
    1251             : {
    1252             :     unz_s *s;
    1253             : 
    1254       15363 :     if (file == nullptr || file_pos == nullptr)
    1255           0 :         return UNZ_PARAMERROR;
    1256       15363 :     s = reinterpret_cast<unz_s *>(file);
    1257       15363 :     if (!s->current_file_ok)
    1258           0 :         return UNZ_END_OF_LIST_OF_FILE;
    1259             : 
    1260       15363 :     file_pos->pos_in_zip_directory = s->pos_in_central_dir;
    1261       15363 :     file_pos->num_of_file = s->num_file;
    1262             : 
    1263       15363 :     return UNZ_OK;
    1264             : }
    1265             : 
    1266        4082 : extern int ZEXPORT cpl_unzGoToFilePos(unzFile file, unz_file_pos *file_pos)
    1267             : {
    1268             :     unz_s *s;
    1269             : 
    1270        4082 :     if (file == nullptr || file_pos == nullptr)
    1271           0 :         return UNZ_PARAMERROR;
    1272        4082 :     s = reinterpret_cast<unz_s *>(file);
    1273             : 
    1274             :     /* jump to the right spot */
    1275        4082 :     s->pos_in_central_dir = file_pos->pos_in_zip_directory;
    1276        4082 :     s->num_file = file_pos->num_of_file;
    1277             : 
    1278             :     /* set the current file */
    1279        4082 :     int err = unzlocal_GetCurrentFileInfoInternal(
    1280             :         file, &s->cur_file_info, &s->cur_file_info_internal, nullptr, 0,
    1281             :         nullptr, 0, nullptr, 0);
    1282             :     /* return results */
    1283        4082 :     s->current_file_ok = (err == UNZ_OK);
    1284        4082 :     return err;
    1285             : }
    1286             : 
    1287             : /*
    1288             : // Unzip Helper Functions - should be here?
    1289             : ///////////////////////////////////////////
    1290             : */
    1291             : 
    1292             : /*
    1293             :   Read the local header of the current zipfile
    1294             :   Check the coherency of the local header and info in the end of central
    1295             :         directory about this file
    1296             :   store in *piSizeVar the size of extra info in local header
    1297             :         (filename and size of extra field data)
    1298             : */
    1299             : static int
    1300        4200 : unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, uInt *piSizeVar,
    1301             :                                          uLong64 *poffset_local_extrafield,
    1302             :                                          uInt *psize_local_extrafield)
    1303             : {
    1304             :     uLong uMagic, uData, uFlags;
    1305             :     uLong size_filename;
    1306             :     uLong size_extra_field;
    1307        4200 :     int err = UNZ_OK;
    1308             : 
    1309        4200 :     *piSizeVar = 0;
    1310        4200 :     *poffset_local_extrafield = 0;
    1311        4200 :     *psize_local_extrafield = 0;
    1312             : 
    1313        4200 :     if (ZSEEK(s->z_filefunc, s->filestream,
    1314             :               s->cur_file_info_internal.offset_curfile +
    1315             :                   s->byte_before_the_zipfile,
    1316        4200 :               ZLIB_FILEFUNC_SEEK_SET) != 0)
    1317           0 :         return UNZ_ERRNO;
    1318             : 
    1319             :     // if (err == UNZ_OK)
    1320             :     {
    1321        4200 :         if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
    1322           0 :             err = UNZ_ERRNO;
    1323        4200 :         else if (uMagic != 0x04034b50)
    1324           0 :             err = UNZ_BADZIPFILE;
    1325             :     }
    1326             : 
    1327        4200 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
    1328           0 :         err = UNZ_ERRNO;
    1329             :     /*
    1330             :         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
    1331             :             err=UNZ_BADZIPFILE;
    1332             :     */
    1333        4200 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK)
    1334           0 :         err = UNZ_ERRNO;
    1335             : 
    1336        4200 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
    1337           0 :         err = UNZ_ERRNO;
    1338        4200 :     else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method))
    1339           0 :         err = UNZ_BADZIPFILE;
    1340             : 
    1341        4200 :     if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) &&
    1342        4129 :         (s->cur_file_info.compression_method != Z_DEFLATED))
    1343             :     {
    1344             : #ifdef ENABLE_DEFLATE64
    1345           1 :         if (s->cur_file_info.compression_method == 9)
    1346             :         {
    1347             :             // ok
    1348             :         }
    1349             :         else
    1350             : #endif
    1351             :         {
    1352           0 :             CPLError(CE_Failure, CPLE_NotSupported,
    1353             :                      "A file in the ZIP archive uses a unsupported "
    1354             :                      "compression method (%lu)",
    1355             :                      s->cur_file_info.compression_method);
    1356           0 :             err = UNZ_BADZIPFILE;
    1357             :         }
    1358             :     }
    1359             : 
    1360        4200 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1361             :         UNZ_OK) /* date/time */
    1362           0 :         err = UNZ_ERRNO;
    1363             : 
    1364        4200 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1365             :         UNZ_OK) /* crc */
    1366           0 :         err = UNZ_ERRNO;
    1367        4200 :     else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) &&
    1368         163 :              ((uFlags & 8) == 0))
    1369           0 :         err = UNZ_BADZIPFILE;
    1370             : 
    1371        4200 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1372             :         UNZ_OK) /* size compr */
    1373           0 :         err = UNZ_ERRNO;
    1374        4200 :     else if (uData != 0xFFFFFFFF && (err == UNZ_OK) &&
    1375        4197 :              (uData != s->cur_file_info.compressed_size) && ((uFlags & 8) == 0))
    1376           0 :         err = UNZ_BADZIPFILE;
    1377             : 
    1378        4200 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1379             :         UNZ_OK) /* size uncompr */
    1380           0 :         err = UNZ_ERRNO;
    1381        4200 :     else if (uData != 0xFFFFFFFF && (err == UNZ_OK) &&
    1382        4197 :              (uData != s->cur_file_info.uncompressed_size) &&
    1383         163 :              ((uFlags & 8) == 0))
    1384           0 :         err = UNZ_BADZIPFILE;
    1385             : 
    1386        4200 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) !=
    1387             :         UNZ_OK)
    1388           0 :         err = UNZ_ERRNO;
    1389        4200 :     else if ((err == UNZ_OK) &&
    1390        4200 :              (size_filename != s->cur_file_info.size_filename))
    1391           0 :         err = UNZ_BADZIPFILE;
    1392             : 
    1393        4200 :     *piSizeVar += static_cast<uInt>(size_filename);
    1394             : 
    1395        4200 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) !=
    1396             :         UNZ_OK)
    1397           0 :         err = UNZ_ERRNO;
    1398        4200 :     *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile +
    1399        4200 :                                 SIZEZIPLOCALHEADER + size_filename;
    1400        4200 :     *psize_local_extrafield = static_cast<uInt>(size_extra_field);
    1401             : 
    1402        4200 :     *piSizeVar += static_cast<uInt>(size_extra_field);
    1403             : 
    1404        4200 :     return err;
    1405             : }
    1406             : 
    1407             : /*
    1408             :   Open for reading data the current file in the zipfile.
    1409             :   If there is no error and the file is opened, the return value is UNZ_OK.
    1410             : */
    1411        4200 : extern int ZEXPORT cpl_unzOpenCurrentFile3(unzFile file, int *method,
    1412             :                                            int *level, int raw,
    1413             :                                            const char *password)
    1414             : {
    1415        4200 :     int err = UNZ_OK;
    1416             :     uInt iSizeVar;
    1417             :     unz_s *s;
    1418             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1419             :     uLong64 offset_local_extrafield; /* offset of the local extra field */
    1420             :     uInt size_local_extrafield;      /* size of the local extra field */
    1421             : #ifndef NOUNCRYPT
    1422             :     char source[12];
    1423             : #else
    1424        4200 :     if (password != nullptr)
    1425           0 :         return UNZ_PARAMERROR;
    1426             : #endif
    1427             : 
    1428        4200 :     if (file == nullptr)
    1429           0 :         return UNZ_PARAMERROR;
    1430        4200 :     s = reinterpret_cast<unz_s *>(file);
    1431        4200 :     if (!s->current_file_ok)
    1432           0 :         return UNZ_PARAMERROR;
    1433             : 
    1434        4200 :     if (s->pfile_in_zip_read != nullptr)
    1435           0 :         cpl_unzCloseCurrentFile(file);
    1436             : 
    1437        4200 :     if (unzlocal_CheckCurrentFileCoherencyHeader(
    1438        4200 :             s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) !=
    1439             :         UNZ_OK)
    1440           0 :         return UNZ_BADZIPFILE;
    1441             : 
    1442             :     pfile_in_zip_read_info = static_cast<file_in_zip_read_info_s *>(
    1443        4200 :         ALLOC(sizeof(file_in_zip_read_info_s)));
    1444        4200 :     if (pfile_in_zip_read_info == nullptr)
    1445           0 :         return UNZ_INTERNALERROR;
    1446             : 
    1447        4200 :     pfile_in_zip_read_info->read_buffer =
    1448        4200 :         static_cast<char *>(ALLOC(UNZ_BUFSIZE));
    1449        4200 :     pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
    1450        4200 :     pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
    1451        4200 :     pfile_in_zip_read_info->pos_local_extrafield = 0;
    1452        4200 :     pfile_in_zip_read_info->raw = raw;
    1453             : 
    1454        4200 :     if (pfile_in_zip_read_info->read_buffer == nullptr)
    1455             :     {
    1456           0 :         TRYFREE(pfile_in_zip_read_info);
    1457           0 :         return UNZ_INTERNALERROR;
    1458             :     }
    1459             : 
    1460        4200 :     pfile_in_zip_read_info->stream_initialised = 0;
    1461             : 
    1462        4200 :     if (method != nullptr)
    1463           0 :         *method = static_cast<int>(s->cur_file_info.compression_method);
    1464             : 
    1465        4200 :     if (level != nullptr)
    1466             :     {
    1467           0 :         *level = 6;
    1468           0 :         switch (s->cur_file_info.flag & 0x06)
    1469             :         {
    1470           0 :             case 6:
    1471           0 :                 *level = 1;
    1472           0 :                 break;
    1473           0 :             case 4:
    1474           0 :                 *level = 2;
    1475           0 :                 break;
    1476           0 :             case 2:
    1477           0 :                 *level = 9;
    1478           0 :                 break;
    1479             :         }
    1480             :     }
    1481             : 
    1482             :     /*if ((s->cur_file_info.compression_method!=0) &&
    1483             :         (s->cur_file_info.compression_method!=Z_DEFLATED))
    1484             :         err=UNZ_BADZIPFILE;*/
    1485             : 
    1486        4200 :     pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;
    1487        4200 :     pfile_in_zip_read_info->crc32 = 0;
    1488        4200 :     pfile_in_zip_read_info->compression_method =
    1489        4200 :         s->cur_file_info.compression_method;
    1490        4200 :     pfile_in_zip_read_info->filestream = s->filestream;
    1491        4200 :     pfile_in_zip_read_info->z_filefunc = s->z_filefunc;
    1492        4200 :     pfile_in_zip_read_info->byte_before_the_zipfile =
    1493        4200 :         s->byte_before_the_zipfile;
    1494             : 
    1495        4200 :     pfile_in_zip_read_info->stream.total_out = 0;
    1496             : 
    1497        4200 :     if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw))
    1498             :     {
    1499        4128 :         pfile_in_zip_read_info->stream.zalloc = nullptr;
    1500        4128 :         pfile_in_zip_read_info->stream.zfree = nullptr;
    1501        4128 :         pfile_in_zip_read_info->stream.opaque = nullptr;
    1502        4128 :         pfile_in_zip_read_info->stream.next_in = nullptr;
    1503        4128 :         pfile_in_zip_read_info->stream.avail_in = 0;
    1504             : 
    1505        4128 :         err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
    1506        4128 :         if (err == Z_OK)
    1507        4128 :             pfile_in_zip_read_info->stream_initialised = 1;
    1508             :         else
    1509             :         {
    1510           0 :             TRYFREE(pfile_in_zip_read_info->read_buffer);
    1511           0 :             TRYFREE(pfile_in_zip_read_info);
    1512           0 :             return err;
    1513             :         }
    1514             :         /* windowBits is passed < 0 to tell that there is no zlib header.
    1515             :          * Note that in this case inflate *requires* an extra "dummy" byte
    1516             :          * after the compressed stream in order to complete decompression and
    1517             :          * return Z_STREAM_END.
    1518             :          * In unzip, i don't wait absolutely Z_STREAM_END because I known the
    1519             :          * size of both compressed and uncompressed data
    1520             :          */
    1521             :     }
    1522        4200 :     pfile_in_zip_read_info->rest_read_compressed =
    1523        4200 :         s->cur_file_info.compressed_size;
    1524        4200 :     pfile_in_zip_read_info->rest_read_uncompressed =
    1525        4200 :         s->cur_file_info.uncompressed_size;
    1526             : 
    1527        4200 :     pfile_in_zip_read_info->pos_in_zipfile =
    1528        4200 :         s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
    1529        4200 :         iSizeVar;
    1530             : 
    1531        4200 :     pfile_in_zip_read_info->stream.avail_in = 0;
    1532             : 
    1533        4200 :     s->pfile_in_zip_read = pfile_in_zip_read_info;
    1534             : 
    1535             : #ifndef NOUNCRYPT
    1536             :     if (password != nullptr)
    1537             :     {
    1538             :         s->pcrc_32_tab = get_crc_table();
    1539             :         init_keys(password, s->keys, s->pcrc_32_tab);
    1540             :         if (ZSEEK(s->z_filefunc, s->filestream,
    1541             :                   s->pfile_in_zip_read->pos_in_zipfile +
    1542             :                       s->pfile_in_zip_read->byte_before_the_zipfile,
    1543             :                   SEEK_SET) != 0)
    1544             :             return UNZ_INTERNALERROR;
    1545             :         if (ZREAD(s->z_filefunc, s->filestream, source, 12) < 12)
    1546             :             return UNZ_INTERNALERROR;
    1547             : 
    1548             :         for (int i = 0; i < 12; i++)
    1549             :             zdecode(s->keys, s->pcrc_32_tab, source[i]);
    1550             : 
    1551             :         s->pfile_in_zip_read->pos_in_zipfile += 12;
    1552             :         s->encrypted = 1;
    1553             :     }
    1554             : #endif
    1555             : 
    1556        4200 :     return UNZ_OK;
    1557             : }
    1558             : 
    1559        4200 : extern int ZEXPORT cpl_unzOpenCurrentFile(unzFile file)
    1560             : {
    1561        4200 :     return cpl_unzOpenCurrentFile3(file, nullptr, nullptr, 0, nullptr);
    1562             : }
    1563             : 
    1564           0 : extern int ZEXPORT cpl_unzOpenCurrentFilePassword(unzFile file,
    1565             :                                                   const char *password)
    1566             : {
    1567           0 :     return cpl_unzOpenCurrentFile3(file, nullptr, nullptr, 0, password);
    1568             : }
    1569             : 
    1570           0 : extern int ZEXPORT cpl_unzOpenCurrentFile2(unzFile file, int *method,
    1571             :                                            int *level, int raw)
    1572             : {
    1573           0 :     return cpl_unzOpenCurrentFile3(file, method, level, raw, nullptr);
    1574             : }
    1575             : 
    1576             : /** Addition for GDAL : START */
    1577             : 
    1578        4200 : extern uLong64 ZEXPORT cpl_unzGetCurrentFileZStreamPos(unzFile file)
    1579             : {
    1580             :     unz_s *s;
    1581             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1582        4200 :     s = reinterpret_cast<unz_s *>(file);
    1583        4200 :     if (file == nullptr)
    1584           0 :         return 0;  // UNZ_PARAMERROR;
    1585        4200 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1586        4200 :     if (pfile_in_zip_read_info == nullptr)
    1587           0 :         return 0;  // UNZ_PARAMERROR;
    1588        4200 :     return pfile_in_zip_read_info->pos_in_zipfile +
    1589        4200 :            pfile_in_zip_read_info->byte_before_the_zipfile;
    1590             : }
    1591             : 
    1592        4200 : extern int cpl_unzGetLocalHeaderPos(unzFile file, uLong64 *pos_local_header)
    1593             : {
    1594             :     unz_s *s;
    1595             : 
    1596        4200 :     if (file == nullptr)
    1597           0 :         return UNZ_PARAMERROR;
    1598        4200 :     s = reinterpret_cast<unz_s *>(file);
    1599        4200 :     *pos_local_header = s->cur_file_info_internal.offset_curfile;
    1600        4200 :     return UNZ_OK;
    1601             : }
    1602             : 
    1603        4128 : extern int cpl_unzCurrentFileInfoFromLocalHeader(
    1604             :     unzFile file, uLong64 pos_local_header, unz_file_info *pfile_info,
    1605             :     char *szFileName, size_t fileNameBufferSize, uLong64 *posData)
    1606             : {
    1607        4128 :     int err = UNZ_OK;
    1608             :     uLong uMagic, uData, uFlags;
    1609             :     uLong size_filename;
    1610             :     uLong size_extra_field;
    1611             :     unz_s *s;
    1612             : 
    1613        4128 :     memset(pfile_info, 0, sizeof(*pfile_info));
    1614             : 
    1615        4128 :     if (!file)
    1616           0 :         return UNZ_PARAMERROR;
    1617        4128 :     s = reinterpret_cast<unz_s *>(file);
    1618             : 
    1619        4128 :     if (ZSEEK(s->z_filefunc, s->filestream, pos_local_header,
    1620        4128 :               ZLIB_FILEFUNC_SEEK_SET) != 0)
    1621           0 :         return UNZ_ERRNO;
    1622             : 
    1623             :     // if (err == UNZ_OK)
    1624             :     {
    1625        4128 :         if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
    1626           0 :             err = UNZ_ERRNO;
    1627        4128 :         else if (uMagic != 0x04034b50)
    1628         523 :             err = UNZ_BADZIPFILE;
    1629             :     }
    1630             : 
    1631        4128 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
    1632           0 :         err = UNZ_ERRNO;
    1633             : 
    1634        4128 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK)
    1635           0 :         err = UNZ_ERRNO;
    1636             : 
    1637        4128 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
    1638           0 :         err = UNZ_ERRNO;
    1639             :     else
    1640        4128 :         pfile_info->compression_method = uData;
    1641             : 
    1642        4128 :     if ((err == UNZ_OK) && (pfile_info->compression_method != 0) &&
    1643        3528 :         (pfile_info->compression_method != Z_DEFLATED))
    1644             :     {
    1645             : #ifdef ENABLE_DEFLATE64
    1646           0 :         if (pfile_info->compression_method == 9)
    1647             :         {
    1648             :             // ok
    1649             :         }
    1650             :         else
    1651             : #endif
    1652             :         {
    1653           0 :             CPLError(CE_Failure, CPLE_NotSupported,
    1654             :                      "A file in the ZIP archive uses a unsupported "
    1655             :                      "compression method (%lu)",
    1656             :                      pfile_info->compression_method);
    1657           0 :             err = UNZ_BADZIPFILE;
    1658             :         }
    1659             :     }
    1660             : 
    1661        4128 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1662             :         UNZ_OK) /* date/time */
    1663           0 :         err = UNZ_ERRNO;
    1664             : 
    1665        4128 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1666             :         UNZ_OK) /* crc */
    1667           0 :         err = UNZ_ERRNO;
    1668             : 
    1669        4128 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1670             :         UNZ_OK) /* size compr */
    1671           0 :         err = UNZ_ERRNO;
    1672             :     else
    1673        4128 :         pfile_info->compressed_size = uData;
    1674             : 
    1675        4128 :     if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) !=
    1676             :         UNZ_OK) /* size uncompr */
    1677           0 :         err = UNZ_ERRNO;
    1678             :     else
    1679        4128 :         pfile_info->uncompressed_size = uData;
    1680             : 
    1681        4128 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) !=
    1682             :         UNZ_OK)
    1683           0 :         err = UNZ_ERRNO;
    1684             : 
    1685        4128 :     if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) !=
    1686             :         UNZ_OK)
    1687           0 :         err = UNZ_ERRNO;
    1688             : 
    1689        4128 :     if (posData)
    1690             :     {
    1691        4128 :         *posData = pos_local_header + SIZEZIPLOCALHEADER + size_filename +
    1692             :                    size_extra_field;
    1693             :     }
    1694             : 
    1695        4128 :     if (size_filename <= fileNameBufferSize && szFileName)
    1696             :     {
    1697        3980 :         if (ZREAD(s->z_filefunc, s->filestream, szFileName, size_filename) !=
    1698             :             size_filename)
    1699           3 :             err = UNZ_ERRNO;
    1700             :     }
    1701             : 
    1702        4128 :     return err;
    1703             : }
    1704             : 
    1705             : /** Addition for GDAL : END */
    1706             : 
    1707             : /*
    1708             :   Read bytes from the current file.
    1709             :   buf contain buffer where data must be copied
    1710             :   len the size of buf.
    1711             : 
    1712             :   return the number of byte copied if some bytes are copied
    1713             :   return 0 if the end of file was reached
    1714             :   return <0 with error code if there is an error
    1715             :     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
    1716             : */
    1717           0 : extern int ZEXPORT cpl_unzReadCurrentFile(unzFile file, voidp buf, unsigned len)
    1718             : {
    1719           0 :     int err = UNZ_OK;
    1720           0 :     uInt iRead = 0;
    1721             :     unz_s *s;
    1722             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1723           0 :     if (file == nullptr)
    1724           0 :         return UNZ_PARAMERROR;
    1725           0 :     s = reinterpret_cast<unz_s *>(file);
    1726           0 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1727             : 
    1728           0 :     if (pfile_in_zip_read_info == nullptr)
    1729           0 :         return UNZ_PARAMERROR;
    1730             : 
    1731           0 :     if (pfile_in_zip_read_info->read_buffer == nullptr)
    1732           0 :         return UNZ_END_OF_LIST_OF_FILE;
    1733           0 :     if (len == 0)
    1734           0 :         return 0;
    1735             : 
    1736           0 :     pfile_in_zip_read_info->stream.next_out = reinterpret_cast<Bytef *>(buf);
    1737             : 
    1738           0 :     pfile_in_zip_read_info->stream.avail_out = static_cast<uInt>(len);
    1739             : 
    1740           0 :     if ((len > pfile_in_zip_read_info->rest_read_uncompressed) &&
    1741           0 :         (!(pfile_in_zip_read_info->raw)))
    1742           0 :         pfile_in_zip_read_info->stream.avail_out =
    1743           0 :             static_cast<uInt>(pfile_in_zip_read_info->rest_read_uncompressed);
    1744             : 
    1745           0 :     if ((len > pfile_in_zip_read_info->rest_read_compressed +
    1746           0 :                    pfile_in_zip_read_info->stream.avail_in) &&
    1747           0 :         (pfile_in_zip_read_info->raw))
    1748           0 :         pfile_in_zip_read_info->stream.avail_out =
    1749           0 :             static_cast<uInt>(pfile_in_zip_read_info->rest_read_compressed) +
    1750           0 :             pfile_in_zip_read_info->stream.avail_in;
    1751             : 
    1752           0 :     while (pfile_in_zip_read_info->stream.avail_out > 0)
    1753             :     {
    1754           0 :         if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
    1755           0 :             (pfile_in_zip_read_info->rest_read_compressed > 0))
    1756             :         {
    1757           0 :             uInt uReadThis = UNZ_BUFSIZE;
    1758           0 :             if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
    1759           0 :                 uReadThis = static_cast<uInt>(
    1760           0 :                     pfile_in_zip_read_info->rest_read_compressed);
    1761           0 :             if (uReadThis == 0)
    1762           0 :                 return UNZ_EOF;
    1763           0 :             if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
    1764             :                       pfile_in_zip_read_info->filestream,
    1765             :                       pfile_in_zip_read_info->pos_in_zipfile +
    1766             :                           pfile_in_zip_read_info->byte_before_the_zipfile,
    1767           0 :                       ZLIB_FILEFUNC_SEEK_SET) != 0)
    1768           0 :                 return UNZ_ERRNO;
    1769           0 :             if (ZREAD(pfile_in_zip_read_info->z_filefunc,
    1770             :                       pfile_in_zip_read_info->filestream,
    1771             :                       pfile_in_zip_read_info->read_buffer,
    1772           0 :                       uReadThis) != uReadThis)
    1773           0 :                 return UNZ_ERRNO;
    1774             : 
    1775             : #ifndef NOUNCRYPT
    1776             :             if (s->encrypted)
    1777             :             {
    1778             :                 uInt i;
    1779             :                 for (i = 0; i < uReadThis; i++)
    1780             :                     pfile_in_zip_read_info->read_buffer[i] =
    1781             :                         zdecode(s->keys, s->pcrc_32_tab,
    1782             :                                 pfile_in_zip_read_info->read_buffer[i]);
    1783             :             }
    1784             : #endif
    1785             : 
    1786           0 :             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
    1787             : 
    1788           0 :             pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
    1789             : 
    1790           0 :             pfile_in_zip_read_info->stream.next_in =
    1791           0 :                 reinterpret_cast<Bytef *>(pfile_in_zip_read_info->read_buffer);
    1792           0 :             pfile_in_zip_read_info->stream.avail_in =
    1793             :                 static_cast<uInt>(uReadThis);
    1794             :         }
    1795             : 
    1796           0 :         if ((pfile_in_zip_read_info->compression_method == 0) ||
    1797           0 :             (pfile_in_zip_read_info->raw))
    1798             :         {
    1799           0 :             uInt uDoCopy = 0;
    1800           0 :             uInt i = 0;
    1801             : 
    1802           0 :             if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
    1803           0 :                 (pfile_in_zip_read_info->rest_read_compressed == 0))
    1804           0 :                 return (iRead == 0) ? UNZ_EOF : iRead;
    1805             : 
    1806           0 :             if (pfile_in_zip_read_info->stream.avail_out <
    1807           0 :                 pfile_in_zip_read_info->stream.avail_in)
    1808           0 :                 uDoCopy = pfile_in_zip_read_info->stream.avail_out;
    1809             :             else
    1810           0 :                 uDoCopy = pfile_in_zip_read_info->stream.avail_in;
    1811             : 
    1812           0 :             for (i = 0; i < uDoCopy; i++)
    1813           0 :                 *(pfile_in_zip_read_info->stream.next_out + i) =
    1814           0 :                     *(pfile_in_zip_read_info->stream.next_in + i);
    1815             : 
    1816           0 :             pfile_in_zip_read_info->crc32 =
    1817           0 :                 crc32(pfile_in_zip_read_info->crc32,
    1818           0 :                       pfile_in_zip_read_info->stream.next_out, uDoCopy);
    1819           0 :             pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
    1820           0 :             pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
    1821           0 :             pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
    1822           0 :             pfile_in_zip_read_info->stream.next_out += uDoCopy;
    1823           0 :             pfile_in_zip_read_info->stream.next_in += uDoCopy;
    1824           0 :             pfile_in_zip_read_info->stream.total_out += uDoCopy;
    1825           0 :             iRead += uDoCopy;
    1826             :         }
    1827             :         else
    1828             :         {
    1829             :             uLong64 uTotalOutBefore, uTotalOutAfter;
    1830             :             const Bytef *bufBefore;
    1831             :             uLong64 uOutThis;
    1832           0 :             int flush = Z_SYNC_FLUSH;
    1833             : 
    1834           0 :             uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
    1835           0 :             bufBefore = pfile_in_zip_read_info->stream.next_out;
    1836             : 
    1837             :             /*
    1838             :             if ((pfile_in_zip_read_info->rest_read_uncompressed ==
    1839             :                      pfile_in_zip_read_info->stream.avail_out) &&
    1840             :                 (pfile_in_zip_read_info->rest_read_compressed == 0))
    1841             :                 flush = Z_FINISH;
    1842             :             */
    1843           0 :             err = inflate(&pfile_in_zip_read_info->stream, flush);
    1844             : 
    1845           0 :             if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != nullptr))
    1846           0 :                 err = Z_DATA_ERROR;
    1847             : 
    1848           0 :             uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
    1849           0 :             uOutThis = uTotalOutAfter - uTotalOutBefore;
    1850             : 
    1851           0 :             pfile_in_zip_read_info->crc32 =
    1852           0 :                 crc32(pfile_in_zip_read_info->crc32, bufBefore,
    1853             :                       static_cast<uInt>(uOutThis));
    1854             : 
    1855           0 :             pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
    1856             : 
    1857           0 :             iRead += static_cast<uInt>(uTotalOutAfter - uTotalOutBefore);
    1858             : 
    1859           0 :             if (err == Z_STREAM_END)
    1860           0 :                 return (iRead == 0) ? UNZ_EOF : iRead;
    1861           0 :             if (err != Z_OK)
    1862           0 :                 break;
    1863             :         }
    1864             :     }
    1865             : 
    1866           0 :     if (err == Z_OK)
    1867           0 :         return iRead;
    1868           0 :     return err;
    1869             : }
    1870             : 
    1871             : /*
    1872             :   Give the current position in uncompressed data
    1873             : */
    1874           0 : extern z_off_t ZEXPORT cpl_unztell(unzFile file)
    1875             : {
    1876             :     unz_s *s;
    1877             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1878           0 :     if (file == nullptr)
    1879           0 :         return UNZ_PARAMERROR;
    1880           0 :     s = reinterpret_cast<unz_s *>(file);
    1881           0 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1882             : 
    1883           0 :     if (pfile_in_zip_read_info == nullptr)
    1884           0 :         return UNZ_PARAMERROR;
    1885             : 
    1886           0 :     return static_cast<z_off_t>(pfile_in_zip_read_info->stream.total_out);
    1887             : }
    1888             : 
    1889             : /*
    1890             :   return 1 if the end of file was reached, 0 elsewhere
    1891             : */
    1892           0 : extern int ZEXPORT cpl_unzeof(unzFile file)
    1893             : {
    1894             :     unz_s *s;
    1895             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1896           0 :     if (file == nullptr)
    1897           0 :         return UNZ_PARAMERROR;
    1898           0 :     s = reinterpret_cast<unz_s *>(file);
    1899           0 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1900             : 
    1901           0 :     if (pfile_in_zip_read_info == nullptr)
    1902           0 :         return UNZ_PARAMERROR;
    1903             : 
    1904           0 :     if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
    1905           0 :         return 1;
    1906             :     else
    1907           0 :         return 0;
    1908             : }
    1909             : 
    1910             : /*
    1911             :   Read extra field from the current file (opened by unzOpenCurrentFile)
    1912             :   This is the local-header version of the extra field (sometimes, there is
    1913             :     more info in the local-header version than in the central-header)
    1914             : 
    1915             :   if buf==NULL, it return the size of the local extra field that can be read
    1916             : 
    1917             :   if buf!=NULL, len is the size of the buffer, the extra header is copied in
    1918             :     buf.
    1919             :   the return value is the number of bytes copied in buf, or (if <0)
    1920             :     the error code
    1921             : */
    1922           0 : extern int ZEXPORT cpl_unzGetLocalExtrafield(unzFile file, voidp buf,
    1923             :                                              unsigned len)
    1924             : {
    1925             :     unz_s *s;
    1926             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1927             :     uInt read_now;
    1928             :     uLong64 size_to_read;
    1929             : 
    1930           0 :     if (file == nullptr)
    1931           0 :         return UNZ_PARAMERROR;
    1932           0 :     s = reinterpret_cast<unz_s *>(file);
    1933           0 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1934             : 
    1935           0 :     if (pfile_in_zip_read_info == nullptr)
    1936           0 :         return UNZ_PARAMERROR;
    1937             : 
    1938           0 :     size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
    1939           0 :                     pfile_in_zip_read_info->pos_local_extrafield);
    1940             : 
    1941           0 :     if (buf == nullptr)
    1942           0 :         return static_cast<int>(size_to_read);
    1943             : 
    1944           0 :     if (len > size_to_read)
    1945           0 :         read_now = static_cast<uInt>(size_to_read);
    1946             :     else
    1947           0 :         read_now = static_cast<uInt>(len);
    1948             : 
    1949           0 :     if (read_now == 0)
    1950           0 :         return 0;
    1951             : 
    1952           0 :     if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
    1953             :               pfile_in_zip_read_info->filestream,
    1954             :               pfile_in_zip_read_info->offset_local_extrafield +
    1955             :                   pfile_in_zip_read_info->pos_local_extrafield,
    1956           0 :               ZLIB_FILEFUNC_SEEK_SET) != 0)
    1957           0 :         return UNZ_ERRNO;
    1958             : 
    1959           0 :     if (ZREAD(pfile_in_zip_read_info->z_filefunc,
    1960           0 :               pfile_in_zip_read_info->filestream, buf, read_now) != read_now)
    1961           0 :         return UNZ_ERRNO;
    1962             : 
    1963           0 :     return static_cast<int>(read_now);
    1964             : }
    1965             : 
    1966             : /*
    1967             :   Close the file in zip opened with unzipOpenCurrentFile
    1968             :   Return UNZ_CRCERROR if all the file was read but the CRC is not good
    1969             : */
    1970        4200 : extern int ZEXPORT cpl_unzCloseCurrentFile(unzFile file)
    1971             : {
    1972        4200 :     int err = UNZ_OK;
    1973             : 
    1974             :     unz_s *s;
    1975             :     file_in_zip_read_info_s *pfile_in_zip_read_info;
    1976        4200 :     if (file == nullptr)
    1977           0 :         return UNZ_PARAMERROR;
    1978        4200 :     s = reinterpret_cast<unz_s *>(file);
    1979        4200 :     pfile_in_zip_read_info = s->pfile_in_zip_read;
    1980             : 
    1981        4200 :     if (pfile_in_zip_read_info == nullptr)
    1982           0 :         return UNZ_PARAMERROR;
    1983             : 
    1984        4200 :     if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
    1985           0 :         (!pfile_in_zip_read_info->raw))
    1986             :     {
    1987           0 :         if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
    1988           0 :             err = UNZ_CRCERROR;
    1989             :     }
    1990             : 
    1991        4200 :     TRYFREE(pfile_in_zip_read_info->read_buffer);
    1992        4200 :     pfile_in_zip_read_info->read_buffer = nullptr;
    1993        4200 :     if (pfile_in_zip_read_info->stream_initialised)
    1994        4128 :         inflateEnd(&pfile_in_zip_read_info->stream);
    1995             : 
    1996        4200 :     pfile_in_zip_read_info->stream_initialised = 0;
    1997        4200 :     TRYFREE(pfile_in_zip_read_info);
    1998             : 
    1999        4200 :     s->pfile_in_zip_read = nullptr;
    2000             : 
    2001        4200 :     return err;
    2002             : }
    2003             : 
    2004             : /*
    2005             :   Get the global comment string of the ZipFile, in the szComment buffer.
    2006             :   uSizeBuf is the size of the szComment buffer.
    2007             :   return the number of byte copied or an error code <0
    2008             : */
    2009           0 : extern int ZEXPORT cpl_unzGetGlobalComment(unzFile file, char *szComment,
    2010             :                                            uLong uSizeBuf)
    2011             : {
    2012             :     /* int err=UNZ_OK; */
    2013             :     unz_s *s;
    2014             :     uLong uReadThis;
    2015           0 :     if (file == nullptr)
    2016           0 :         return UNZ_PARAMERROR;
    2017           0 :     s = reinterpret_cast<unz_s *>(file);
    2018             : 
    2019           0 :     uReadThis = uSizeBuf;
    2020           0 :     if (uReadThis > s->gi.size_comment)
    2021           0 :         uReadThis = s->gi.size_comment;
    2022             : 
    2023           0 :     if (ZSEEK(s->z_filefunc, s->filestream, s->central_pos + 22,
    2024           0 :               ZLIB_FILEFUNC_SEEK_SET) != 0)
    2025           0 :         return UNZ_ERRNO;
    2026             : 
    2027           0 :     if (uReadThis > 0)
    2028             :     {
    2029           0 :         *szComment = '\0';
    2030           0 :         if (ZREAD(s->z_filefunc, s->filestream, szComment, uReadThis) !=
    2031             :             uReadThis)
    2032           0 :             return UNZ_ERRNO;
    2033             :     }
    2034             : 
    2035           0 :     if ((szComment != nullptr) && (uSizeBuf > s->gi.size_comment))
    2036           0 :         *(szComment + s->gi.size_comment) = '\0';
    2037           0 :     return static_cast<int>(uReadThis);
    2038             : }
    2039             : 
    2040             : // Additions by RX '2004.
    2041           0 : extern uLong64 ZEXPORT cpl_unzGetOffset(unzFile file)
    2042             : {
    2043             :     unz_s *s;
    2044             : 
    2045           0 :     if (file == nullptr)
    2046           0 :         return 0;  // UNZ_PARAMERROR;
    2047           0 :     s = reinterpret_cast<unz_s *>(file);
    2048           0 :     if (!s->current_file_ok)
    2049           0 :         return 0;
    2050           0 :     if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
    2051           0 :         if (s->num_file == s->gi.number_entry)
    2052           0 :             return 0;
    2053           0 :     return s->pos_in_central_dir;
    2054             : }
    2055             : 
    2056           0 : extern int ZEXPORT cpl_unzSetOffset(unzFile file, uLong64 pos)
    2057             : {
    2058             :     unz_s *s;
    2059             : 
    2060           0 :     if (file == nullptr)
    2061           0 :         return UNZ_PARAMERROR;
    2062           0 :     s = reinterpret_cast<unz_s *>(file);
    2063             : 
    2064           0 :     s->pos_in_central_dir = pos;
    2065           0 :     s->num_file = s->gi.number_entry; /* hack */
    2066           0 :     int err = unzlocal_GetCurrentFileInfoInternal(
    2067             :         file, &s->cur_file_info, &s->cur_file_info_internal, nullptr, 0,
    2068             :         nullptr, 0, nullptr, 0);
    2069           0 :     s->current_file_ok = (err == UNZ_OK);
    2070           0 :     return err;
    2071             : }

Generated by: LCOV version 1.14