PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/zip - php_zip.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 942 1250 75.4 %
Date: 2022-01-18 Functions: 72 77 93.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2018 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt.                                 |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Author: Piere-Alain Joye <pierre@php.net>                            |
      16             :   +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : 
      20             : #ifdef HAVE_CONFIG_H
      21             : #include "config.h"
      22             : #endif
      23             : 
      24             : #include "php.h"
      25             : #include "php_ini.h"
      26             : #include "ext/standard/info.h"
      27             : #include "ext/standard/file.h"
      28             : #include "ext/standard/php_string.h"
      29             : #include "ext/pcre/php_pcre.h"
      30             : #include "ext/standard/php_filestat.h"
      31             : #if PHP_VERSION_ID >= 70200
      32             : #include "zend_interfaces.h"
      33             : #elif defined(HAVE_SPL)
      34             : #include "ext/spl/spl_iterators.h"
      35             : #endif
      36             : #include "php_zip.h"
      37             : 
      38             : /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
      39             : static PHP_NAMED_FUNCTION(zif_zip_open);
      40             : static PHP_NAMED_FUNCTION(zif_zip_read);
      41             : static PHP_NAMED_FUNCTION(zif_zip_close);
      42             : static PHP_NAMED_FUNCTION(zif_zip_entry_read);
      43             : static PHP_NAMED_FUNCTION(zif_zip_entry_filesize);
      44             : static PHP_NAMED_FUNCTION(zif_zip_entry_name);
      45             : static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize);
      46             : static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod);
      47             : static PHP_NAMED_FUNCTION(zif_zip_entry_open);
      48             : static PHP_NAMED_FUNCTION(zif_zip_entry_close);
      49             : 
      50             : #ifdef HAVE_GLOB
      51             : #ifndef PHP_WIN32
      52             : #include <glob.h>
      53             : #else
      54             : #include "win32/glob.h"
      55             : #endif
      56             : #endif
      57             : 
      58             : /* {{{ Resource le */
      59             : static int le_zip_dir;
      60             : #define le_zip_dir_name "Zip Directory"
      61             : static int le_zip_entry;
      62             : #define le_zip_entry_name "Zip Entry"
      63             : /* }}} */
      64             : 
      65             : /* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */
      66             : #define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \
      67             :         if (zip_stat_index(za, index, flags, &sb) != 0) { \
      68             :                 RETURN_FALSE; \
      69             :         }
      70             : /* }}} */
      71             : 
      72             : /* {{{  PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */
      73             : #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \
      74             :         if (path_len < 1) { \
      75             :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); \
      76             :                 RETURN_FALSE; \
      77             :         } \
      78             :         if (zip_stat(za, path, flags, &sb) != 0) { \
      79             :                 RETURN_FALSE; \
      80             :         }
      81             : /* }}} */
      82             : 
      83             : /* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */
      84             : #define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
      85             :         if (comment_len == 0) { \
      86             :                 /* Passing NULL remove the existing comment */ \
      87             :                 if (zip_set_file_comment(za, index, NULL, 0) < 0) { \
      88             :                         RETURN_FALSE; \
      89             :                 } \
      90             :         } else if (zip_set_file_comment(za, index, comment, comment_len) < 0) { \
      91             :                 RETURN_FALSE; \
      92             :         } \
      93             :         RETURN_TRUE;
      94             : /* }}} */
      95             : 
      96             : # define add_ascii_assoc_string add_assoc_string
      97             : # define add_ascii_assoc_long add_assoc_long
      98             : 
      99             : /* Flatten a path by making a relative path (to .)*/
     100          15 : static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
     101             : {
     102          15 :         char *path_begin = path;
     103             :         size_t i;
     104             : 
     105          15 :         if (path_len < 1 || path == NULL) {
     106           0 :                 return NULL;
     107             :         }
     108             : 
     109          15 :         if (IS_SLASH(path[0])) {
     110           0 :                 return path + 1;
     111             :         }
     112             : 
     113          15 :         i = path_len;
     114             : 
     115             :         while (1) {
     116         148 :                 while (i > 0 && !IS_SLASH(path[i])) {
     117          91 :                         i--;
     118             :                 }
     119             : 
     120          24 :                 if (!i) {
     121          14 :                         return path;
     122             :                 }
     123             : 
     124          10 :                 if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
     125             :                         /* i is the position of . or :, add 1 for / */
     126           1 :                         path_begin = path + i + 1;
     127           1 :                         break;
     128             :                 }
     129           9 :                 i--;
     130             :         }
     131             : 
     132           1 :         return path_begin;
     133             : }
     134             : /* }}} */
     135             : 
     136             : # define CWD_STATE_ALLOC(l) emalloc(l)
     137             : # define CWD_STATE_FREE(s)  efree(s)
     138             : 
     139             : /* {{{ php_zip_extract_file */
     140          15 : static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t file_len)
     141             : {
     142             :         php_stream_statbuf ssb;
     143             :         struct zip_file *zf;
     144             :         struct zip_stat sb;
     145             :         char b[8192];
     146             :         int n, ret;
     147             :         php_stream *stream;
     148             :         char *fullpath;
     149             :         char *file_dirname_fullpath;
     150             :         char file_dirname[MAXPATHLEN];
     151             :         size_t dir_len, len;
     152          15 :         int is_dir_only = 0;
     153             :         char *path_cleaned;
     154             :         size_t path_cleaned_len;
     155             :         cwd_state new_state;
     156             :         zend_string *file_basename;
     157             : 
     158          15 :         new_state.cwd = CWD_STATE_ALLOC(1);
     159          15 :         new_state.cwd[0] = '\0';
     160          15 :         new_state.cwd_length = 0;
     161             : 
     162             :         /* Clean/normlize the path and then transform any path (absolute or relative)
     163             :                  to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
     164             :          */
     165          15 :         virtual_file_ex(&new_state, file, NULL, CWD_EXPAND);
     166          15 :         path_cleaned =  php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
     167          15 :         if(!path_cleaned) {
     168           0 :                 return 0;
     169             :         }
     170          15 :         path_cleaned_len = strlen(path_cleaned);
     171             : 
     172          15 :         if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
     173           0 :                 return 0;
     174             :         }
     175             : 
     176             :         /* it is a directory only, see #40228 */
     177          15 :         if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
     178           6 :                 len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, path_cleaned);
     179           6 :                 is_dir_only = 1;
     180             :         } else {
     181           9 :                 memcpy(file_dirname, path_cleaned, path_cleaned_len);
     182           9 :                 dir_len = php_dirname(file_dirname, path_cleaned_len);
     183             : 
     184           9 :                 if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) {
     185           8 :                         len = spprintf(&file_dirname_fullpath, 0, "%s", dest);
     186             :                 } else {
     187           1 :                         len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
     188             :                 }
     189             : 
     190           9 :                 file_basename = php_basename(path_cleaned, path_cleaned_len, NULL, 0);
     191             : 
     192           9 :                 if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
     193           0 :                         efree(file_dirname_fullpath);
     194             :                         zend_string_release_ex(file_basename, 0);
     195           0 :                         CWD_STATE_FREE(new_state.cwd);
     196           0 :                         return 0;
     197             :                 }
     198             :         }
     199             : 
     200             :         /* let see if the path already exists */
     201          15 :         if (php_stream_stat_path_ex(file_dirname_fullpath, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
     202           6 :                 ret = php_stream_mkdir(file_dirname_fullpath, 0777,  PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL);
     203           6 :                 if (!ret) {
     204           0 :                         efree(file_dirname_fullpath);
     205           0 :                         if (!is_dir_only) {
     206             :                                 zend_string_release_ex(file_basename, 0);
     207           0 :                                 CWD_STATE_FREE(new_state.cwd);
     208             :                         }
     209           0 :                         return 0;
     210             :                 }
     211             :         }
     212             : 
     213             :         /* it is a standalone directory, job done */
     214          15 :         if (is_dir_only) {
     215           6 :                 efree(file_dirname_fullpath);
     216           6 :                 CWD_STATE_FREE(new_state.cwd);
     217           6 :                 return 1;
     218             :         }
     219             : 
     220           9 :         len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, ZSTR_VAL(file_basename));
     221           9 :         if (!len) {
     222           0 :                 efree(file_dirname_fullpath);
     223             :                 zend_string_release_ex(file_basename, 0);
     224           0 :                 CWD_STATE_FREE(new_state.cwd);
     225           0 :                 return 0;
     226           9 :         } else if (len > MAXPATHLEN) {
     227           0 :                 php_error_docref(NULL, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
     228           0 :                 efree(file_dirname_fullpath);
     229             :                 zend_string_release_ex(file_basename, 0);
     230           0 :                 CWD_STATE_FREE(new_state.cwd);
     231           0 :                 return 0;
     232             :         }
     233             : 
     234             :         /* check again the full path, not sure if it
     235             :          * is required, does a file can have a different
     236             :          * safemode status as its parent folder?
     237             :          */
     238           9 :         if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) {
     239           0 :                 efree(fullpath);
     240           0 :                 efree(file_dirname_fullpath);
     241             :                 zend_string_release_ex(file_basename, 0);
     242           0 :                 CWD_STATE_FREE(new_state.cwd);
     243           0 :                 return 0;
     244             :         }
     245             : 
     246           9 :         zf = zip_fopen(za, file, 0);
     247           9 :         if (zf == NULL) {
     248           1 :                 n = -1;
     249           1 :                 goto done;
     250             :         }
     251             : 
     252           8 :         stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL);
     253             : 
     254           8 :         if (stream == NULL) {
     255           1 :                 n = -1;
     256           1 :                 zip_fclose(zf);
     257           1 :                 goto done;
     258             :         }
     259             : 
     260           7 :         n = 0;
     261             : 
     262          21 :         while ((n=zip_fread(zf, b, sizeof(b))) > 0) {
     263           7 :                 php_stream_write(stream, b, n);
     264             :         }
     265             : 
     266           7 :         php_stream_close(stream);
     267           7 :         n = zip_fclose(zf);
     268             : 
     269           9 : done:
     270           9 :         efree(fullpath);
     271             :         zend_string_release_ex(file_basename, 0);
     272           9 :         efree(file_dirname_fullpath);
     273           9 :         CWD_STATE_FREE(new_state.cwd);
     274             : 
     275           9 :         if (n<0) {
     276           2 :                 return 0;
     277             :         } else {
     278           7 :                 return 1;
     279             :         }
     280             : }
     281             : /* }}} */
     282             : 
     283          13 : static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
     284             :         char *entry_name, size_t entry_name_len, long offset_start, long offset_len) /* {{{ */
     285             : {
     286             :         struct zip_source *zs;
     287             :         char resolved_path[MAXPATHLEN];
     288             :         zval exists_flag;
     289             : 
     290             : 
     291          13 :         if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
     292           0 :                 return -1;
     293             :         }
     294             : 
     295          13 :         if (!expand_filepath(filename, resolved_path)) {
     296           0 :                 return -1;
     297             :         }
     298             : 
     299          13 :         php_stat(resolved_path, strlen(resolved_path), FS_EXISTS, &exists_flag);
     300          13 :         if (Z_TYPE(exists_flag) == IS_FALSE) {
     301           3 :                 return -1;
     302             :         }
     303             : 
     304          10 :         zs = zip_source_file(za, resolved_path, offset_start, offset_len);
     305          10 :         if (!zs) {
     306           0 :                 return -1;
     307             :         }
     308          10 :         if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
     309           0 :                 zip_source_free(zs);
     310           0 :                 return -1;
     311             :         } else {
     312          10 :                 zip_error_clear(za);
     313          10 :                 return 1;
     314             :         }
     315             : }
     316             : /* }}} */
     317             : 
     318           4 : static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char **remove_path, size_t *remove_path_len, char **add_path, size_t *add_path_len) /* {{{ */
     319             : {
     320             :         zval *option;
     321           4 :         if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) {
     322           2 :                 *remove_all_path = zval_get_long(option);
     323             :         }
     324             : 
     325             :         /* If I add more options, it would make sense to create a nice static struct and loop over it. */
     326           4 :         if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_path", sizeof("remove_path") - 1)) != NULL) {
     327           2 :                 if (Z_TYPE_P(option) != IS_STRING) {
     328           0 :                         php_error_docref(NULL, E_WARNING, "remove_path option expected to be a string");
     329           0 :                         return -1;
     330             :                 }
     331             : 
     332           2 :                 if (Z_STRLEN_P(option) < 1) {
     333           0 :                         php_error_docref(NULL, E_NOTICE, "Empty string given as remove_path option");
     334           0 :                         return -1;
     335             :                 }
     336             : 
     337           2 :                 if (Z_STRLEN_P(option) >= MAXPATHLEN) {
     338           0 :                         php_error_docref(NULL, E_WARNING, "remove_path string is too long (max: %d, %zd given)",
     339           0 :                                                 MAXPATHLEN - 1, Z_STRLEN_P(option));
     340           0 :                         return -1;
     341             :                 }
     342           2 :                 *remove_path_len = Z_STRLEN_P(option);
     343           2 :                 *remove_path = Z_STRVAL_P(option);
     344             :         }
     345             : 
     346           4 :         if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "add_path", sizeof("add_path") - 1)) != NULL) {
     347           2 :                 if (Z_TYPE_P(option) != IS_STRING) {
     348           0 :                         php_error_docref(NULL, E_WARNING, "add_path option expected to be a string");
     349           0 :                         return -1;
     350             :                 }
     351             : 
     352           2 :                 if (Z_STRLEN_P(option) < 1) {
     353           0 :                         php_error_docref(NULL, E_NOTICE, "Empty string given as the add_path option");
     354           0 :                         return -1;
     355             :                 }
     356             : 
     357           2 :                 if (Z_STRLEN_P(option) >= MAXPATHLEN) {
     358           0 :                         php_error_docref(NULL, E_WARNING, "add_path string too long (max: %d, %zd given)",
     359           0 :                                                 MAXPATHLEN - 1, Z_STRLEN_P(option));
     360           0 :                         return -1;
     361             :                 }
     362           2 :                 *add_path_len = Z_STRLEN_P(option);
     363           2 :                 *add_path = Z_STRVAL_P(option);
     364             :         }
     365           4 :         return 1;
     366             : }
     367             : /* }}} */
     368             : 
     369             : /* {{{ REGISTER_ZIP_CLASS_CONST_LONG */
     370             : #define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \
     371             :             zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (zend_long)value);
     372             : /* }}} */
     373             : 
     374             : /* {{{ ZIP_FROM_OBJECT */
     375             : #define ZIP_FROM_OBJECT(intern, object) \
     376             :         { \
     377             :                 ze_zip_object *obj = Z_ZIP_P(object); \
     378             :                 intern = obj->za; \
     379             :                 if (!intern) { \
     380             :                         php_error_docref(NULL, E_WARNING, "Invalid or uninitialized Zip object"); \
     381             :                         RETURN_FALSE; \
     382             :                 } \
     383             :         }
     384             : /* }}} */
     385             : 
     386             : /* {{{ RETURN_SB(sb) */
     387             : #ifdef HAVE_ENCRYPTION
     388             : #define RETURN_SB(sb) \
     389             :         { \
     390             :                 array_init(return_value); \
     391             :                 add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \
     392             :                 add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \
     393             :                 add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \
     394             :                 add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \
     395             :                 add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \
     396             :                 add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \
     397             :                 add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \
     398             :                 add_ascii_assoc_long(return_value, "encryption_method", (zend_long) (sb)->encryption_method); \
     399             :         }
     400             : #else
     401             : #define RETURN_SB(sb) \
     402             :         { \
     403             :                 array_init(return_value); \
     404             :                 add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \
     405             :                 add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \
     406             :                 add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \
     407             :                 add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \
     408             :                 add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \
     409             :                 add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \
     410             :                 add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \
     411             :         }
     412             : #endif
     413             : /* }}} */
     414             : 
     415          23 : static int php_zip_status(struct zip *za) /* {{{ */
     416             : {
     417             : #if LIBZIP_VERSION_MAJOR < 1
     418             :         int zep, syp;
     419             : 
     420             :         zip_error_get(za, &zep, &syp);
     421             : #else
     422             :         int zep;
     423             :         zip_error_t *err;
     424             : 
     425          23 :         err = zip_get_error(za);
     426          23 :         zep = zip_error_code_zip(err);
     427          23 :         zip_error_fini(err);
     428             : #endif
     429          23 :         return zep;
     430             : }
     431             : /* }}} */
     432             : 
     433           3 : static int php_zip_status_sys(struct zip *za) /* {{{ */
     434             : {
     435             : #if LIBZIP_VERSION_MAJOR < 1
     436             :         int zep, syp;
     437             : 
     438             :         zip_error_get(za, &zep, &syp);
     439             : #else
     440             :         int syp;
     441             :         zip_error_t *err;
     442             : 
     443           3 :         err = zip_get_error(za);
     444           3 :         syp = zip_error_code_system(err);
     445           3 :         zip_error_fini(err);
     446             : #endif
     447           3 :         return syp;
     448             : }
     449             : /* }}} */
     450             : 
     451          76 : static int php_zip_get_num_files(struct zip *za) /* {{{ */
     452             : {
     453          76 :         return zip_get_num_files(za);
     454             : }
     455             : /* }}} */
     456             : 
     457           6 : static char * php_zipobj_get_filename(ze_zip_object *obj) /* {{{ */
     458             : {
     459             : 
     460           6 :         if (!obj) {
     461           0 :                 return NULL;
     462             :         }
     463             : 
     464           6 :         if (obj->filename) {
     465           6 :                 return obj->filename;
     466             :         }
     467           0 :         return NULL;
     468             : }
     469             : /* }}} */
     470             : 
     471           6 : static char * php_zipobj_get_zip_comment(struct zip *za, int *len) /* {{{ */
     472             : {
     473           6 :         if (za) {
     474           6 :                 return (char *)zip_get_archive_comment(za, len, 0);
     475             :         }
     476           0 :         return NULL;
     477             : }
     478             : /* }}} */
     479             : 
     480             : #ifdef HAVE_GLOB /* {{{ */
     481             : #ifndef GLOB_ONLYDIR
     482             : #define GLOB_ONLYDIR (1<<30)
     483             : #define GLOB_EMULATE_ONLYDIR
     484             : #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
     485             : #else
     486             : #define GLOB_FLAGMASK (~0)
     487             : #endif
     488             : #ifndef GLOB_BRACE
     489             : # define GLOB_BRACE 0
     490             : #endif
     491             : #ifndef GLOB_MARK
     492             : # define GLOB_MARK 0
     493             : #endif
     494             : #ifndef GLOB_NOSORT
     495             : # define GLOB_NOSORT 0
     496             : #endif
     497             : #ifndef GLOB_NOCHECK
     498             : # define GLOB_NOCHECK 0
     499             : #endif
     500             : #ifndef GLOB_NOESCAPE
     501             : # define GLOB_NOESCAPE 0
     502             : #endif
     503             : #ifndef GLOB_ERR
     504             : # define GLOB_ERR 0
     505             : #endif
     506             : 
     507             : /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
     508             : #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
     509             : 
     510             : #endif /* }}} */
     511             : 
     512           3 : int php_zip_glob(char *pattern, int pattern_len, zend_long flags, zval *return_value) /* {{{ */
     513             : {
     514             : #ifdef HAVE_GLOB
     515             :         char cwd[MAXPATHLEN];
     516           3 :         int cwd_skip = 0;
     517             : #ifdef ZTS
     518             :         char work_pattern[MAXPATHLEN];
     519             :         char *result;
     520             : #endif
     521             :         glob_t globbuf;
     522             :         size_t n;
     523             :         int ret;
     524             : 
     525           3 :         if (pattern_len >= MAXPATHLEN) {
     526           0 :                 php_error_docref(NULL, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
     527           0 :                 return -1;
     528             :         }
     529             : 
     530           3 :         if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
     531           0 :                 php_error_docref(NULL, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
     532           0 :                 return -1;
     533             :         }
     534             : 
     535             : #ifdef ZTS
     536             :         if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
     537             :                 result = VCWD_GETCWD(cwd, MAXPATHLEN);
     538             :                 if (!result) {
     539             :                         cwd[0] = '\0';
     540             :                 }
     541             : #ifdef PHP_WIN32
     542             :                 if (IS_SLASH(*pattern)) {
     543             :                         cwd[2] = '\0';
     544             :                 }
     545             : #endif
     546             :                 cwd_skip = strlen(cwd)+1;
     547             : 
     548             :                 snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
     549             :                 pattern = work_pattern;
     550             :         }
     551             : #endif
     552             : 
     553           3 :         globbuf.gl_offs = 0;
     554           3 :         if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
     555             : #ifdef GLOB_NOMATCH
     556           0 :                 if (GLOB_NOMATCH == ret) {
     557             :                         /* Some glob implementation simply return no data if no matches
     558             :                            were found, others return the GLOB_NOMATCH error code.
     559             :                            We don't want to treat GLOB_NOMATCH as an error condition
     560             :                            so that PHP glob() behaves the same on both types of
     561             :                            implementations and so that 'foreach (glob() as ...'
     562             :                            can be used for simple glob() calls without further error
     563             :                            checking.
     564             :                         */
     565           0 :                         array_init(return_value);
     566           0 :                         return 0;
     567             :                 }
     568             : #endif
     569           0 :                 return 0;
     570             :         }
     571             : 
     572             :         /* now catch the FreeBSD style of "no matches" */
     573           3 :         if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
     574           0 :                 array_init(return_value);
     575           0 :                 return 0;
     576             :         }
     577             : 
     578             :         /* we assume that any glob pattern will match files from one directory only
     579             :            so checking the dirname of the first match should be sufficient */
     580           3 :         strncpy(cwd, globbuf.gl_pathv[0], MAXPATHLEN);
     581           3 :         if (ZIP_OPENBASEDIR_CHECKPATH(cwd)) {
     582           0 :                 return -1;
     583             :         }
     584             : 
     585           3 :         array_init(return_value);
     586           7 :         for (n = 0; n < globbuf.gl_pathc; n++) {
     587             :                 /* we need to do this every time since GLOB_ONLYDIR does not guarantee that
     588             :                  * all directories will be filtered. GNU libc documentation states the
     589             :                  * following:
     590             :                  * If the information about the type of the file is easily available
     591             :                  * non-directories will be rejected but no extra work will be done to
     592             :                  * determine the information for each file. I.e., the caller must still be
     593             :                  * able to filter directories out.
     594             :                  */
     595           4 :                 if (flags & GLOB_ONLYDIR) {
     596             :                         zend_stat_t s;
     597             : 
     598           0 :                         if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
     599           0 :                                 continue;
     600             :                         }
     601             : 
     602           0 :                         if (S_IFDIR != (s.st_mode & S_IFMT)) {
     603           0 :                                 continue;
     604             :                         }
     605             :                 }
     606           4 :                 add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip);
     607             :         }
     608             : 
     609           3 :         ret = globbuf.gl_pathc;
     610           3 :         globfree(&globbuf);
     611           3 :         return ret;
     612             : #else
     613             :         zend_throw_error(NULL, "Glob support is not available");
     614             :         return 0;
     615             : #endif  /* HAVE_GLOB */
     616             : }
     617             : /* }}} */
     618             : 
     619           1 : int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_value) /* {{{ */
     620             : {
     621             : #ifdef ZTS
     622             :         char cwd[MAXPATHLEN];
     623             :         int cwd_skip = 0;
     624             :         char work_path[MAXPATHLEN];
     625             :         char *result;
     626             : #endif
     627             :         int files_cnt;
     628             :         zend_string **namelist;
     629           1 :         pcre2_match_context *mctx = php_pcre_mctx();
     630             : 
     631             : #ifdef ZTS
     632             :         if (!IS_ABSOLUTE_PATH(path, path_len)) {
     633             :                 result = VCWD_GETCWD(cwd, MAXPATHLEN);
     634             :                 if (!result) {
     635             :                         cwd[0] = '\0';
     636             :                 }
     637             : #ifdef PHP_WIN32
     638             :                 if (IS_SLASH(*path)) {
     639             :                         cwd[2] = '\0';
     640             :                 }
     641             : #endif
     642             :                 cwd_skip = strlen(cwd)+1;
     643             : 
     644             :                 snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path);
     645             :                 path = work_path;
     646             :         }
     647             : #endif
     648             : 
     649           1 :         if (ZIP_OPENBASEDIR_CHECKPATH(path)) {
     650           0 :                 return -1;
     651             :         }
     652             : 
     653           1 :         files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort);
     654             : 
     655           1 :         if (files_cnt > 0) {
     656           1 :                 pcre2_code *re = NULL;
     657           1 :                 pcre2_match_data *match_data = NULL;
     658           1 :                 uint32_t preg_options = 0, i, capture_count;
     659             :                 int rc;
     660             : 
     661           1 :                 re = pcre_get_compiled_regex(regexp, &capture_count, &preg_options);
     662           1 :                 if (!re) {
     663           0 :                         php_error_docref(NULL, E_WARNING, "Invalid expression");
     664           0 :                         return -1;
     665             :                 }
     666             : 
     667           1 :                 array_init(return_value);
     668             : 
     669             :                 /* only the files, directories are ignored */
     670         167 :                 for (i = 0; i < files_cnt; i++) {
     671             :                         zend_stat_t s;
     672             :                         char   fullpath[MAXPATHLEN];
     673         166 :                         size_t    namelist_len = ZSTR_LEN(namelist[i]);
     674             : 
     675         166 :                         if ((namelist_len == 1 && ZSTR_VAL(namelist[i])[0] == '.') ||
     676           1 :                                 (namelist_len == 2 && ZSTR_VAL(namelist[i])[0] == '.' && ZSTR_VAL(namelist[i])[1] == '.')) {
     677           2 :                                 zend_string_release_ex(namelist[i], 0);
     678         166 :                                 continue;
     679             :                         }
     680             : 
     681         164 :                         if ((path_len + namelist_len + 1) >= MAXPATHLEN) {
     682           0 :                                 php_error_docref(NULL, E_WARNING, "add_path string too long (max: %u, %zu given)",
     683           0 :                                                 MAXPATHLEN - 1, (path_len + namelist_len + 1));
     684           0 :                                 zend_string_release_ex(namelist[i], 0);
     685           0 :                                 break;
     686             :                         }
     687             : 
     688         164 :                         snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, ZSTR_VAL(namelist[i]));
     689             : 
     690         164 :                         if (0 != VCWD_STAT(fullpath, &s)) {
     691           0 :                                 php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath);
     692           0 :                                 zend_string_release_ex(namelist[i], 0);
     693           0 :                                 continue;
     694             :                         }
     695             : 
     696         164 :                         if (S_IFDIR == (s.st_mode & S_IFMT)) {
     697           0 :                                 zend_string_release_ex(namelist[i], 0);
     698           0 :                                 continue;
     699             :                         }
     700             : 
     701         164 :                         match_data = php_pcre_create_match_data(capture_count, re);
     702         164 :                         if (!match_data) {
     703             :                                 /* Allocation failed, but can proceed to the next pattern. */
     704           0 :                                 zend_string_release_ex(namelist[i], 0);
     705           0 :                                 continue;
     706             :                         }
     707         164 :                         rc = pcre2_match(re, (PCRE2_SPTR)ZSTR_VAL(namelist[i]), ZSTR_LEN(namelist[i]), 0, preg_options, match_data, mctx);
     708         164 :                         php_pcre_free_match_data(match_data);
     709             :                         /* 0 means that the vector is too small to hold all the captured substring offsets */
     710         164 :                         if (rc < 0) {
     711         162 :                                 zend_string_release_ex(namelist[i], 0);
     712         162 :                                 continue;
     713             :                         }
     714             : 
     715           2 :                         add_next_index_string(return_value, fullpath);
     716           2 :                         zend_string_release_ex(namelist[i], 0);
     717             :                 }
     718           1 :                 efree(namelist);
     719             :         }
     720           1 :         return files_cnt;
     721             : }
     722             : /* }}} */
     723             : 
     724             : /* {{{ arginfo */
     725             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1)
     726             :         ZEND_ARG_INFO(0, filename)
     727             : ZEND_END_ARG_INFO()
     728             : 
     729             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_close, 0, 0, 1)
     730             :         ZEND_ARG_INFO(0, zip)
     731             : ZEND_END_ARG_INFO()
     732             : 
     733             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_read, 0, 0, 1)
     734             :         ZEND_ARG_INFO(0, zip)
     735             : ZEND_END_ARG_INFO()
     736             : 
     737             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_open, 0, 0, 2)
     738             :         ZEND_ARG_INFO(0, zip_dp)
     739             :         ZEND_ARG_INFO(0, zip_entry)
     740             :         ZEND_ARG_INFO(0, mode)
     741             : ZEND_END_ARG_INFO()
     742             : 
     743             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_close, 0, 0, 1)
     744             :         ZEND_ARG_INFO(0, zip_ent)
     745             : ZEND_END_ARG_INFO()
     746             : 
     747             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_read, 0, 0, 1)
     748             :         ZEND_ARG_INFO(0, zip_entry)
     749             :         ZEND_ARG_INFO(0, len)
     750             : ZEND_END_ARG_INFO()
     751             : 
     752             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_name, 0, 0, 1)
     753             :         ZEND_ARG_INFO(0, zip_entry)
     754             : ZEND_END_ARG_INFO()
     755             : 
     756             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressedsize, 0, 0, 1)
     757             :         ZEND_ARG_INFO(0, zip_entry)
     758             : ZEND_END_ARG_INFO()
     759             : 
     760             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_filesize, 0, 0, 1)
     761             :         ZEND_ARG_INFO(0, zip_entry)
     762             : ZEND_END_ARG_INFO()
     763             : 
     764             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressionmethod, 0, 0, 1)
     765             :         ZEND_ARG_INFO(0, zip_entry)
     766             : ZEND_END_ARG_INFO()
     767             : /* }}} */
     768             : 
     769             : /* {{{ zend_function_entry */
     770             : static const zend_function_entry zip_functions[] = {
     771             :         ZEND_RAW_FENTRY("zip_open", zif_zip_open, arginfo_zip_open, 0)
     772             :         ZEND_RAW_FENTRY("zip_close", zif_zip_close, arginfo_zip_close, 0)
     773             :         ZEND_RAW_FENTRY("zip_read", zif_zip_read, arginfo_zip_read, 0)
     774             :         PHP_FE(zip_entry_open,          arginfo_zip_entry_open)
     775             :         PHP_FE(zip_entry_close,         arginfo_zip_entry_close)
     776             :         PHP_FE(zip_entry_read,          arginfo_zip_entry_read)
     777             :         PHP_FE(zip_entry_filesize,      arginfo_zip_entry_filesize)
     778             :         PHP_FE(zip_entry_name,          arginfo_zip_entry_name)
     779             :         PHP_FE(zip_entry_compressedsize,                arginfo_zip_entry_compressedsize)
     780             :         PHP_FE(zip_entry_compressionmethod,             arginfo_zip_entry_compressionmethod)
     781             : #ifdef  PHP_FE_END
     782             :         PHP_FE_END
     783             : #else
     784             :         {NULL,NULL,NULL}
     785             : #endif
     786             : };
     787             : /* }}} */
     788             : 
     789             : /* {{{ ZE2 OO definitions */
     790             : static zend_class_entry *zip_class_entry;
     791             : static zend_object_handlers zip_object_handlers;
     792             : 
     793             : static HashTable zip_prop_handlers;
     794             : 
     795             : typedef int (*zip_read_int_t)(struct zip *za);
     796             : typedef char *(*zip_read_const_char_t)(struct zip *za, int *len);
     797             : typedef char *(*zip_read_const_char_from_ze_t)(ze_zip_object *obj);
     798             : 
     799             : typedef struct _zip_prop_handler {
     800             :         zip_read_int_t read_int_func;
     801             :         zip_read_const_char_t read_const_char_func;
     802             :         zip_read_const_char_from_ze_t read_const_char_from_obj_func;
     803             : 
     804             :         int type;
     805             : } zip_prop_handler;
     806             : /* }}} */
     807             : 
     808      130000 : static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype) /* {{{ */
     809             : {
     810             :         zip_prop_handler hnd;
     811             :         zend_string *str;
     812             :         zval tmp;
     813             : 
     814      130000 :         hnd.read_const_char_func = read_char_func;
     815      130000 :         hnd.read_int_func = read_int_func;
     816      130000 :         hnd.read_const_char_from_obj_func = read_char_from_obj_func;
     817      130000 :         hnd.type = rettype;
     818      130000 :         str = zend_string_init_interned(name, strlen(name), 1);
     819             :         zend_hash_add_mem(prop_handler, str, &hnd, sizeof(zip_prop_handler));
     820             : 
     821             :         /* Register for reflection */
     822      130000 :         ZVAL_NULL(&tmp);
     823      130000 :         zend_declare_property_ex(zip_class_entry, str, &tmp, ZEND_ACC_PUBLIC, NULL);
     824             :         zend_string_release_ex(str, 1);
     825      130000 : }
     826             : /* }}} */
     827             : 
     828         126 : static zval *php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zval *rv) /* {{{ */
     829             : {
     830         126 :         const char *retchar = NULL;
     831         126 :         int retint = 0;
     832         126 :         int len = 0;
     833             : 
     834         126 :         if (obj && obj->za != NULL) {
     835         114 :                 if (hnd->read_const_char_func) {
     836           6 :                         retchar = hnd->read_const_char_func(obj->za, &len);
     837             :                 } else {
     838         108 :                         if (hnd->read_int_func) {
     839         102 :                                 retint = hnd->read_int_func(obj->za);
     840         102 :                                 if (retint == -1) {
     841           0 :                                         php_error_docref(NULL, E_WARNING, "Internal zip error returned");
     842           0 :                                         return NULL;
     843             :                                 }
     844             :                         } else {
     845           6 :                                 if (hnd->read_const_char_from_obj_func) {
     846           6 :                                         retchar = hnd->read_const_char_from_obj_func(obj);
     847           6 :                                         len = strlen(retchar);
     848             :                                 }
     849             :                         }
     850             :                 }
     851             :         }
     852             : 
     853         126 :         switch (hnd->type) {
     854          16 :                 case IS_STRING:
     855          16 :                         if (retchar) {
     856          24 :                                 ZVAL_STRINGL(rv, (char *) retchar, len);
     857             :                         } else {
     858           4 :                                 ZVAL_EMPTY_STRING(rv);
     859             :                         }
     860          16 :                         break;
     861             :                 /* case IS_TRUE */
     862           0 :                 case IS_FALSE:
     863           0 :                         ZVAL_BOOL(rv, (long)retint);
     864           0 :                         break;
     865         110 :                 case IS_LONG:
     866         110 :                         ZVAL_LONG(rv, (long)retint);
     867         110 :                         break;
     868           0 :                 default:
     869           0 :                         ZVAL_NULL(rv);
     870             :         }
     871             : 
     872         126 :         return rv;
     873             : }
     874             : /* }}} */
     875             : 
     876           3 : static zval *php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) /* {{{ */
     877             : {
     878             :         ze_zip_object *obj;
     879             :         zval tmp_member;
     880           3 :         zval *retval = NULL;
     881           3 :         zip_prop_handler *hnd = NULL;
     882             : 
     883           3 :         if (Z_TYPE_P(member) != IS_STRING) {
     884           0 :                 ZVAL_STR(&tmp_member, zval_get_string_func(member));
     885           0 :                 member = &tmp_member;
     886           0 :                 cache_slot = NULL;
     887             :         }
     888             : 
     889           3 :         obj = Z_ZIP_P(object);
     890             : 
     891           3 :         if (obj->prop_handler != NULL) {
     892           6 :                 hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
     893             :         }
     894             : 
     895           3 :         if (hnd == NULL) {
     896           3 :                 retval = zend_std_get_property_ptr_ptr(object, member, type, cache_slot);
     897             :         }
     898             : 
     899           3 :         if (member == &tmp_member) {
     900             :                 zval_ptr_dtor_str(&tmp_member);
     901             :         }
     902             : 
     903           3 :         return retval;
     904             : }
     905             : /* }}} */
     906             : 
     907          98 : static zval *php_zip_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */
     908             : {
     909             :         ze_zip_object *obj;
     910             :         zval tmp_member;
     911          98 :         zval *retval = NULL;
     912          98 :         zip_prop_handler *hnd = NULL;
     913             : 
     914          98 :         if (Z_TYPE_P(member) != IS_STRING) {
     915           0 :                 ZVAL_STR(&tmp_member, zval_get_string_func(member));
     916           0 :                 member = &tmp_member;
     917           0 :                 cache_slot = NULL;
     918             :         }
     919             : 
     920          98 :         obj = Z_ZIP_P(object);
     921             : 
     922          98 :         if (obj->prop_handler != NULL) {
     923         196 :                 hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
     924             :         }
     925             : 
     926          98 :         if (hnd != NULL) {
     927          94 :                 retval = php_zip_property_reader(obj, hnd, rv);
     928          94 :                 if (retval == NULL) {
     929           0 :                         retval = &EG(uninitialized_zval);
     930             :                 }
     931             :         } else {
     932           4 :                 retval = zend_std_read_property(object, member, type, cache_slot, rv);
     933             :         }
     934             : 
     935          98 :         if (member == &tmp_member) {
     936             :                 zval_ptr_dtor_str(&tmp_member);
     937             :         }
     938             : 
     939          98 :         return retval;
     940             : }
     941             : /* }}} */
     942             : 
     943          14 : static int php_zip_has_property(zval *object, zval *member, int type, void **cache_slot) /* {{{ */
     944             : {
     945             :         ze_zip_object *obj;
     946             :         zval tmp_member;
     947          14 :         zip_prop_handler *hnd = NULL;
     948          14 :         int retval = 0;
     949             : 
     950          14 :         if (Z_TYPE_P(member) != IS_STRING) {
     951           0 :                 ZVAL_STR(&tmp_member, zval_get_string_func(member));
     952           0 :                 member = &tmp_member;
     953           0 :                 cache_slot = NULL;
     954             :         }
     955             : 
     956          14 :         obj = Z_ZIP_P(object);
     957             : 
     958          14 :         if (obj->prop_handler != NULL) {
     959          28 :                 hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
     960             :         }
     961             : 
     962          14 :         if (hnd != NULL) {
     963             :                 zval tmp, *prop;
     964             : 
     965          12 :                 if (type == 2) {
     966           0 :                         retval = 1;
     967          12 :                 } else if ((prop = php_zip_property_reader(obj, hnd, &tmp)) != NULL) {
     968          12 :                         if (type == 1) {
     969           6 :                                 retval = zend_is_true(&tmp);
     970           6 :                         } else if (type == 0) {
     971           6 :                                 retval = (Z_TYPE(tmp) != IS_NULL);
     972             :                         }
     973             :                 }
     974             : 
     975          12 :                 zval_ptr_dtor(&tmp);
     976             :         } else {
     977           2 :                 retval = zend_std_has_property(object, member, type, cache_slot);
     978             :         }
     979             : 
     980          14 :         if (member == &tmp_member) {
     981             :                 zval_ptr_dtor_str(&tmp_member);
     982             :         }
     983             : 
     984          14 :         return retval;
     985             : }
     986             : /* }}} */
     987             : 
     988           0 : static HashTable *php_zip_get_gc(zval *object, zval **gc_data, int *gc_data_count) /* {{{ */
     989             : {
     990           0 :         *gc_data = NULL;
     991           0 :         *gc_data_count = 0;
     992           0 :         return zend_std_get_properties(object);
     993             : }
     994             : /* }}} */
     995             : 
     996           4 : static HashTable *php_zip_get_properties(zval *object)/* {{{ */
     997             : {
     998             :         ze_zip_object *obj;
     999             :         HashTable *props;
    1000             :         zip_prop_handler *hnd;
    1001             :         zend_string *key;
    1002             : 
    1003           4 :         obj = Z_ZIP_P(object);
    1004           4 :         props = zend_std_get_properties(object);
    1005             : 
    1006           4 :         if (obj->prop_handler == NULL) {
    1007           0 :                 return NULL;
    1008             :         }
    1009             : 
    1010          44 :         ZEND_HASH_FOREACH_STR_KEY_PTR(obj->prop_handler, key, hnd) {
    1011             :                 zval *ret, val;
    1012          20 :                 ret = php_zip_property_reader(obj, hnd, &val);
    1013          20 :                 if (ret == NULL) {
    1014           0 :                         ret = &EG(uninitialized_zval);
    1015             :                 }
    1016          20 :                 zend_hash_update(props, key, ret);
    1017             :         } ZEND_HASH_FOREACH_END();
    1018             : 
    1019           4 :         return props;
    1020             : }
    1021             : /* }}} */
    1022             : 
    1023          64 : static void php_zip_object_free_storage(zend_object *object) /* {{{ */
    1024             : {
    1025          64 :         ze_zip_object * intern = php_zip_fetch_object(object);
    1026             :         int i;
    1027             : 
    1028          64 :         if (!intern) {
    1029           0 :                 return;
    1030             :         }
    1031          64 :         if (intern->za) {
    1032          15 :                 if (zip_close(intern->za) != 0) {
    1033             : #if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
    1034             :                         php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", "zip_close have failed");
    1035             : #else
    1036           1 :                         php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(intern->za));
    1037           1 :                         zip_discard(intern->za);
    1038             : #endif
    1039             :                 }
    1040             :         }
    1041             : 
    1042          64 :         if (intern->buffers_cnt>0) {
    1043          59 :                 for (i=0; i<intern->buffers_cnt; i++) {
    1044          39 :                         efree(intern->buffers[i]);
    1045             :                 }
    1046          20 :                 efree(intern->buffers);
    1047             :         }
    1048             : 
    1049          64 :         intern->za = NULL;
    1050          64 :         zend_object_std_dtor(&intern->zo);
    1051             : 
    1052          64 :         if (intern->filename) {
    1053          15 :                 efree(intern->filename);
    1054             :         }
    1055             : }
    1056             : /* }}} */
    1057             : 
    1058          64 : static zend_object *php_zip_object_new(zend_class_entry *class_type) /* {{{ */
    1059             : {
    1060             :         ze_zip_object *intern;
    1061             : 
    1062          64 :         intern = zend_object_alloc(sizeof(ze_zip_object), class_type);
    1063          64 :         intern->prop_handler = &zip_prop_handlers;
    1064          64 :         zend_object_std_init(&intern->zo, class_type);
    1065          64 :         object_properties_init(&intern->zo, class_type);
    1066          64 :         intern->zo.handlers = &zip_object_handlers;
    1067             : 
    1068          64 :         return &intern->zo;
    1069             : }
    1070             : /* }}} */
    1071             : 
    1072             : /* {{{ Resource dtors */
    1073             : 
    1074             : /* {{{ php_zip_free_dir */
    1075          13 : static void php_zip_free_dir(zend_resource *rsrc)
    1076             : {
    1077          13 :         zip_rsrc * zip_int = (zip_rsrc *) rsrc->ptr;
    1078             : 
    1079          13 :         if (zip_int) {
    1080          13 :                 if (zip_int->za) {
    1081          13 :                         if (zip_close(zip_int->za) != 0) {
    1082           0 :                                 php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context");
    1083             :                         }
    1084          13 :                         zip_int->za = NULL;
    1085             :                 }
    1086             : 
    1087          13 :                 efree(rsrc->ptr);
    1088             : 
    1089          13 :                 rsrc->ptr = NULL;
    1090             :         }
    1091          13 : }
    1092             : /* }}} */
    1093             : 
    1094             : /* {{{ php_zip_free_entry */
    1095          31 : static void php_zip_free_entry(zend_resource *rsrc)
    1096             : {
    1097          31 :         zip_read_rsrc *zr_rsrc = (zip_read_rsrc *) rsrc->ptr;
    1098             : 
    1099          31 :         if (zr_rsrc) {
    1100          31 :                 if (zr_rsrc->zf) {
    1101          31 :                         zip_fclose(zr_rsrc->zf);
    1102          31 :                         zr_rsrc->zf = NULL;
    1103             :                 }
    1104          31 :                 efree(zr_rsrc);
    1105          31 :                 rsrc->ptr = NULL;
    1106             :         }
    1107          31 : }
    1108             : /* }}} */
    1109             : 
    1110             : /* }}}*/
    1111             : 
    1112             : /* reset macro */
    1113             : 
    1114             : /* {{{ function prototypes */
    1115             : static PHP_MINIT_FUNCTION(zip);
    1116             : static PHP_MSHUTDOWN_FUNCTION(zip);
    1117             : static PHP_MINFO_FUNCTION(zip);
    1118             : /* }}} */
    1119             : 
    1120             : /* {{{ zip_module_entry
    1121             :  */
    1122             : zend_module_entry zip_module_entry = {
    1123             :         STANDARD_MODULE_HEADER,
    1124             :         "zip",
    1125             :         zip_functions,
    1126             :         PHP_MINIT(zip),
    1127             :         PHP_MSHUTDOWN(zip),
    1128             :         NULL,
    1129             :         NULL,
    1130             :         PHP_MINFO(zip),
    1131             :         PHP_ZIP_VERSION,
    1132             :         STANDARD_MODULE_PROPERTIES
    1133             : };
    1134             : /* }}} */
    1135             : 
    1136             : #ifdef COMPILE_DL_ZIP
    1137             : ZEND_GET_MODULE(zip)
    1138             : #endif
    1139             : /* set macro */
    1140             : 
    1141             : /* {{{ proto resource zip_open(string filename)
    1142             : Create new zip using source uri for output */
    1143          16 : static PHP_NAMED_FUNCTION(zif_zip_open)
    1144             : {
    1145             :         char resolved_path[MAXPATHLEN + 1];
    1146             :         zip_rsrc *rsrc_int;
    1147          16 :         int err = 0;
    1148             :         zend_string *filename;
    1149             : 
    1150          16 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) {
    1151           1 :                 return;
    1152             :         }
    1153             : 
    1154          15 :         if (ZSTR_LEN(filename) == 0) {
    1155           1 :                 php_error_docref(NULL, E_WARNING, "Empty string as source");
    1156           1 :                 RETURN_FALSE;
    1157             :         }
    1158             : 
    1159          14 :         if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) {
    1160           0 :                 RETURN_FALSE;
    1161             :         }
    1162             : 
    1163          14 :         if(!expand_filepath(ZSTR_VAL(filename), resolved_path)) {
    1164           0 :                 RETURN_FALSE;
    1165             :         }
    1166             : 
    1167          14 :         rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc));
    1168             : 
    1169          14 :         rsrc_int->za = zip_open(resolved_path, 0, &err);
    1170          14 :         if (rsrc_int->za == NULL) {
    1171           1 :                 efree(rsrc_int);
    1172           1 :                 RETURN_LONG((zend_long)err);
    1173             :         }
    1174             : 
    1175          13 :         rsrc_int->index_current = 0;
    1176          13 :         rsrc_int->num_files = zip_get_num_files(rsrc_int->za);
    1177             : 
    1178          13 :         RETURN_RES(zend_register_resource(rsrc_int, le_zip_dir));
    1179             : }
    1180             : /* }}} */
    1181             : 
    1182             : /* {{{ proto void zip_close(resource zip)
    1183             :    Close a Zip archive */
    1184          12 : static PHP_NAMED_FUNCTION(zif_zip_close)
    1185             : {
    1186             :         zval * zip;
    1187          12 :         zip_rsrc *z_rsrc = NULL;
    1188             : 
    1189          12 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip) == FAILURE) {
    1190           1 :                 return;
    1191             :         }
    1192             : 
    1193          12 :         if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) {
    1194           1 :                 RETURN_FALSE;
    1195             :         }
    1196             : 
    1197             :         /* really close the zip will break BC :-D */
    1198          11 :         zend_list_close(Z_RES_P(zip));
    1199             : }
    1200             : /* }}} */
    1201             : 
    1202             : /* {{{ proto resource zip_read(resource zip)
    1203             :    Returns the next file in the archive */
    1204          37 : static PHP_NAMED_FUNCTION(zif_zip_read)
    1205             : {
    1206             :         zval *zip_dp;
    1207             :         zip_read_rsrc *zr_rsrc;
    1208             :         int ret;
    1209             :         zip_rsrc *rsrc_int;
    1210             : 
    1211          37 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_dp) == FAILURE) {
    1212           0 :                 return;
    1213             :         }
    1214             : 
    1215          37 :         if ((rsrc_int = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip_dp), le_zip_dir_name, le_zip_dir)) == NULL) {
    1216           0 :                 RETURN_FALSE;
    1217             :         }
    1218             : 
    1219          37 :         if (rsrc_int && rsrc_int->za) {
    1220          37 :                 if (rsrc_int->index_current >= rsrc_int->num_files) {
    1221           6 :                         RETURN_FALSE;
    1222             :                 }
    1223             : 
    1224          31 :                 zr_rsrc = emalloc(sizeof(zip_read_rsrc));
    1225             : 
    1226          31 :                 ret = zip_stat_index(rsrc_int->za, rsrc_int->index_current, 0, &zr_rsrc->sb);
    1227             : 
    1228          31 :                 if (ret != 0) {
    1229           0 :                         efree(zr_rsrc);
    1230           0 :                         RETURN_FALSE;
    1231             :                 }
    1232             : 
    1233          31 :                 zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0);
    1234          31 :                 if (zr_rsrc->zf) {
    1235          31 :                         rsrc_int->index_current++;
    1236          31 :                         RETURN_RES(zend_register_resource(zr_rsrc, le_zip_entry));
    1237             :                 } else {
    1238           0 :                         efree(zr_rsrc);
    1239           0 :                         RETURN_FALSE;
    1240             :                 }
    1241             : 
    1242             :         } else {
    1243           0 :                 RETURN_FALSE;
    1244             :         }
    1245             : }
    1246             : /* }}} */
    1247             : 
    1248             : /* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
    1249             :    Open a Zip File, pointed by the resource entry */
    1250             : /* Dummy function to follow the old API */
    1251           3 : static PHP_NAMED_FUNCTION(zif_zip_entry_open)
    1252             : {
    1253             :         zval * zip;
    1254             :         zval * zip_entry;
    1255           3 :         char *mode = NULL;
    1256           3 :         size_t mode_len = 0;
    1257             :         zip_read_rsrc * zr_rsrc;
    1258             :         zip_rsrc *z_rsrc;
    1259             : 
    1260           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|s", &zip, &zip_entry, &mode, &mode_len) == FAILURE) {
    1261           0 :                 return;
    1262             :         }
    1263             : 
    1264           3 :         if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
    1265           0 :                 RETURN_FALSE;
    1266             :         }
    1267             : 
    1268           3 :         if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) {
    1269           0 :                 RETURN_FALSE;
    1270             :         }
    1271             : 
    1272           3 :         if (zr_rsrc->zf != NULL) {
    1273           3 :                 RETURN_TRUE;
    1274             :         } else {
    1275           0 :                 RETURN_FALSE;
    1276             :         }
    1277             : }
    1278             : /* }}} */
    1279             : 
    1280             : /* {{{ proto bool zip_entry_close(resource zip_ent)
    1281             :    Close a zip entry */
    1282           4 : static PHP_NAMED_FUNCTION(zif_zip_entry_close)
    1283             : {
    1284             :         zval * zip_entry;
    1285             :         zip_read_rsrc * zr_rsrc;
    1286             : 
    1287           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) {
    1288           0 :                 return;
    1289             :         }
    1290             : 
    1291           4 :         if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
    1292           1 :                 RETURN_FALSE;
    1293             :         }
    1294             : 
    1295           3 :         RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(zip_entry)));
    1296             : }
    1297             : /* }}} */
    1298             : 
    1299             : /* {{{ proto mixed zip_entry_read(resource zip_entry [, int len])
    1300             :    Read from an open directory entry */
    1301           2 : static PHP_NAMED_FUNCTION(zif_zip_entry_read)
    1302             : {
    1303             :         zval * zip_entry;
    1304           2 :         zend_long len = 0;
    1305             :         zip_read_rsrc * zr_rsrc;
    1306             :         zend_string *buffer;
    1307           2 :         int n = 0;
    1308             : 
    1309           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &zip_entry, &len) == FAILURE) {
    1310           0 :                 return;
    1311             :         }
    1312             : 
    1313           2 :         if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
    1314           0 :                 RETURN_FALSE;
    1315             :         }
    1316             : 
    1317           2 :         if (len <= 0) {
    1318           1 :                 len = 1024;
    1319             :         }
    1320             : 
    1321           2 :         if (zr_rsrc->zf) {
    1322           4 :                 buffer = zend_string_safe_alloc(1, len, 0, 0);
    1323           2 :                 n = zip_fread(zr_rsrc->zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer));
    1324           2 :                 if (n > 0) {
    1325           2 :                         ZSTR_VAL(buffer)[n] = '\0';
    1326           2 :                         ZSTR_LEN(buffer) = n;
    1327           2 :                         RETURN_NEW_STR(buffer);
    1328             :                 } else {
    1329             :                         zend_string_efree(buffer);
    1330           0 :                         RETURN_EMPTY_STRING()
    1331             :                 }
    1332             :         } else {
    1333           0 :                 RETURN_FALSE;
    1334             :         }
    1335             : }
    1336             : /* }}} */
    1337             : 
    1338          32 : static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ */
    1339             : {
    1340             :         zval * zip_entry;
    1341             :         zip_read_rsrc * zr_rsrc;
    1342             : 
    1343          32 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) {
    1344          32 :                 return;
    1345             :         }
    1346             : 
    1347          32 :         if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
    1348           0 :                 RETURN_FALSE;
    1349             :         }
    1350             : 
    1351          32 :         if (!zr_rsrc->zf) {
    1352           0 :                 RETURN_FALSE;
    1353             :         }
    1354             : 
    1355          32 :         switch (opt) {
    1356          11 :                 case 0:
    1357          22 :                         RETURN_STRING((char *)zr_rsrc->sb.name);
    1358             :                         break;
    1359           4 :                 case 1:
    1360           4 :                         RETURN_LONG((zend_long) (zr_rsrc->sb.comp_size));
    1361             :                         break;
    1362           6 :                 case 2:
    1363           6 :                         RETURN_LONG((zend_long) (zr_rsrc->sb.size));
    1364             :                         break;
    1365          11 :                 case 3:
    1366          11 :                         switch (zr_rsrc->sb.comp_method) {
    1367           5 :                                 case 0:
    1368          10 :                                         RETURN_STRING("stored");
    1369             :                                         break;
    1370           0 :                                 case 1:
    1371           0 :                                         RETURN_STRING("shrunk");
    1372             :                                         break;
    1373           0 :                                 case 2:
    1374             :                                 case 3:
    1375             :                                 case 4:
    1376             :                                 case 5:
    1377           0 :                                         RETURN_STRING("reduced");
    1378             :                                         break;
    1379           0 :                                 case 6:
    1380           0 :                                         RETURN_STRING("imploded");
    1381             :                                         break;
    1382           0 :                                 case 7:
    1383           0 :                                         RETURN_STRING("tokenized");
    1384             :                                         break;
    1385           6 :                                 case 8:
    1386          12 :                                         RETURN_STRING("deflated");
    1387             :                                         break;
    1388           0 :                                 case 9:
    1389           0 :                                         RETURN_STRING("deflatedX");
    1390             :                                         break;
    1391           0 :                                 case 10:
    1392           0 :                                         RETURN_STRING("implodedX");
    1393             :                                         break;
    1394           0 :                                 default:
    1395           0 :                                         RETURN_FALSE;
    1396             :                         }
    1397             :                         RETURN_LONG((zend_long) (zr_rsrc->sb.comp_method));
    1398             :                         break;
    1399             :         }
    1400             : 
    1401             : }
    1402             : /* }}} */
    1403             : 
    1404             : /* {{{ proto string zip_entry_name(resource zip_entry)
    1405             :    Return the name given a ZZip entry */
    1406          11 : static PHP_NAMED_FUNCTION(zif_zip_entry_name)
    1407             : {
    1408          11 :         php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    1409          11 : }
    1410             : /* }}} */
    1411             : 
    1412             : /* {{{ proto int zip_entry_compressedsize(resource zip_entry)
    1413             :    Return the compressed size of a ZZip entry */
    1414           4 : static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize)
    1415             : {
    1416           4 :         php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1417           4 : }
    1418             : /* }}} */
    1419             : 
    1420             : /* {{{ proto int zip_entry_filesize(resource zip_entry)
    1421             :    Return the actual filesize of a ZZip entry */
    1422           6 : static PHP_NAMED_FUNCTION(zif_zip_entry_filesize)
    1423             : {
    1424           6 :         php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
    1425           6 : }
    1426             : /* }}} */
    1427             : 
    1428             : /* {{{ proto string zip_entry_compressionmethod(resource zip_entry)
    1429             :    Return a string containing the compression method used on a particular entry */
    1430          11 : static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod)
    1431             : {
    1432          11 :         php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
    1433          11 : }
    1434             : /* }}} */
    1435             : 
    1436             : /* {{{ proto mixed ZipArchive::open(string source [, int flags])
    1437             : Create new zip using source uri for output, return TRUE on success or the error code */
    1438          71 : static ZIPARCHIVE_METHOD(open)
    1439             : {
    1440             :         struct zip *intern;
    1441          71 :         int err = 0;
    1442          71 :         zend_long flags = 0;
    1443             :         char *resolved_path;
    1444             :         zend_string *filename;
    1445         142 :         zval *self = getThis();
    1446          71 :         ze_zip_object *ze_obj = NULL;
    1447             : 
    1448          71 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &filename, &flags) == FAILURE) {
    1449           0 :                 return;
    1450             :         }
    1451             : 
    1452          71 :         if (self) {
    1453             :                 /* We do not use ZIP_FROM_OBJECT, zip init function here */
    1454          71 :                 ze_obj = Z_ZIP_P(self);
    1455             :         }
    1456             : 
    1457          71 :         if (ZSTR_LEN(filename) == 0) {
    1458           1 :                 php_error_docref(NULL, E_WARNING, "Empty string as source");
    1459           1 :                 RETURN_FALSE;
    1460             :         }
    1461             : 
    1462          70 :         if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) {
    1463           0 :                 RETURN_FALSE;
    1464             :         }
    1465             : 
    1466          70 :         if (!(resolved_path = expand_filepath(ZSTR_VAL(filename), NULL))) {
    1467           0 :                 RETURN_FALSE;
    1468             :         }
    1469             : 
    1470          70 :         if (ze_obj->za) {
    1471             :                 /* we already have an opened zip, free it */
    1472           0 :                 if (zip_close(ze_obj->za) != 0) {
    1473           0 :                         php_error_docref(NULL, E_WARNING, "Empty string as source");
    1474           0 :                         efree(resolved_path);
    1475           0 :                         RETURN_FALSE;
    1476             :                 }
    1477           0 :                 ze_obj->za = NULL;
    1478             :         }
    1479          70 :         if (ze_obj->filename) {
    1480           0 :                 efree(ze_obj->filename);
    1481           0 :                 ze_obj->filename = NULL;
    1482             :         }
    1483             : 
    1484             : #if LIBZIP_VERSION_MAJOR > 1 || LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR >= 6
    1485             :         /* reduce BC break introduce in libzip 1.6.0
    1486             :            "Do not accept empty files as valid zip archives any longer" */
    1487             : 
    1488             :         /* open for write without option to empty the archive */
    1489             :         if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) {
    1490             :                 zend_stat_t st;
    1491             : 
    1492             :                 /* exists and is empty */
    1493             :                 if (VCWD_STAT(resolved_path, &st) == 0 && st.st_size == 0) {
    1494             :                         flags |= ZIP_TRUNCATE;
    1495             :                 }
    1496             :         }
    1497             : #endif
    1498             : 
    1499          70 :         intern = zip_open(resolved_path, flags, &err);
    1500          70 :         if (!intern || err) {
    1501           2 :                 efree(resolved_path);
    1502           2 :                 RETURN_LONG((zend_long)err);
    1503             :         }
    1504          68 :         ze_obj->filename = resolved_path;
    1505          68 :         ze_obj->filename_len = strlen(resolved_path);
    1506          68 :         ze_obj->za = intern;
    1507          68 :         RETURN_TRUE;
    1508             : }
    1509             : /* }}} */
    1510             : 
    1511             : /* {{{ proto resource ZipArchive::setPassword(string password)
    1512             : Set the password for the active archive */
    1513           1 : static ZIPARCHIVE_METHOD(setPassword)
    1514             : {
    1515             :         struct zip *intern;
    1516           2 :         zval *self = getThis();
    1517             :         char *password;
    1518             :         size_t  password_len;
    1519             : 
    1520           1 :         if (!self) {
    1521           0 :                 RETURN_FALSE;
    1522             :         }
    1523             : 
    1524           1 :         ZIP_FROM_OBJECT(intern, self);
    1525             : 
    1526           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &password, &password_len) == FAILURE) {
    1527           0 :                 return;
    1528             :         }
    1529             : 
    1530           1 :         if (password_len < 1) {
    1531           0 :                 RETURN_FALSE;
    1532             :         } else {
    1533           1 :                 int res = zip_set_default_password(intern, (const char *)password);
    1534           1 :                 if (res == 0) {
    1535           1 :                         RETURN_TRUE;
    1536             :                 } else {
    1537           0 :                         RETURN_FALSE;
    1538             :                 }
    1539             :         }
    1540             : }
    1541             : /* }}} */
    1542             : 
    1543             : /* {{{ proto bool ZipArchive::close()
    1544             : close the zip archive */
    1545          54 : static ZIPARCHIVE_METHOD(close)
    1546             : {
    1547             :         struct zip *intern;
    1548         108 :         zval *self = getThis();
    1549             :         ze_zip_object *ze_obj;
    1550             :         int err;
    1551             : 
    1552          54 :         if (!self) {
    1553           0 :                 RETURN_FALSE;
    1554             :         }
    1555             : 
    1556          54 :         ZIP_FROM_OBJECT(intern, self);
    1557             : 
    1558          53 :         ze_obj = Z_ZIP_P(self);
    1559             : 
    1560          53 :         if ((err = zip_close(intern))) {
    1561             : #if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
    1562             :                 php_error_docref(NULL, E_WARNING, "%s", "zip_close have failed");
    1563             : #else
    1564           1 :                 php_error_docref(NULL, E_WARNING, "%s", zip_strerror(intern));
    1565           1 :                 zip_discard(intern);
    1566             : #endif
    1567             :         }
    1568             : 
    1569          53 :         efree(ze_obj->filename);
    1570          53 :         ze_obj->filename = NULL;
    1571          53 :         ze_obj->filename_len = 0;
    1572          53 :         ze_obj->za = NULL;
    1573             : 
    1574          53 :         if (!err) {
    1575          52 :                 RETURN_TRUE;
    1576             :         } else {
    1577           1 :                 RETURN_FALSE;
    1578             :         }
    1579             : }
    1580             : /* }}} */
    1581             : 
    1582             : /* {{{ proto bool ZipArchive::count()
    1583             : close the zip archive */
    1584           2 : static ZIPARCHIVE_METHOD(count)
    1585             : {
    1586             :         struct zip *intern;
    1587           4 :         zval *self = getThis();
    1588             : 
    1589           2 :         if (!self) {
    1590           0 :                 RETURN_FALSE;
    1591             :         }
    1592             : 
    1593           2 :         ZIP_FROM_OBJECT(intern, self);
    1594             : 
    1595           2 :         RETVAL_LONG(zip_get_num_files(intern));
    1596             : }
    1597             : /* }}} */
    1598             : 
    1599             : /* {{{ proto string ZipArchive::getStatusString()
    1600             :  * Returns the status error message, system and/or zip messages */
    1601           2 : static ZIPARCHIVE_METHOD(getStatusString)
    1602             : {
    1603             :         struct zip *intern;
    1604           4 :         zval *self = getThis();
    1605             : #if LIBZIP_VERSION_MAJOR < 1
    1606             :         int zep, syp, len;
    1607             :         char error_string[128];
    1608             : #else
    1609             :         zip_error_t *err;
    1610             : #endif
    1611             : 
    1612           2 :         if (!self) {
    1613           0 :                 RETURN_FALSE;
    1614             :         }
    1615             : 
    1616           2 :         ZIP_FROM_OBJECT(intern, self);
    1617             : 
    1618             : #if LIBZIP_VERSION_MAJOR < 1
    1619             :         zip_error_get(intern, &zep, &syp);
    1620             : 
    1621             :         len = zip_error_to_str(error_string, 128, zep, syp);
    1622             :         RETVAL_STRINGL(error_string, len);
    1623             : #else
    1624           2 :         err = zip_get_error(intern);
    1625           4 :         RETVAL_STRING(zip_error_strerror(err));
    1626           2 :         zip_error_fini(err);
    1627             : #endif
    1628             : }
    1629             : /* }}} */
    1630             : 
    1631             : /* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
    1632             : Returns the index of the entry named filename in the archive */
    1633           5 : static ZIPARCHIVE_METHOD(addEmptyDir)
    1634             : {
    1635             :         struct zip *intern;
    1636          10 :         zval *self = getThis();
    1637             :         char *dirname;
    1638             :         size_t   dirname_len;
    1639             :         int idx;
    1640             :         struct zip_stat sb;
    1641             :         char *s;
    1642             : 
    1643           5 :         if (!self) {
    1644           0 :                 RETURN_FALSE;
    1645             :         }
    1646             : 
    1647           5 :         ZIP_FROM_OBJECT(intern, self);
    1648             : 
    1649           5 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
    1650             :                                 &dirname, &dirname_len) == FAILURE) {
    1651           0 :                 return;
    1652             :         }
    1653             : 
    1654           5 :         if (dirname_len<1) {
    1655           0 :                 RETURN_FALSE;
    1656             :         }
    1657             : 
    1658           5 :         if (dirname[dirname_len-1] != '/') {
    1659           4 :                 s=(char *)safe_emalloc(dirname_len, 1, 2);
    1660           4 :                 strcpy(s, dirname);
    1661           4 :                 s[dirname_len] = '/';
    1662           4 :                 s[dirname_len+1] = '\0';
    1663             :         } else {
    1664           1 :                 s = dirname;
    1665             :         }
    1666             : 
    1667           5 :         idx = zip_stat(intern, s, 0, &sb);
    1668           5 :         if (idx >= 0) {
    1669           1 :                 RETVAL_FALSE;
    1670             :         } else {
    1671           4 :                 if (zip_add_dir(intern, (const char *)s) == -1) {
    1672           0 :                         RETVAL_FALSE;
    1673             :                 }
    1674           4 :                 zip_error_clear(intern);
    1675           4 :                 RETVAL_TRUE;
    1676             :         }
    1677             : 
    1678           5 :         if (s != dirname) {
    1679           4 :                 efree(s);
    1680             :         }
    1681             : }
    1682             : /* }}} */
    1683             : 
    1684           4 : static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
    1685             : {
    1686             :         struct zip *intern;
    1687           8 :         zval *self = getThis();
    1688           4 :         char *path = ".";
    1689           4 :         char *remove_path = NULL, *save_remove_path;
    1690           4 :         char *add_path = NULL;
    1691           4 :         size_t  add_path_len, remove_path_len = 0, path_len = 1;
    1692           4 :         zend_long remove_all_path = 0;
    1693           4 :         zend_long flags = 0;
    1694           4 :         zval *options = NULL;
    1695             :         int found;
    1696             :         zend_string *pattern;
    1697             : 
    1698           4 :         if (!self) {
    1699           0 :                 RETURN_FALSE;
    1700             :         }
    1701             : 
    1702           4 :         ZIP_FROM_OBJECT(intern, self);
    1703             :         /* 1 == glob, 2 == pcre */
    1704           4 :         if (type == 1) {
    1705           3 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|la",
    1706             :                                         &pattern, &flags, &options) == FAILURE) {
    1707           0 :                         return;
    1708             :                 }
    1709             :         } else {
    1710           1 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sa",
    1711             :                                         &pattern, &path, &path_len, &options) == FAILURE) {
    1712           0 :                         return;
    1713             :                 }
    1714             :         }
    1715             : 
    1716           4 :         if (ZSTR_LEN(pattern) == 0) {
    1717           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as pattern");
    1718           0 :                 RETURN_FALSE;
    1719             :         }
    1720           4 :         if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
    1721             :                         &add_path, &add_path_len) < 0)) {
    1722           0 :                 RETURN_FALSE;
    1723             :         }
    1724             : 
    1725           4 :         save_remove_path = remove_path;
    1726           4 :         if (remove_path && remove_path_len > 1) {
    1727           2 :                 size_t real_len = strlen(remove_path);
    1728           2 :                 if ((real_len > 1) && ((remove_path[real_len - 1] == '/') || (remove_path[real_len - 1] == '\\'))) {
    1729           1 :                         remove_path = estrndup(remove_path, real_len - 1);
    1730             :                 }
    1731             :         }
    1732             : 
    1733           4 :         if (type == 1) {
    1734           3 :                 found = php_zip_glob(ZSTR_VAL(pattern), ZSTR_LEN(pattern), flags, return_value);
    1735             :         } else {
    1736           1 :                 found = php_zip_pcre(pattern, path, path_len, return_value);
    1737             :         }
    1738             : 
    1739           4 :         if (found > 0) {
    1740             :                 int i;
    1741             :                 zval *zval_file;
    1742             : 
    1743         348 :                 for (i = 0; i < found; i++) {
    1744             :                         char *file_stripped, *entry_name;
    1745             :                         size_t entry_name_len, file_stripped_len;
    1746             :                         char entry_name_buf[MAXPATHLEN];
    1747         170 :                         zend_string *basename = NULL;
    1748             : 
    1749         170 :                         if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(return_value), i)) != NULL) {
    1750           6 :                                 if (remove_all_path) {
    1751           3 :                                         basename = php_basename(Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), NULL, 0);
    1752           3 :                                         file_stripped = ZSTR_VAL(basename);
    1753           3 :                                         file_stripped_len = ZSTR_LEN(basename);
    1754           3 :                                 } else if (remove_path && strstr(Z_STRVAL_P(zval_file), remove_path) != NULL) {
    1755           3 :                                         file_stripped = Z_STRVAL_P(zval_file) + remove_path_len + 1;
    1756           3 :                                         file_stripped_len = Z_STRLEN_P(zval_file) - remove_path_len - 1;
    1757             :                                 } else {
    1758           0 :                                         file_stripped = Z_STRVAL_P(zval_file);
    1759           0 :                                         file_stripped_len = Z_STRLEN_P(zval_file);
    1760             :                                 }
    1761             : 
    1762           6 :                                 if (add_path) {
    1763           4 :                                         if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
    1764           0 :                                                 php_error_docref(NULL, E_WARNING, "Entry name too long (max: %d, %zd given)",
    1765             :                                                 MAXPATHLEN - 1, (add_path_len + file_stripped_len));
    1766           0 :                                                 zend_array_destroy(Z_ARR_P(return_value));
    1767           0 :                                                 RETURN_FALSE;
    1768             :                                         }
    1769           4 :                                         snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
    1770             :                                 } else {
    1771           2 :                                         snprintf(entry_name_buf, MAXPATHLEN, "%s", file_stripped);
    1772             :                                 }
    1773             : 
    1774           6 :                                 entry_name = entry_name_buf;
    1775           6 :                                 entry_name_len = strlen(entry_name);
    1776           6 :                                 if (basename) {
    1777             :                                         zend_string_release_ex(basename, 0);
    1778           3 :                                         basename = NULL;
    1779             :                                 }
    1780             : 
    1781           6 :                                 if (php_zip_add_file(intern, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
    1782             :                                         entry_name, entry_name_len, 0, 0) < 0) {
    1783           0 :                                         zend_array_destroy(Z_ARR_P(return_value));
    1784           0 :                                         RETURN_FALSE;
    1785             :                                 }
    1786             :                         }
    1787             :                 }
    1788             :         }
    1789           4 :         if (remove_path != save_remove_path) {
    1790           1 :                 efree(remove_path);
    1791             :         }
    1792             : }
    1793             : /* }}} */
    1794             : 
    1795             : /* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]])
    1796             : Add files matching the glob pattern. See php's glob for the pattern syntax. */
    1797           3 : static ZIPARCHIVE_METHOD(addGlob)
    1798             : {
    1799           3 :         php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1800           3 : }
    1801             : /* }}} */
    1802             : 
    1803             : /* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]])
    1804             : Add files matching the pcre pattern. See php's pcre for the pattern syntax. */
    1805           1 : static ZIPARCHIVE_METHOD(addPattern)
    1806             : {
    1807           1 :         php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
    1808           1 : }
    1809             : /* }}} */
    1810             : 
    1811             : /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
    1812             : Add a file in a Zip archive using its path and the name to use. */
    1813           7 : static ZIPARCHIVE_METHOD(addFile)
    1814             : {
    1815             :         struct zip *intern;
    1816          14 :         zval *self = getThis();
    1817           7 :         char *entry_name = NULL;
    1818           7 :         size_t entry_name_len = 0;
    1819           7 :         zend_long offset_start = 0, offset_len = 0;
    1820             :         zend_string *filename;
    1821             : 
    1822           7 :         if (!self) {
    1823           0 :                 RETURN_FALSE;
    1824             :         }
    1825             : 
    1826           7 :         ZIP_FROM_OBJECT(intern, self);
    1827             : 
    1828           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sll",
    1829             :                         &filename, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
    1830           0 :                 return;
    1831             :         }
    1832             : 
    1833           7 :         if (ZSTR_LEN(filename) == 0) {
    1834           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as filename");
    1835           0 :                 RETURN_FALSE;
    1836             :         }
    1837             : 
    1838           7 :         if (entry_name_len == 0) {
    1839           2 :                 entry_name = ZSTR_VAL(filename);
    1840           2 :                 entry_name_len = ZSTR_LEN(filename);
    1841             :         }
    1842             : 
    1843           7 :         if (php_zip_add_file(intern, ZSTR_VAL(filename), ZSTR_LEN(filename),
    1844             :                         entry_name, entry_name_len, offset_start, offset_len) < 0) {
    1845           3 :                 RETURN_FALSE;
    1846             :         } else {
    1847           4 :                 RETURN_TRUE;
    1848             :         }
    1849             : }
    1850             : /* }}} */
    1851             : 
    1852             : /* {{{ proto bool ZipArchive::addFromString(string name, string content)
    1853             : Add a file using content and the entry name */
    1854          39 : static ZIPARCHIVE_METHOD(addFromString)
    1855             : {
    1856             :         struct zip *intern;
    1857          78 :         zval *self = getThis();
    1858             :         zend_string *buffer;
    1859             :         char *name;
    1860             :         size_t name_len;
    1861             :         ze_zip_object *ze_obj;
    1862             :         struct zip_source *zs;
    1863          39 :         int pos = 0;
    1864             :         int cur_idx;
    1865             : 
    1866          39 :         if (!self) {
    1867           0 :                 RETURN_FALSE;
    1868             :         }
    1869             : 
    1870          39 :         ZIP_FROM_OBJECT(intern, self);
    1871             : 
    1872          39 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS",
    1873             :                         &name, &name_len, &buffer) == FAILURE) {
    1874           0 :                 return;
    1875             :         }
    1876             : 
    1877          39 :         ze_obj = Z_ZIP_P(self);
    1878          39 :         if (ze_obj->buffers_cnt) {
    1879          19 :                 ze_obj->buffers = (char **)safe_erealloc(ze_obj->buffers, sizeof(char *), (ze_obj->buffers_cnt+1), 0);
    1880          19 :                 pos = ze_obj->buffers_cnt++;
    1881             :         } else {
    1882          20 :                 ze_obj->buffers = (char **)emalloc(sizeof(char *));
    1883          20 :                 ze_obj->buffers_cnt++;
    1884          20 :                 pos = 0;
    1885             :         }
    1886          39 :         ze_obj->buffers[pos] = (char *)safe_emalloc(ZSTR_LEN(buffer), 1, 1);
    1887          39 :         memcpy(ze_obj->buffers[pos], ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1);
    1888             : 
    1889          39 :         zs = zip_source_buffer(intern, ze_obj->buffers[pos], ZSTR_LEN(buffer), 0);
    1890             : 
    1891          39 :         if (zs == NULL) {
    1892           0 :                 RETURN_FALSE;
    1893             :         }
    1894             : 
    1895          39 :         cur_idx = zip_name_locate(intern, (const char *)name, 0);
    1896             :         /* TODO: fix  _zip_replace */
    1897          39 :         if (cur_idx >= 0) {
    1898           0 :                 if (zip_delete(intern, cur_idx) == -1) {
    1899           0 :                         zip_source_free(zs);
    1900           0 :                         RETURN_FALSE;
    1901             :                 }
    1902             :         }
    1903             : 
    1904          39 :         if (zip_add(intern, name, zs) == -1) {
    1905           0 :                 zip_source_free(zs);
    1906           0 :                 RETURN_FALSE;
    1907             :         } else {
    1908          39 :                 zip_error_clear(intern);
    1909          39 :                 RETURN_TRUE;
    1910             :         }
    1911             : }
    1912             : /* }}} */
    1913             : 
    1914             : /* {{{ proto array ZipArchive::statName(string filename[, int flags])
    1915             : Returns the information about a the zip entry filename */
    1916           7 : static ZIPARCHIVE_METHOD(statName)
    1917             : {
    1918             :         struct zip *intern;
    1919          14 :         zval *self = getThis();
    1920           7 :         zend_long flags = 0;
    1921             :         struct zip_stat sb;
    1922             :         zend_string *name;
    1923             : 
    1924           7 :         if (!self) {
    1925           1 :                 RETURN_FALSE;
    1926             :         }
    1927             : 
    1928           7 :         ZIP_FROM_OBJECT(intern, self);
    1929             : 
    1930           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) {
    1931           0 :                 return;
    1932             :         }
    1933             : 
    1934           7 :         PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(name), ZSTR_LEN(name), flags, sb);
    1935             : 
    1936           6 :         RETURN_SB(&sb);
    1937             : }
    1938             : /* }}} */
    1939             : 
    1940             : /* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
    1941             : Returns the zip entry informations using its index */
    1942          55 : static ZIPARCHIVE_METHOD(statIndex)
    1943             : {
    1944             :         struct zip *intern;
    1945         110 :         zval *self = getThis();
    1946          55 :         zend_long index, flags = 0;
    1947             : 
    1948             :         struct zip_stat sb;
    1949             : 
    1950          55 :         if (!self) {
    1951           3 :                 RETURN_FALSE;
    1952             :         }
    1953             : 
    1954          55 :         ZIP_FROM_OBJECT(intern, self);
    1955             : 
    1956          55 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
    1957             :                         &index, &flags) == FAILURE) {
    1958           0 :                 return;
    1959             :         }
    1960             : 
    1961          55 :         if (zip_stat_index(intern, index, flags, &sb) != 0) {
    1962           3 :                 RETURN_FALSE;
    1963             :         }
    1964          52 :         RETURN_SB(&sb);
    1965             : }
    1966             : /* }}} */
    1967             : 
    1968             : /* {{{ proto int ZipArchive::locateName(string filename[, int flags])
    1969             : Returns the index of the entry named filename in the archive */
    1970           8 : static ZIPARCHIVE_METHOD(locateName)
    1971             : {
    1972             :         struct zip *intern;
    1973          16 :         zval *self = getThis();
    1974           8 :         zend_long flags = 0;
    1975           8 :         zend_long idx = -1;
    1976             :         zend_string *name;
    1977             : 
    1978           8 :         if (!self) {
    1979           0 :                 RETURN_FALSE;
    1980             :         }
    1981             : 
    1982           8 :         ZIP_FROM_OBJECT(intern, self);
    1983             : 
    1984           8 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) {
    1985           0 :                 return;
    1986             :         }
    1987             : 
    1988           8 :         if (ZSTR_LEN(name) < 1) {
    1989           0 :                 RETURN_FALSE;
    1990             :         }
    1991             : 
    1992           8 :         idx = (zend_long)zip_name_locate(intern, (const char *)ZSTR_VAL(name), flags);
    1993             : 
    1994           8 :         if (idx >= 0) {
    1995           6 :                 RETURN_LONG(idx);
    1996             :         } else {
    1997           2 :                 RETURN_FALSE;
    1998             :         }
    1999             : }
    2000             : /* }}} */
    2001             : 
    2002             : /* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
    2003             : Returns the name of the file at position index */
    2004           6 : static ZIPARCHIVE_METHOD(getNameIndex)
    2005             : {
    2006             :         struct zip *intern;
    2007          12 :         zval *self = getThis();
    2008             :         const char *name;
    2009           6 :         zend_long flags = 0, index = 0;
    2010             : 
    2011           6 :         if (!self) {
    2012           1 :                 RETURN_FALSE;
    2013             :         }
    2014             : 
    2015           6 :         ZIP_FROM_OBJECT(intern, self);
    2016             : 
    2017           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
    2018             :                         &index, &flags) == FAILURE) {
    2019           0 :                 return;
    2020             :         }
    2021             : 
    2022           6 :         name = zip_get_name(intern, (int) index, flags);
    2023             : 
    2024           6 :         if (name) {
    2025          10 :                 RETVAL_STRING((char *)name);
    2026             :         } else {
    2027           1 :                 RETURN_FALSE;
    2028             :         }
    2029             : }
    2030             : /* }}} */
    2031             : 
    2032             : /* {{{ proto bool ZipArchive::setArchiveComment(string comment)
    2033             : Set or remove (NULL/'') the comment of the archive */
    2034           2 : static ZIPARCHIVE_METHOD(setArchiveComment)
    2035             : {
    2036             :         struct zip *intern;
    2037           4 :         zval *self = getThis();
    2038             :         size_t comment_len;
    2039             :         char * comment;
    2040             : 
    2041           2 :         if (!self) {
    2042           0 :                 RETURN_FALSE;
    2043             :         }
    2044             : 
    2045           2 :         ZIP_FROM_OBJECT(intern, self);
    2046             : 
    2047           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &comment, &comment_len) == FAILURE) {
    2048           0 :                 return;
    2049             :         }
    2050           2 :         if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
    2051           0 :                 RETURN_FALSE;
    2052             :         } else {
    2053           2 :                 RETURN_TRUE;
    2054             :         }
    2055             : }
    2056             : /* }}} */
    2057             : 
    2058             : /* {{{ proto string ZipArchive::getArchiveComment([int flags])
    2059             : Returns the comment of an entry using its index */
    2060           2 : static ZIPARCHIVE_METHOD(getArchiveComment)
    2061             : {
    2062             :         struct zip *intern;
    2063           4 :         zval *self = getThis();
    2064           2 :         zend_long flags = 0;
    2065             :         const char * comment;
    2066           2 :         int comment_len = 0;
    2067             : 
    2068           2 :         if (!self) {
    2069           0 :                 RETURN_FALSE;
    2070             :         }
    2071             : 
    2072           2 :         ZIP_FROM_OBJECT(intern, self);
    2073             : 
    2074           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
    2075           0 :                 return;
    2076             :         }
    2077             : 
    2078           2 :         comment = zip_get_archive_comment(intern, &comment_len, (int)flags);
    2079           2 :         if(comment==NULL) {
    2080           0 :                 RETURN_FALSE;
    2081             :         }
    2082           4 :         RETURN_STRINGL((char *)comment, (zend_long)comment_len);
    2083             : }
    2084             : /* }}} */
    2085             : 
    2086             : /* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
    2087             : Set or remove (NULL/'') the comment of an entry using its Name */
    2088           3 : static ZIPARCHIVE_METHOD(setCommentName)
    2089             : {
    2090             :         struct zip *intern;
    2091           6 :         zval *self = getThis();
    2092             :         size_t comment_len, name_len;
    2093             :         char * comment, *name;
    2094             :         int idx;
    2095             : 
    2096           3 :         if (!self) {
    2097           0 :                 RETURN_FALSE;
    2098             :         }
    2099             : 
    2100           3 :         ZIP_FROM_OBJECT(intern, self);
    2101             : 
    2102           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
    2103             :                         &name, &name_len, &comment, &comment_len) == FAILURE) {
    2104           0 :                 return;
    2105             :         }
    2106             : 
    2107           3 :         if (name_len < 1) {
    2108           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2109             :         }
    2110             : 
    2111           3 :         idx = zip_name_locate(intern, name, 0);
    2112           3 :         if (idx < 0) {
    2113           0 :                 RETURN_FALSE;
    2114             :         }
    2115           3 :         PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len);
    2116             : }
    2117             : /* }}} */
    2118             : 
    2119             : /* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
    2120             : Set or remove (NULL/'') the comment of an entry using its index */
    2121           2 : static ZIPARCHIVE_METHOD(setCommentIndex)
    2122             : {
    2123             :         struct zip *intern;
    2124           4 :         zval *self = getThis();
    2125             :         zend_long index;
    2126             :         size_t comment_len;
    2127             :         char * comment;
    2128             :         struct zip_stat sb;
    2129             : 
    2130           2 :         if (!self) {
    2131           0 :                 RETURN_FALSE;
    2132             :         }
    2133             : 
    2134           2 :         ZIP_FROM_OBJECT(intern, self);
    2135             : 
    2136           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
    2137             :                         &index, &comment, &comment_len) == FAILURE) {
    2138           0 :                 return;
    2139             :         }
    2140             : 
    2141           2 :         PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
    2142           2 :         PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
    2143             : }
    2144             : /* }}} */
    2145             : 
    2146             : /* those constants/functions are only available in libzip since 0.11.2 */
    2147             : #ifdef ZIP_OPSYS_DEFAULT
    2148             : 
    2149             : /* {{{ proto bool ZipArchive::setExternalAttributesName(string name, int opsys, int attr [, int flags])
    2150             : Set external attributes for file in zip, using its name */
    2151           2 : static ZIPARCHIVE_METHOD(setExternalAttributesName)
    2152             : {
    2153             :         struct zip *intern;
    2154           4 :         zval *self = getThis();
    2155             :         size_t name_len;
    2156             :         char *name;
    2157           2 :         zend_long flags=0, opsys, attr;
    2158             :         zip_int64_t idx;
    2159             : 
    2160           2 :         if (!self) {
    2161           0 :                 RETURN_FALSE;
    2162             :         }
    2163             : 
    2164           2 :         ZIP_FROM_OBJECT(intern, self);
    2165             : 
    2166           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|l",
    2167             :                         &name, &name_len, &opsys, &attr, &flags) == FAILURE) {
    2168           0 :                 return;
    2169             :         }
    2170             : 
    2171           2 :         if (name_len < 1) {
    2172           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2173             :         }
    2174             : 
    2175           2 :         idx = zip_name_locate(intern, name, 0);
    2176           2 :         if (idx < 0) {
    2177           0 :                 RETURN_FALSE;
    2178             :         }
    2179           4 :         if (zip_file_set_external_attributes(intern, idx, (zip_flags_t)flags,
    2180           2 :                         (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) {
    2181           0 :                 RETURN_FALSE;
    2182             :         }
    2183           2 :         RETURN_TRUE;
    2184             : }
    2185             : /* }}} */
    2186             : 
    2187             : /* {{{ proto bool ZipArchive::setExternalAttributesIndex(int index, int opsys, int attr [, int flags])
    2188             : Set external attributes for file in zip, using its index */
    2189           2 : static ZIPARCHIVE_METHOD(setExternalAttributesIndex)
    2190             : {
    2191             :         struct zip *intern;
    2192           4 :         zval *self = getThis();
    2193           2 :         zend_long index, flags=0, opsys, attr;
    2194             :         struct zip_stat sb;
    2195             : 
    2196           2 :         if (!self) {
    2197           0 :                 RETURN_FALSE;
    2198             :         }
    2199             : 
    2200           2 :         ZIP_FROM_OBJECT(intern, self);
    2201             : 
    2202           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll|l",
    2203             :                         &index, &opsys, &attr, &flags) == FAILURE) {
    2204           0 :                 return;
    2205             :         }
    2206             : 
    2207           2 :         PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
    2208           4 :         if (zip_file_set_external_attributes(intern, (zip_uint64_t)index,
    2209           2 :                         (zip_flags_t)flags, (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) {
    2210           0 :                 RETURN_FALSE;
    2211             :         }
    2212           2 :         RETURN_TRUE;
    2213             : }
    2214             : /* }}} */
    2215             : 
    2216             : /* {{{ proto bool ZipArchive::getExternalAttributesName(string name, int &opsys, int &attr [, int flags])
    2217             : Get external attributes for file in zip, using its name */
    2218           3 : static ZIPARCHIVE_METHOD(getExternalAttributesName)
    2219             : {
    2220             :         struct zip *intern;
    2221           6 :         zval *self = getThis(), *z_opsys, *z_attr;
    2222             :         size_t name_len;
    2223             :         char *name;
    2224           3 :         zend_long flags=0;
    2225             :         zip_uint8_t opsys;
    2226             :         zip_uint32_t attr;
    2227             :         zip_int64_t idx;
    2228             : 
    2229           3 :         if (!self) {
    2230           0 :                 RETURN_FALSE;
    2231             :         }
    2232             : 
    2233           3 :         ZIP_FROM_OBJECT(intern, self);
    2234             : 
    2235           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz/z/|l",
    2236             :                         &name, &name_len, &z_opsys, &z_attr, &flags) == FAILURE) {
    2237           0 :                 return;
    2238             :         }
    2239             : 
    2240           3 :         if (name_len < 1) {
    2241           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2242             :         }
    2243             : 
    2244           3 :         idx = zip_name_locate(intern, name, 0);
    2245           3 :         if (idx < 0) {
    2246           0 :                 RETURN_FALSE;
    2247             :         }
    2248           3 :         if (zip_file_get_external_attributes(intern, idx,
    2249             :                         (zip_flags_t)flags, &opsys, &attr) < 0) {
    2250           0 :                 RETURN_FALSE;
    2251             :         }
    2252           3 :         zval_ptr_dtor(z_opsys);
    2253           3 :         ZVAL_LONG(z_opsys, opsys);
    2254           3 :         zval_ptr_dtor(z_attr);
    2255           3 :         ZVAL_LONG(z_attr, attr);
    2256           3 :         RETURN_TRUE;
    2257             : }
    2258             : /* }}} */
    2259             : 
    2260             : /* {{{ proto bool ZipArchive::getExternalAttributesIndex(int index, int &opsys, int &attr [, int flags])
    2261             : Get external attributes for file in zip, using its index */
    2262           3 : static ZIPARCHIVE_METHOD(getExternalAttributesIndex)
    2263             : {
    2264             :         struct zip *intern;
    2265           6 :         zval *self = getThis(), *z_opsys, *z_attr;
    2266           3 :         zend_long index, flags=0;
    2267             :         zip_uint8_t opsys;
    2268             :         zip_uint32_t attr;
    2269             :         struct zip_stat sb;
    2270             : 
    2271           3 :         if (!self) {
    2272           0 :                 RETURN_FALSE;
    2273             :         }
    2274             : 
    2275           3 :         ZIP_FROM_OBJECT(intern, self);
    2276             : 
    2277           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz/z/|l",
    2278             :                         &index, &z_opsys, &z_attr, &flags) == FAILURE) {
    2279           0 :                 return;
    2280             :         }
    2281             : 
    2282           3 :         PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
    2283           3 :         if (zip_file_get_external_attributes(intern, (zip_uint64_t)index,
    2284             :                         (zip_flags_t)flags, &opsys, &attr) < 0) {
    2285           0 :                 RETURN_FALSE;
    2286             :         }
    2287           3 :         zval_ptr_dtor(z_opsys);
    2288           3 :         ZVAL_LONG(z_opsys, opsys);
    2289           3 :         zval_ptr_dtor(z_attr);
    2290           3 :         ZVAL_LONG(z_attr, attr);
    2291           3 :         RETURN_TRUE;
    2292             : }
    2293             : /* }}} */
    2294             : #endif /* ifdef ZIP_OPSYS_DEFAULT */
    2295             : 
    2296             : #ifdef HAVE_ENCRYPTION
    2297             : /* {{{ proto bool ZipArchive::setEncryptionName(string name, int method, [string password])
    2298             : Set encryption method for file in zip, using its name */
    2299             : static ZIPARCHIVE_METHOD(setEncryptionName)
    2300             : {
    2301             :         struct zip *intern;
    2302             :         zval *self = getThis();
    2303             :         zend_long method;
    2304             :         zip_int64_t idx;
    2305             :         char *name, *password = NULL;
    2306             :         size_t name_len, password_len;
    2307             : 
    2308             :         if (!self) {
    2309             :                 RETURN_FALSE;
    2310             :         }
    2311             : 
    2312             :         ZIP_FROM_OBJECT(intern, self);
    2313             : 
    2314             :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|s",
    2315             :                         &name, &name_len, &method, &password, &password_len) == FAILURE) {
    2316             :                 return;
    2317             :         }
    2318             : 
    2319             :         if (name_len < 1) {
    2320             :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2321             :         }
    2322             : 
    2323             :         idx = zip_name_locate(intern, name, 0);
    2324             :         if (idx < 0) {
    2325             :                 RETURN_FALSE;
    2326             :         }
    2327             : 
    2328             :         if (zip_file_set_encryption(intern, idx, (zip_uint16_t)method, password)) {
    2329             :                 RETURN_FALSE;
    2330             :         }
    2331             :         RETURN_TRUE;
    2332             : }
    2333             : /* }}} */
    2334             : 
    2335             : /* {{{ proto bool ZipArchive::setEncryptionIndex(int index, int method, [string password])
    2336             : Set encryption method for file in zip, using its index */
    2337             : static ZIPARCHIVE_METHOD(setEncryptionIndex)
    2338             : {
    2339             :         struct zip *intern;
    2340             :         zval *self = getThis();
    2341             :         zend_long index, method;
    2342             :         char *password = NULL;
    2343             :         size_t password_len;
    2344             : 
    2345             :         if (!self) {
    2346             :                 RETURN_FALSE;
    2347             :         }
    2348             : 
    2349             :         ZIP_FROM_OBJECT(intern, self);
    2350             : 
    2351             :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|s",
    2352             :                         &index, &method, &password, &password_len) == FAILURE) {
    2353             :                 return;
    2354             :         }
    2355             : 
    2356             :         if (zip_file_set_encryption(intern, index, (zip_uint16_t)method, password)) {
    2357             :                 RETURN_FALSE;
    2358             :         }
    2359             :         RETURN_TRUE;
    2360             : }
    2361             : /* }}} */
    2362             : #endif
    2363             : 
    2364             : /* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
    2365             : Returns the comment of an entry using its name */
    2366           3 : static ZIPARCHIVE_METHOD(getCommentName)
    2367             : {
    2368             :         struct zip *intern;
    2369           6 :         zval *self = getThis();
    2370             :         size_t name_len;
    2371             :         int idx;
    2372           3 :         zend_long flags = 0;
    2373           3 :         int comment_len = 0;
    2374             :         const char * comment;
    2375             :         char *name;
    2376             : 
    2377           3 :         if (!self) {
    2378           0 :                 RETURN_FALSE;
    2379             :         }
    2380             : 
    2381           3 :         ZIP_FROM_OBJECT(intern, self);
    2382             : 
    2383           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l",
    2384             :                         &name, &name_len, &flags) == FAILURE) {
    2385           1 :                 return;
    2386             :         }
    2387           2 :         if (name_len < 1) {
    2388           1 :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2389           1 :                 RETURN_FALSE;
    2390             :         }
    2391             : 
    2392           1 :         idx = zip_name_locate(intern, name, 0);
    2393           1 :         if (idx < 0) {
    2394           0 :                 RETURN_FALSE;
    2395             :         }
    2396             : 
    2397           1 :         comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
    2398           2 :         RETURN_STRINGL((char *)comment, (zend_long)comment_len);
    2399             : }
    2400             : /* }}} */
    2401             : 
    2402             : /* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
    2403             : Returns the comment of an entry using its index */
    2404           6 : static ZIPARCHIVE_METHOD(getCommentIndex)
    2405             : {
    2406             :         struct zip *intern;
    2407          12 :         zval *self = getThis();
    2408           6 :         zend_long index, flags = 0;
    2409             :         const char * comment;
    2410           6 :         int comment_len = 0;
    2411             :         struct zip_stat sb;
    2412             : 
    2413           6 :         if (!self) {
    2414           0 :                 RETURN_FALSE;
    2415             :         }
    2416             : 
    2417           6 :         ZIP_FROM_OBJECT(intern, self);
    2418             : 
    2419           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
    2420             :                                 &index, &flags) == FAILURE) {
    2421           0 :                 return;
    2422             :         }
    2423             : 
    2424           6 :         PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
    2425           6 :         comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
    2426          12 :         RETURN_STRINGL((char *)comment, (zend_long)comment_len);
    2427             : }
    2428             : /* }}} */
    2429             : 
    2430             : /* {{{ proto bool ZipArchive::setCompressionName(string name, int comp_method[, int comp_flags])
    2431             : Set the compression of a file in zip, using its name */
    2432           3 : static ZIPARCHIVE_METHOD(setCompressionName)
    2433             :  {
    2434             :         struct zip *intern;
    2435           6 :         zval *this = getThis();
    2436             :         size_t name_len;
    2437             :         char *name;
    2438             :         zip_int64_t idx;
    2439           3 :         zend_long comp_method, comp_flags = 0;
    2440             : 
    2441           3 :         if (!this) {
    2442           0 :                 RETURN_FALSE;
    2443             :         }
    2444             : 
    2445           3 :         ZIP_FROM_OBJECT(intern, this);
    2446             : 
    2447           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l",
    2448             :                         &name, &name_len, &comp_method, &comp_flags) == FAILURE) {
    2449           0 :                 return;
    2450             :         }
    2451             : 
    2452           3 :         if (name_len < 1) {
    2453           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
    2454             :         }
    2455             : 
    2456           3 :         idx = zip_name_locate(intern, name, 0);
    2457           3 :         if (idx < 0) {
    2458           0 :                 RETURN_FALSE;
    2459             :         }
    2460             : 
    2461           3 :         if (zip_set_file_compression(intern, (zip_uint64_t)idx,
    2462             :                         (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) {
    2463           0 :                 RETURN_FALSE;
    2464             :         }
    2465           3 :         RETURN_TRUE;
    2466             : }
    2467             : /* }}} */
    2468             : 
    2469             : /* {{{ proto bool ZipArchive::setCompressionIndex(int index, int comp_method[, int comp_flags])
    2470             : Set the compression of a file in zip, using its index */
    2471           3 : static ZIPARCHIVE_METHOD(setCompressionIndex)
    2472             : {
    2473             :         struct zip *intern;
    2474           6 :         zval *this = getThis();
    2475             :         zend_long index;
    2476           3 :         zend_long comp_method, comp_flags = 0;
    2477             : 
    2478           3 :         if (!this) {
    2479           0 :                 RETURN_FALSE;
    2480             :         }
    2481             : 
    2482           3 :         ZIP_FROM_OBJECT(intern, this);
    2483             : 
    2484           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l",
    2485             :                         &index, &comp_method, &comp_flags) == FAILURE) {
    2486           0 :                 return;
    2487             :         }
    2488             : 
    2489           3 :         if (zip_set_file_compression(intern, (zip_uint64_t)index,
    2490             :                         (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) {
    2491           0 :                 RETURN_FALSE;
    2492             :         }
    2493           3 :         RETURN_TRUE;
    2494             : }
    2495             : /* }}} */
    2496             : 
    2497             : /* {{{ proto bool ZipArchive::deleteIndex(int index)
    2498             : Delete a file using its index */
    2499           3 : static ZIPARCHIVE_METHOD(deleteIndex)
    2500             : {
    2501             :         struct zip *intern;
    2502           6 :         zval *self = getThis();
    2503             :         zend_long index;
    2504             : 
    2505           3 :         if (!self) {
    2506           0 :                 RETURN_FALSE;
    2507             :         }
    2508             : 
    2509           3 :         ZIP_FROM_OBJECT(intern, self);
    2510             : 
    2511           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
    2512           0 :                 return;
    2513             :         }
    2514             : 
    2515           3 :         if (index < 0) {
    2516           0 :                 RETURN_FALSE;
    2517             :         }
    2518             : 
    2519           3 :         if (zip_delete(intern, index) < 0) {
    2520           2 :                 RETURN_FALSE;
    2521             :         }
    2522             : 
    2523           1 :         RETURN_TRUE;
    2524             : }
    2525             : /* }}} */
    2526             : 
    2527             : /* {{{ proto bool ZipArchive::deleteName(string name)
    2528             : Delete a file using its index */
    2529           3 : static ZIPARCHIVE_METHOD(deleteName)
    2530             : {
    2531             :         struct zip *intern;
    2532           6 :         zval *self = getThis();
    2533             :         size_t name_len;
    2534             :         char *name;
    2535             :         struct zip_stat sb;
    2536             : 
    2537           3 :         if (!self) {
    2538           0 :                 RETURN_FALSE;
    2539             :         }
    2540             : 
    2541           3 :         ZIP_FROM_OBJECT(intern, self);
    2542             : 
    2543           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
    2544           0 :                 return;
    2545             :         }
    2546           3 :         if (name_len < 1) {
    2547           0 :                 RETURN_FALSE;
    2548             :         }
    2549             : 
    2550           3 :         PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
    2551           3 :         if (zip_delete(intern, sb.index)) {
    2552           0 :                 RETURN_FALSE;
    2553             :         }
    2554           3 :         RETURN_TRUE;
    2555             : }
    2556             : /* }}} */
    2557             : 
    2558             : /* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
    2559             : Rename an entry selected by its index to new_name */
    2560           1 : static ZIPARCHIVE_METHOD(renameIndex)
    2561             : {
    2562             :         struct zip *intern;
    2563           2 :         zval *self = getThis();
    2564             : 
    2565             :         char *new_name;
    2566             :         size_t new_name_len;
    2567             :         zend_long index;
    2568             : 
    2569           1 :         if (!self) {
    2570           0 :                 RETURN_FALSE;
    2571             :         }
    2572             : 
    2573           1 :         ZIP_FROM_OBJECT(intern, self);
    2574             : 
    2575           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &index, &new_name, &new_name_len) == FAILURE) {
    2576           0 :                 return;
    2577             :         }
    2578             : 
    2579           1 :         if (index < 0) {
    2580           0 :                 RETURN_FALSE;
    2581             :         }
    2582             : 
    2583           1 :         if (new_name_len < 1) {
    2584           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as new entry name");
    2585           0 :                 RETURN_FALSE;
    2586             :         }
    2587           1 :         if (zip_rename(intern, index, (const char *)new_name) != 0) {
    2588           0 :                 RETURN_FALSE;
    2589             :         }
    2590           1 :         RETURN_TRUE;
    2591             : }
    2592             : /* }}} */
    2593             : 
    2594             : /* {{{ proto bool ZipArchive::renameName(string name, string new_name)
    2595             : Rename an entry selected by its name to new_name */
    2596           1 : static ZIPARCHIVE_METHOD(renameName)
    2597             : {
    2598             :         struct zip *intern;
    2599           2 :         zval *self = getThis();
    2600             :         struct zip_stat sb;
    2601             :         char *name, *new_name;
    2602             :         size_t name_len, new_name_len;
    2603             : 
    2604           1 :         if (!self) {
    2605           0 :                 RETURN_FALSE;
    2606             :         }
    2607             : 
    2608           1 :         ZIP_FROM_OBJECT(intern, self);
    2609             : 
    2610           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) {
    2611           0 :                 return;
    2612             :         }
    2613             : 
    2614           1 :         if (new_name_len < 1) {
    2615           0 :                 php_error_docref(NULL, E_NOTICE, "Empty string as new entry name");
    2616           0 :                 RETURN_FALSE;
    2617             :         }
    2618             : 
    2619           1 :         PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
    2620             : 
    2621           1 :         if (zip_rename(intern, sb.index, (const char *)new_name)) {
    2622           0 :                 RETURN_FALSE;
    2623             :         }
    2624           1 :         RETURN_TRUE;
    2625             : }
    2626             : /* }}} */
    2627             : 
    2628             : /* {{{ proto bool ZipArchive::unchangeIndex(int index)
    2629             : Changes to the file at position index are reverted */
    2630           0 : static ZIPARCHIVE_METHOD(unchangeIndex)
    2631             : {
    2632             :         struct zip *intern;
    2633           0 :         zval *self = getThis();
    2634             :         zend_long index;
    2635             : 
    2636           0 :         if (!self) {
    2637           0 :                 RETURN_FALSE;
    2638             :         }
    2639             : 
    2640           0 :         ZIP_FROM_OBJECT(intern, self);
    2641             : 
    2642           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
    2643           0 :                 return;
    2644             :         }
    2645             : 
    2646           0 :         if (index < 0) {
    2647           0 :                 RETURN_FALSE;
    2648             :         }
    2649             : 
    2650           0 :         if (zip_unchange(intern, index) != 0) {
    2651           0 :                 RETURN_FALSE;
    2652             :         } else {
    2653           0 :                 RETURN_TRUE;
    2654             :         }
    2655             : }
    2656             : /* }}} */
    2657             : 
    2658             : /* {{{ proto bool ZipArchive::unchangeName(string name)
    2659             : Changes to the file named 'name' are reverted */
    2660           0 : static ZIPARCHIVE_METHOD(unchangeName)
    2661             : {
    2662             :         struct zip *intern;
    2663           0 :         zval *self = getThis();
    2664             :         struct zip_stat sb;
    2665             :         char *name;
    2666             :         size_t name_len;
    2667             : 
    2668           0 :         if (!self) {
    2669           0 :                 RETURN_FALSE;
    2670             :         }
    2671             : 
    2672           0 :         ZIP_FROM_OBJECT(intern, self);
    2673             : 
    2674           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
    2675           0 :                 return;
    2676             :         }
    2677             : 
    2678           0 :         if (name_len < 1) {
    2679           0 :                 RETURN_FALSE;
    2680             :         }
    2681             : 
    2682           0 :         PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
    2683             : 
    2684           0 :         if (zip_unchange(intern, sb.index) != 0) {
    2685           0 :                 RETURN_FALSE;
    2686             :         } else {
    2687           0 :                 RETURN_TRUE;
    2688             :         }
    2689             : }
    2690             : /* }}} */
    2691             : 
    2692             : /* {{{ proto bool ZipArchive::unchangeAll()
    2693             : All changes to files and global information in archive are reverted */
    2694           0 : static ZIPARCHIVE_METHOD(unchangeAll)
    2695             : {
    2696             :         struct zip *intern;
    2697           0 :         zval *self = getThis();
    2698             : 
    2699           0 :         if (!self) {
    2700           0 :                 RETURN_FALSE;
    2701             :         }
    2702             : 
    2703           0 :         ZIP_FROM_OBJECT(intern, self);
    2704             : 
    2705           0 :         if (zip_unchange_all(intern) != 0) {
    2706           0 :                 RETURN_FALSE;
    2707             :         } else {
    2708           0 :                 RETURN_TRUE;
    2709             :         }
    2710             : }
    2711             : /* }}} */
    2712             : 
    2713             : /* {{{ proto bool ZipArchive::unchangeArchive()
    2714             : Revert all global changes to the archive archive.  For now, this only reverts archive comment changes. */
    2715           0 : static ZIPARCHIVE_METHOD(unchangeArchive)
    2716             : {
    2717             :         struct zip *intern;
    2718           0 :         zval *self = getThis();
    2719             : 
    2720           0 :         if (!self) {
    2721           0 :                 RETURN_FALSE;
    2722             :         }
    2723             : 
    2724           0 :         ZIP_FROM_OBJECT(intern, self);
    2725             : 
    2726           0 :         if (zip_unchange_archive(intern) != 0) {
    2727           0 :                 RETURN_FALSE;
    2728             :         } else {
    2729           0 :                 RETURN_TRUE;
    2730             :         }
    2731             : }
    2732             : /* }}} */
    2733             : 
    2734             : /* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
    2735             : Extract one or more file from a zip archive */
    2736             : /* TODO:
    2737             :  * - allow index or array of indeces
    2738             :  * - replace path
    2739             :  * - patterns
    2740             :  */
    2741           9 : static ZIPARCHIVE_METHOD(extractTo)
    2742             : {
    2743             :         struct zip *intern;
    2744             : 
    2745          18 :         zval *self = getThis();
    2746           9 :         zval *zval_files = NULL;
    2747           9 :         zval *zval_file = NULL;
    2748             :         php_stream_statbuf ssb;
    2749             :         char *pathto;
    2750             :         size_t pathto_len;
    2751             :         int ret, i;
    2752             : 
    2753             :         int nelems;
    2754             : 
    2755           9 :         if (!self) {
    2756           0 :                 RETURN_FALSE;
    2757             :         }
    2758             : 
    2759           9 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
    2760           0 :                 return;
    2761             :         }
    2762             : 
    2763           9 :         if (pathto_len < 1) {
    2764           0 :                 RETURN_FALSE;
    2765             :         }
    2766             : 
    2767           9 :         if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
    2768           1 :                         ret = php_stream_mkdir(pathto, 0777,  PHP_STREAM_MKDIR_RECURSIVE, NULL);
    2769           1 :                         if (!ret) {
    2770           0 :                                         RETURN_FALSE;
    2771             :                         }
    2772             :         }
    2773             : 
    2774           9 :         ZIP_FROM_OBJECT(intern, self);
    2775          12 :         if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
    2776           4 :                 switch (Z_TYPE_P(zval_files)) {
    2777           1 :                         case IS_STRING:
    2778           1 :                                 if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files))) {
    2779           0 :                                         RETURN_FALSE;
    2780             :                                 }
    2781           1 :                                 break;
    2782           1 :                         case IS_ARRAY:
    2783           1 :                                 nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
    2784           1 :                                 if (nelems == 0 ) {
    2785           0 :                                         RETURN_FALSE;
    2786             :                                 }
    2787           3 :                                 for (i = 0; i < nelems; i++) {
    2788           2 :                                         if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), i)) != NULL) {
    2789           2 :                                                 switch (Z_TYPE_P(zval_file)) {
    2790           0 :                                                         case IS_LONG:
    2791           0 :                                                                 break;
    2792           2 :                                                         case IS_STRING:
    2793           2 :                                                                 if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file))) {
    2794           0 :                                                                         RETURN_FALSE;
    2795             :                                                                 }
    2796           2 :                                                                 break;
    2797             :                                                 }
    2798             :                                         }
    2799             :                                 }
    2800           1 :                                 break;
    2801           0 :                         case IS_LONG:
    2802             :                         default:
    2803           0 :                                 php_error_docref(NULL, E_WARNING, "Invalid argument, expect string or array of strings");
    2804           0 :                                 break;
    2805             :                 }
    2806           2 :         } else {
    2807             :                 /* Extract all files */
    2808           7 :                 int filecount = zip_get_num_files(intern);
    2809             : 
    2810           7 :                 if (filecount == -1) {
    2811           0 :                                 php_error_docref(NULL, E_WARNING, "Illegal archive");
    2812           0 :                                 RETURN_FALSE;
    2813             :                 }
    2814             : 
    2815          17 :                 for (i = 0; i < filecount; i++) {
    2816          12 :                         char *file = (char*)zip_get_name(intern, i, ZIP_FL_UNCHANGED);
    2817          12 :                         if (!file || !php_zip_extract_file(intern, pathto, file, strlen(file))) {
    2818           2 :                                         RETURN_FALSE;
    2819             :                         }
    2820             :                 }
    2821             :         }
    2822           7 :         RETURN_TRUE;
    2823             : }
    2824             : /* }}} */
    2825             : 
    2826           4 : static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
    2827             : {
    2828             :         struct zip *intern;
    2829           8 :         zval *self = getThis();
    2830             : 
    2831             :         struct zip_stat sb;
    2832             :         struct zip_file *zf;
    2833             : 
    2834           4 :         zend_long index = -1;
    2835           4 :         zend_long flags = 0;
    2836           4 :         zend_long len = 0;
    2837             : 
    2838             :         zend_string *filename;
    2839             :         zend_string *buffer;
    2840             : 
    2841           4 :         int n = 0;
    2842             : 
    2843           4 :         if (!self) {
    2844           0 :                 RETURN_FALSE;
    2845             :         }
    2846             : 
    2847           4 :         ZIP_FROM_OBJECT(intern, self);
    2848             : 
    2849           4 :         if (type == 1) {
    2850           3 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|ll", &filename, &len, &flags) == FAILURE) {
    2851           0 :                         return;
    2852             :                 }
    2853           3 :                 PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(filename), ZSTR_LEN(filename), flags, sb);
    2854             :         } else {
    2855           1 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &index, &len, &flags) == FAILURE) {
    2856           0 :                         return;
    2857             :                 }
    2858           1 :                 PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
    2859             :         }
    2860             : 
    2861           4 :         if (sb.size < 1) {
    2862           0 :                 RETURN_EMPTY_STRING();
    2863             :         }
    2864             : 
    2865           4 :         if (len < 1) {
    2866           4 :                 len = sb.size;
    2867             :         }
    2868           4 :         if (index >= 0) {
    2869           1 :                 zf = zip_fopen_index(intern, index, flags);
    2870             :         } else {
    2871           3 :                 zf = zip_fopen(intern, ZSTR_VAL(filename), flags);
    2872             :         }
    2873             : 
    2874           4 :         if (zf == NULL) {
    2875           0 :                 RETURN_FALSE;
    2876             :         }
    2877             : 
    2878           8 :         buffer = zend_string_safe_alloc(1, len, 0, 0);
    2879           4 :         n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer));
    2880           4 :         if (n < 1) {
    2881             :                 zend_string_efree(buffer);
    2882           0 :                 RETURN_EMPTY_STRING();
    2883             :         }
    2884             : 
    2885           4 :         zip_fclose(zf);
    2886           4 :         ZSTR_VAL(buffer)[n] = '\0';
    2887           4 :         ZSTR_LEN(buffer) = n;
    2888           4 :         RETURN_NEW_STR(buffer);
    2889             : }
    2890             : /* }}} */
    2891             : 
    2892             : /* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
    2893             : get the contents of an entry using its name */
    2894           3 : static ZIPARCHIVE_METHOD(getFromName)
    2895             : {
    2896           3 :         php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    2897           3 : }
    2898             : /* }}} */
    2899             : 
    2900             : /* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
    2901             : get the contents of an entry using its index */
    2902           1 : static ZIPARCHIVE_METHOD(getFromIndex)
    2903             : {
    2904           1 :         php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    2905           1 : }
    2906             : /* }}} */
    2907             : 
    2908             : /* {{{ proto resource ZipArchive::getStream(string entryname)
    2909             : get a stream for an entry using its name */
    2910           4 : static ZIPARCHIVE_METHOD(getStream)
    2911             : {
    2912             :         struct zip *intern;
    2913           8 :         zval *self = getThis();
    2914             :         struct zip_stat sb;
    2915           4 :         char *mode = "rb";
    2916             :         zend_string *filename;
    2917             :         php_stream *stream;
    2918             :         ze_zip_object *obj;
    2919             : 
    2920           4 :         if (!self) {
    2921           0 :                 RETURN_FALSE;
    2922             :         }
    2923             : 
    2924           4 :         ZIP_FROM_OBJECT(intern, self);
    2925             : 
    2926           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) {
    2927           0 :                 return;
    2928             :         }
    2929             : 
    2930           4 :         if (zip_stat(intern, ZSTR_VAL(filename), 0, &sb) != 0) {
    2931           0 :                 RETURN_FALSE;
    2932             :         }
    2933             : 
    2934           4 :         obj = Z_ZIP_P(self);
    2935             : 
    2936           4 :         stream = php_stream_zip_open(obj->filename, ZSTR_VAL(filename), mode STREAMS_CC);
    2937           4 :         if (stream) {
    2938           4 :                 php_stream_to_zval(stream, return_value);
    2939             :         } else {
    2940           0 :                 RETURN_FALSE;
    2941             :         }
    2942             : }
    2943             : /* }}} */
    2944             : 
    2945             : /* {{{ arginfo */
    2946             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
    2947             :         ZEND_ARG_INFO(0, filename)
    2948             :         ZEND_ARG_INFO(0, flags)
    2949             : ZEND_END_ARG_INFO()
    2950             : 
    2951             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1)
    2952             :         ZEND_ARG_INFO(0, password)
    2953             : ZEND_END_ARG_INFO()
    2954             : 
    2955             : ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
    2956             : ZEND_END_ARG_INFO()
    2957             : 
    2958             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir, 0, 0, 1)
    2959             :         ZEND_ARG_INFO(0, dirname)
    2960             : ZEND_END_ARG_INFO()
    2961             : 
    2962             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob, 0, 0, 1)
    2963             :         ZEND_ARG_INFO(0, pattern)
    2964             :         ZEND_ARG_INFO(0, flags)
    2965             :         ZEND_ARG_INFO(0, options)
    2966             : ZEND_END_ARG_INFO()
    2967             : 
    2968             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern, 0, 0, 1)
    2969             :         ZEND_ARG_INFO(0, pattern)
    2970             :         ZEND_ARG_INFO(0, path)
    2971             :         ZEND_ARG_INFO(0, options)
    2972             : ZEND_END_ARG_INFO()
    2973             : 
    2974             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile, 0, 0, 1)
    2975             :         ZEND_ARG_INFO(0, filepath)
    2976             :         ZEND_ARG_INFO(0, entryname)
    2977             :         ZEND_ARG_INFO(0, start)
    2978             :         ZEND_ARG_INFO(0, length)
    2979             : ZEND_END_ARG_INFO()
    2980             : 
    2981             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring, 0, 0, 2)
    2982             :         ZEND_ARG_INFO(0, name)
    2983             :         ZEND_ARG_INFO(0, content)
    2984             : ZEND_END_ARG_INFO()
    2985             : 
    2986             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname, 0, 0, 1)
    2987             :         ZEND_ARG_INFO(0, filename)
    2988             :         ZEND_ARG_INFO(0, flags)
    2989             : ZEND_END_ARG_INFO()
    2990             : 
    2991             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex, 0, 0, 1)
    2992             :         ZEND_ARG_INFO(0, index)
    2993             :         ZEND_ARG_INFO(0, flags)
    2994             : ZEND_END_ARG_INFO()
    2995             : 
    2996             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment, 0, 0, 1)
    2997             :         ZEND_ARG_INFO(0, comment)
    2998             : ZEND_END_ARG_INFO()
    2999             : 
    3000             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex, 0, 0, 2)
    3001             :         ZEND_ARG_INFO(0, index)
    3002             :         ZEND_ARG_INFO(0, comment)
    3003             : ZEND_END_ARG_INFO()
    3004             : 
    3005             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname, 0, 0, 1)
    3006             :         ZEND_ARG_INFO(0, name)
    3007             :         ZEND_ARG_INFO(0, flags)
    3008             : ZEND_END_ARG_INFO()
    3009             : 
    3010             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex, 0, 0, 1)
    3011             :         ZEND_ARG_INFO(0, index)
    3012             :         ZEND_ARG_INFO(0, flags)
    3013             : ZEND_END_ARG_INFO()
    3014             : 
    3015             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex, 0, 0, 2)
    3016             :         ZEND_ARG_INFO(0, index)
    3017             :         ZEND_ARG_INFO(0, new_name)
    3018             : ZEND_END_ARG_INFO()
    3019             : 
    3020             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename, 0, 0, 2)
    3021             :         ZEND_ARG_INFO(0, name)
    3022             :         ZEND_ARG_INFO(0, new_name)
    3023             : ZEND_END_ARG_INFO()
    3024             : 
    3025             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex, 0, 0, 1)
    3026             :         ZEND_ARG_INFO(0, index)
    3027             : ZEND_END_ARG_INFO()
    3028             : 
    3029             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename, 0, 0, 1)
    3030             :         ZEND_ARG_INFO(0, name)
    3031             : ZEND_END_ARG_INFO()
    3032             : 
    3033             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto, 0, 0, 1)
    3034             :         ZEND_ARG_INFO(0, pathto)
    3035             :         ZEND_ARG_INFO(0, files)
    3036             : ZEND_END_ARG_INFO()
    3037             : 
    3038             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname, 0, 0, 1)
    3039             :         ZEND_ARG_INFO(0, entryname)
    3040             :         ZEND_ARG_INFO(0, len)
    3041             :         ZEND_ARG_INFO(0, flags)
    3042             : ZEND_END_ARG_INFO()
    3043             : 
    3044             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex, 0, 0, 1)
    3045             :         ZEND_ARG_INFO(0, index)
    3046             :         ZEND_ARG_INFO(0, len)
    3047             :         ZEND_ARG_INFO(0, flags)
    3048             : ZEND_END_ARG_INFO()
    3049             : 
    3050             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment, 0, 0, 0)
    3051             :         ZEND_ARG_INFO(0, flags)
    3052             : ZEND_END_ARG_INFO()
    3053             : 
    3054             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname, 0, 0, 2)
    3055             :         ZEND_ARG_INFO(0, name)
    3056             :         ZEND_ARG_INFO(0, comment)
    3057             : ZEND_END_ARG_INFO()
    3058             : 
    3059             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream, 0, 0, 1)
    3060             :         ZEND_ARG_INFO(0, entryname)
    3061             : ZEND_END_ARG_INFO()
    3062             : 
    3063             : #ifdef ZIP_OPSYS_DEFAULT
    3064             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setextattrname, 0, 0, 3)
    3065             :         ZEND_ARG_INFO(0, name)
    3066             :         ZEND_ARG_INFO(0, opsys)
    3067             :         ZEND_ARG_INFO(0, attr)
    3068             :         ZEND_ARG_INFO(0, flags)
    3069             : ZEND_END_ARG_INFO()
    3070             : 
    3071             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setextattrindex, 0, 0, 3)
    3072             :         ZEND_ARG_INFO(0, index)
    3073             :         ZEND_ARG_INFO(0, opsys)
    3074             :         ZEND_ARG_INFO(0, attr)
    3075             :         ZEND_ARG_INFO(0, flags)
    3076             : ZEND_END_ARG_INFO()
    3077             : 
    3078             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getextattrname, 0, 0, 3)
    3079             :         ZEND_ARG_INFO(0, name)
    3080             :         ZEND_ARG_INFO(1, opsys)
    3081             :         ZEND_ARG_INFO(1, attr)
    3082             :         ZEND_ARG_INFO(0, flags)
    3083             : ZEND_END_ARG_INFO()
    3084             : 
    3085             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getextattrindex, 0, 0, 3)
    3086             :         ZEND_ARG_INFO(0, index)
    3087             :         ZEND_ARG_INFO(1, opsys)
    3088             :         ZEND_ARG_INFO(1, attr)
    3089             :         ZEND_ARG_INFO(0, flags)
    3090             : ZEND_END_ARG_INFO()
    3091             : #endif /* ifdef ZIP_OPSYS_DEFAULT */
    3092             : /* }}} */
    3093             : 
    3094             : #ifdef HAVE_ENCRYPTION
    3095             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_name, 0, 0, 2)
    3096             :         ZEND_ARG_INFO(0, name)
    3097             :         ZEND_ARG_INFO(0, method)
    3098             :         ZEND_ARG_INFO(0, password)
    3099             : ZEND_END_ARG_INFO()
    3100             : 
    3101             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_index, 0, 0, 2)
    3102             :         ZEND_ARG_INFO(0, index)
    3103             :         ZEND_ARG_INFO(0, method)
    3104             :         ZEND_ARG_INFO(0, password)
    3105             : ZEND_END_ARG_INFO()
    3106             : #endif
    3107             : 
    3108             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcompname, 0, 0, 2)
    3109             :         ZEND_ARG_INFO(0, name)
    3110             :         ZEND_ARG_INFO(0, method)
    3111             :         ZEND_ARG_INFO(0, compflags)
    3112             : ZEND_END_ARG_INFO()
    3113             : 
    3114             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcompindex, 0, 0, 2)
    3115             :         ZEND_ARG_INFO(0, index)
    3116             :         ZEND_ARG_INFO(0, method)
    3117             :         ZEND_ARG_INFO(0, compflags)
    3118             : ZEND_END_ARG_INFO()
    3119             : 
    3120             : /* {{{ ze_zip_object_class_functions */
    3121             : static const zend_function_entry zip_class_functions[] = {
    3122             :         ZIPARCHIVE_ME(open,                                     arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
    3123             :         ZIPARCHIVE_ME(setPassword,                      arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC)
    3124             :         ZIPARCHIVE_ME(close,                            arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
    3125             :         ZIPARCHIVE_ME(count,                            arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
    3126             :         ZIPARCHIVE_ME(getStatusString,          arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
    3127             :         ZIPARCHIVE_ME(addEmptyDir,                      arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
    3128             :         ZIPARCHIVE_ME(addFromString,            arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
    3129             :         ZIPARCHIVE_ME(addFile,                          arginfo_ziparchive_addfile, ZEND_ACC_PUBLIC)
    3130             :         ZIPARCHIVE_ME(addGlob,                          arginfo_ziparchive_addglob, ZEND_ACC_PUBLIC)
    3131             :         ZIPARCHIVE_ME(addPattern,                       arginfo_ziparchive_addpattern, ZEND_ACC_PUBLIC)
    3132             :         ZIPARCHIVE_ME(renameIndex,                      arginfo_ziparchive_renameindex, ZEND_ACC_PUBLIC)
    3133             :         ZIPARCHIVE_ME(renameName,                       arginfo_ziparchive_renamename, ZEND_ACC_PUBLIC)
    3134             :         ZIPARCHIVE_ME(setArchiveComment,        arginfo_ziparchive_setarchivecomment, ZEND_ACC_PUBLIC)
    3135             :         ZIPARCHIVE_ME(getArchiveComment,        arginfo_ziparchive_getarchivecomment, ZEND_ACC_PUBLIC)
    3136             :         ZIPARCHIVE_ME(setCommentIndex,          arginfo_ziparchive_setcommentindex, ZEND_ACC_PUBLIC)
    3137             :         ZIPARCHIVE_ME(setCommentName,           arginfo_ziparchive_setcommentname, ZEND_ACC_PUBLIC)
    3138             :         ZIPARCHIVE_ME(getCommentIndex,          arginfo_ziparchive_getcommentindex, ZEND_ACC_PUBLIC)
    3139             :         ZIPARCHIVE_ME(getCommentName,           arginfo_ziparchive_getcommentname, ZEND_ACC_PUBLIC)
    3140             :         ZIPARCHIVE_ME(deleteIndex,                      arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
    3141             :         ZIPARCHIVE_ME(deleteName,                       arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
    3142             :         ZIPARCHIVE_ME(statName,                         arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
    3143             :         ZIPARCHIVE_ME(statIndex,                        arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
    3144             :         ZIPARCHIVE_ME(locateName,                       arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
    3145             :         ZIPARCHIVE_ME(getNameIndex,                     arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
    3146             :         ZIPARCHIVE_ME(unchangeArchive,          arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
    3147             :         ZIPARCHIVE_ME(unchangeAll,                      arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
    3148             :         ZIPARCHIVE_ME(unchangeIndex,            arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
    3149             :         ZIPARCHIVE_ME(unchangeName,                     arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
    3150             :         ZIPARCHIVE_ME(extractTo,                        arginfo_ziparchive_extractto, ZEND_ACC_PUBLIC)
    3151             :         ZIPARCHIVE_ME(getFromName,                      arginfo_ziparchive_getfromname, ZEND_ACC_PUBLIC)
    3152             :         ZIPARCHIVE_ME(getFromIndex,                     arginfo_ziparchive_getfromindex, ZEND_ACC_PUBLIC)
    3153             :         ZIPARCHIVE_ME(getStream,                        arginfo_ziparchive_getstream, ZEND_ACC_PUBLIC)
    3154             : #ifdef ZIP_OPSYS_DEFAULT
    3155             :         ZIPARCHIVE_ME(setExternalAttributesName,        arginfo_ziparchive_setextattrname, ZEND_ACC_PUBLIC)
    3156             :         ZIPARCHIVE_ME(setExternalAttributesIndex,       arginfo_ziparchive_setextattrindex, ZEND_ACC_PUBLIC)
    3157             :         ZIPARCHIVE_ME(getExternalAttributesName,        arginfo_ziparchive_getextattrname, ZEND_ACC_PUBLIC)
    3158             :         ZIPARCHIVE_ME(getExternalAttributesIndex,       arginfo_ziparchive_getextattrindex, ZEND_ACC_PUBLIC)
    3159             : #endif
    3160             :         ZIPARCHIVE_ME(setCompressionName,               arginfo_ziparchive_setcompname, ZEND_ACC_PUBLIC)
    3161             :         ZIPARCHIVE_ME(setCompressionIndex,              arginfo_ziparchive_setcompindex, ZEND_ACC_PUBLIC)
    3162             : #ifdef HAVE_ENCRYPTION
    3163             :         ZIPARCHIVE_ME(setEncryptionName,                arginfo_ziparchive_setencryption_name, ZEND_ACC_PUBLIC)
    3164             :         ZIPARCHIVE_ME(setEncryptionIndex,               arginfo_ziparchive_setencryption_index, ZEND_ACC_PUBLIC)
    3165             : #endif
    3166             :         PHP_FE_END
    3167             : };
    3168             : /* }}} */
    3169             : 
    3170      130305 : static void php_zip_free_prop_handler(zval *el) /* {{{ */ {
    3171      130305 :         pefree(Z_PTR_P(el), 1);
    3172      130305 : } /* }}} */
    3173             : 
    3174             : /* {{{ PHP_MINIT_FUNCTION */
    3175       26000 : static PHP_MINIT_FUNCTION(zip)
    3176             : {
    3177             :         zend_class_entry ce;
    3178             : 
    3179       26000 :         memcpy(&zip_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
    3180       26000 :         zip_object_handlers.offset = XtOffsetOf(ze_zip_object, zo);
    3181       26000 :         zip_object_handlers.free_obj = php_zip_object_free_storage;
    3182       26000 :         zip_object_handlers.clone_obj = NULL;
    3183       26000 :         zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
    3184             : 
    3185       26000 :         zip_object_handlers.get_gc          = php_zip_get_gc;
    3186       26000 :         zip_object_handlers.get_properties = php_zip_get_properties;
    3187       26000 :         zip_object_handlers.read_property       = php_zip_read_property;
    3188       26000 :         zip_object_handlers.has_property        = php_zip_has_property;
    3189             : 
    3190       26000 :         INIT_CLASS_ENTRY(ce, "ZipArchive", zip_class_functions);
    3191       26000 :         ce.create_object = php_zip_object_new;
    3192       26000 :         zip_class_entry = zend_register_internal_class(&ce);
    3193             : 
    3194       26000 :         zend_hash_init(&zip_prop_handlers, 0, NULL, php_zip_free_prop_handler, 1);
    3195       26000 :         php_zip_register_prop_handler(&zip_prop_handlers, "status",    php_zip_status, NULL, NULL, IS_LONG);
    3196       26000 :         php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, NULL, IS_LONG);
    3197       26000 :         php_zip_register_prop_handler(&zip_prop_handlers, "numFiles",  php_zip_get_num_files, NULL, NULL, IS_LONG);
    3198       26000 :         php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING);
    3199       26000 :         php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING);
    3200             : #if PHP_VERSION_ID >= 70200
    3201       26000 :         zend_class_implements(zip_class_entry, 1, zend_ce_countable);
    3202             : #elif defined(HAVE_SPL)
    3203             :         zend_class_implements(zip_class_entry, 1, spl_ce_Countable);
    3204             : #endif
    3205             : 
    3206       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
    3207       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
    3208       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS);
    3209       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE);
    3210             : 
    3211       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE);
    3212       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
    3213       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
    3214       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
    3215             : 
    3216             : #ifdef ZIP_FL_ENC_GUESS
    3217             :         /* Default filename encoding policy. */
    3218       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_GUESS", ZIP_FL_ENC_GUESS);
    3219             : #endif
    3220             : #ifdef ZIP_FL_ENC_RAW
    3221       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_RAW", ZIP_FL_ENC_RAW);
    3222             : #endif
    3223             : #ifdef ZIP_FL_ENC_STRICT
    3224       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_STRICT", ZIP_FL_ENC_STRICT);
    3225             : #endif
    3226             : #ifdef ZIP_FL_ENC_UTF_8
    3227       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_UTF_8", ZIP_FL_ENC_UTF_8);
    3228             : #endif
    3229             : #ifdef ZIP_FL_ENC_CP437
    3230       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_CP437", ZIP_FL_ENC_CP437);
    3231             : #endif
    3232             : 
    3233       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
    3234       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
    3235       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
    3236       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1);
    3237       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2);
    3238       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3);
    3239       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4);
    3240       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE);
    3241       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE);
    3242       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64);
    3243       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE);
    3244       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2);
    3245       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA);
    3246       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE);
    3247       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77);
    3248       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK);
    3249       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD);
    3250             : 
    3251             :         /* Error code */
    3252       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_OK",                        ZIP_ER_OK);                     /* N No error */
    3253       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK);      /* N Multi-disk zip archives not supported */
    3254       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME",            ZIP_ER_RENAME);         /* S Renaming temporary file failed */
    3255       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE",             ZIP_ER_CLOSE);          /* S Closing zip archive failed */
    3256       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK",              ZIP_ER_SEEK);           /* S Seek error */
    3257       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_READ",              ZIP_ER_READ);           /* S Read error */
    3258       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE",             ZIP_ER_WRITE);          /* S Write error */
    3259       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC",                       ZIP_ER_CRC);            /* N CRC error */
    3260       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED);      /* N Containing zip archive was closed */
    3261       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT",             ZIP_ER_NOENT);          /* N No such file */
    3262       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS",            ZIP_ER_EXISTS);         /* N File already exists */
    3263       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN",              ZIP_ER_OPEN);           /* S Can't open file */
    3264       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN",           ZIP_ER_TMPOPEN);        /* S Failure to create temporary file */
    3265       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB",              ZIP_ER_ZLIB);           /* Z Zlib error */
    3266       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY",            ZIP_ER_MEMORY);         /* N Malloc failure */
    3267       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED",           ZIP_ER_CHANGED);        /* N Entry has been changed */
    3268       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP",       ZIP_ER_COMPNOTSUPP);/* N Compression method not supported */
    3269       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF",                       ZIP_ER_EOF);            /* N Premature EOF */
    3270       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL",             ZIP_ER_INVAL);          /* N Invalid argument */
    3271       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP",             ZIP_ER_NOZIP);          /* N Not a zip archive */
    3272       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL",  ZIP_ER_INTERNAL);       /* N Internal error */
    3273       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS",            ZIP_ER_INCONS);         /* N Zip archive inconsistent */
    3274       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE",            ZIP_ER_REMOVE);         /* S Can't remove file */
    3275       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED",   ZIP_ER_DELETED);        /* N Entry has been deleted */
    3276             : 
    3277             : #ifdef ZIP_OPSYS_DEFAULT
    3278       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DOS",                            ZIP_OPSYS_DOS);
    3279       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_AMIGA",                  ZIP_OPSYS_AMIGA);
    3280       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OPENVMS",                        ZIP_OPSYS_OPENVMS);
    3281       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_UNIX",                           ZIP_OPSYS_UNIX);
    3282       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VM_CMS",                 ZIP_OPSYS_VM_CMS);
    3283       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ATARI_ST",                       ZIP_OPSYS_ATARI_ST);
    3284       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_2",                           ZIP_OPSYS_OS_2);
    3285       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MACINTOSH",              ZIP_OPSYS_MACINTOSH);
    3286       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_SYSTEM",                       ZIP_OPSYS_Z_SYSTEM);
    3287       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM",                  ZIP_OPSYS_CPM);  // typo kept for BC
    3288       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_CPM",                            ZIP_OPSYS_CPM);
    3289       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_WINDOWS_NTFS",           ZIP_OPSYS_WINDOWS_NTFS);
    3290       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MVS",                            ZIP_OPSYS_MVS);
    3291       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VSE",                            ZIP_OPSYS_VSE);
    3292       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ACORN_RISC",             ZIP_OPSYS_ACORN_RISC);
    3293       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VFAT",                           ZIP_OPSYS_VFAT);
    3294       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ALTERNATE_MVS",  ZIP_OPSYS_ALTERNATE_MVS);
    3295       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_BEOS",                           ZIP_OPSYS_BEOS);
    3296       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_TANDEM",                 ZIP_OPSYS_TANDEM);
    3297       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_400",                 ZIP_OPSYS_OS_400);
    3298       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_X",                           ZIP_OPSYS_OS_X);
    3299             : 
    3300       26000 :         REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DEFAULT", ZIP_OPSYS_DEFAULT);
    3301             : #endif /* ifdef ZIP_OPSYS_DEFAULT */
    3302             : 
    3303             : #ifdef HAVE_ENCRYPTION
    3304             :         REGISTER_ZIP_CLASS_CONST_LONG("EM_NONE",                              ZIP_EM_NONE);
    3305             :         REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_128",                           ZIP_EM_AES_128);
    3306             :         REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_192",                           ZIP_EM_AES_192);
    3307             :         REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_256",                           ZIP_EM_AES_256);
    3308             : #endif
    3309             : 
    3310       26000 :         php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper);
    3311             : 
    3312       26000 :         le_zip_dir   = zend_register_list_destructors_ex(php_zip_free_dir,   NULL, le_zip_dir_name,   module_number);
    3313       26000 :         le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number);
    3314             : 
    3315       26000 :         return SUCCESS;
    3316             : }
    3317             : /* }}} */
    3318             : 
    3319             : /* {{{ PHP_MSHUTDOWN_FUNCTION
    3320             :  */
    3321       26061 : static PHP_MSHUTDOWN_FUNCTION(zip)
    3322             : {
    3323       26061 :         zend_hash_destroy(&zip_prop_handlers);
    3324       26061 :         php_unregister_url_stream_wrapper("zip");
    3325       26061 :         return SUCCESS;
    3326             : }
    3327             : /* }}} */
    3328             : 
    3329             : /* {{{ PHP_MINFO_FUNCTION
    3330             :  */
    3331         149 : static PHP_MINFO_FUNCTION(zip)
    3332             : {
    3333         149 :         php_info_print_table_start();
    3334             : 
    3335         149 :         php_info_print_table_row(2, "Zip", "enabled");
    3336         149 :         php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
    3337             : #if HAVE_LIBZIP_VERSION
    3338             :         php_info_print_table_row(2, "Libzip headers version", LIBZIP_VERSION);
    3339             :         php_info_print_table_row(2, "Libzip library version", zip_libzip_version());
    3340             : #else
    3341         149 :         php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
    3342             : #endif
    3343             : 
    3344         149 :         php_info_print_table_end();
    3345         149 : }
    3346             : /* }}} */
    3347             : 
    3348             : /*
    3349             :  * Local variables:
    3350             :  * tab-width: 4
    3351             :  * c-basic-offset: 4
    3352             :  * End:
    3353             :  * vim600: noet sw=4 ts=4 fdm=marker
    3354             :  * vim<600: noet sw=4 ts=4
    3355             :  */

Generated by: LCOV version 1.10

Generated at Wed, 19 Jan 2022 00:14:27 +0000 (3 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.