PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - zip - php_zip.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 1092
Code covered: 63.6 % Executed lines: 694
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:44 +0000 (36 hours ago)

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