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: 0 1188 0.0 %
Date: 2014-04-16 Functions: 0 72 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:48:00 +0000 (8 days ago)

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