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

Generated by: LCOV version 1.10

Generated at Sun, 29 May 2016 00:48:36 +0000 (3 days ago)

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