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

Generated by: LCOV version 1.14