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: 899 1212 74.2 %
Date: 2016-08-24 Functions: 71 76 93.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 24 Aug 2016 12:20:34 +0000 (3 days ago)

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