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: 695 1107 62.8 %
Date: 2014-07-27 Functions: 57 67 85.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:39 +0000 (17 hours ago)

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