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: 860 1166 73.8 %
Date: 2014-12-13 Functions: 68 73 93.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:25 +0000 (8 days ago)

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