From bee1898bbbf2a38c1e51162704022f185ce00190 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 1 Jul 2025 07:53:22 +0200 Subject: [PATCH 1/2] 8.5 compat --- config.m4 | 3 + config.w32 | 2 + php85/php_zip.c | 3200 +++++++++++++++++++++++++++++++++++++++ php85/php_zip.h | 101 ++ php85/php_zip.stub.php | 824 ++++++++++ php85/php_zip_arginfo.h | 1343 ++++++++++++++++ php85/zip_stream.c | 390 +++++ 7 files changed, 5863 insertions(+) create mode 100644 php85/php_zip.c create mode 100644 php85/php_zip.h create mode 100644 php85/php_zip.stub.php create mode 100644 php85/php_zip_arginfo.h create mode 100644 php85/zip_stream.c diff --git a/config.m4 b/config.m4 index 9ea6130..9d5e0c7 100644 --- a/config.m4 +++ b/config.m4 @@ -36,6 +36,9 @@ if test "$PHP_ZIP" != "no"; then elif test $PHP_VERSION -lt 80500; then AC_MSG_RESULT(8.1/8.2/8.3/8.4) subdir=php81 + elif test $PHP_VERSION -lt 80600; then + AC_MSG_RESULT(8.5) + subdir=php85 else AC_MSG_ERROR(PHP version $PHP_VERSION is not supported yet) fi diff --git a/config.w32 b/config.w32 index d6f0917..0345aae 100644 --- a/config.w32 +++ b/config.w32 @@ -36,6 +36,8 @@ if (PHP_ZIP != "no") { configure_module_dirname = configure_module_dirname + "\\php81"; } else if (PHP_VERSION == 8 && PHP_MINOR_VERSION == 4) { configure_module_dirname = configure_module_dirname + "\\php81"; + } else if (PHP_VERSION == 8 && PHP_MINOR_VERSION == 5) { + configure_module_dirname = configure_module_dirname + "\\php85"; } else { ERROR("PHP " + PHP_VERSION + "." + PHP_MINOR_VERSION + " not supported"); } diff --git a/php85/php_zip.c b/php85/php_zip.c new file mode 100644 index 0000000..450c297 --- /dev/null +++ b/php85/php_zip.c @@ -0,0 +1,3200 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Piere-Alain Joye | + +----------------------------------------------------------------------+ +*/ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "php.h" +#include "ext/standard/info.h" +#include "ext/standard/file.h" +#include "ext/standard/php_string.h" /* For php_basename() */ +#include "ext/pcre/php_pcre.h" +#include "ext/standard/php_filestat.h" +#include "zend_attributes.h" +#include "zend_interfaces.h" +#include "php_zip.h" +#include "php_zip_arginfo.h" + +#include "php_glob.h" + +/* {{{ Resource le */ +static int le_zip_dir; +#define le_zip_dir_name "Zip Directory" +static int le_zip_entry; +#define le_zip_entry_name "Zip Entry" +/* }}} */ + +/* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */ +#define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \ + if (zip_stat_index(za, index, flags, &sb) != 0) { \ + RETURN_FALSE; \ + } +/* }}} */ + +/* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) + This is always used for the first argument*/ +#define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \ + if (path_len == 0) { \ + zend_argument_must_not_be_empty_error(1); \ + RETURN_THROWS(); \ + } \ + if (zip_stat(za, path, flags, &sb) != 0) { \ + RETURN_FALSE; \ + } +/* }}} */ + +/* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */ +#define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \ + if (comment_len == 0) { \ + /* Passing NULL remove the existing comment */ \ + if (zip_file_set_comment(za, index, NULL, 0, 0) < 0) { \ + RETURN_FALSE; \ + } \ + } else if (zip_file_set_comment(za, index, comment, comment_len, 0) < 0) { \ + RETURN_FALSE; \ + } \ + RETURN_TRUE; +/* }}} */ + +# define add_ascii_assoc_string add_assoc_string +# define add_ascii_assoc_long add_assoc_long + +/* Flatten a path by making a relative path (to .)*/ +static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */ +{ + char *path_begin = path; + size_t i; + + if (path_len < 1 || path == NULL) { + return NULL; + } + + if (IS_ABSOLUTE_PATH(path, path_len)) { + return path + COPY_WHEN_ABSOLUTE(path) + 1; + } + + i = path_len; + + while (1) { + while (i > 0 && !IS_SLASH(path[i])) { + i--; + } + + if (!i) { + return path; + } + + if (i >= 2 && path[i -1] == '.') { + /* i is the position of ., add 1 for / */ + path_begin = path + i + 1; + break; + } + i--; + } + + return path_begin; +} +/* }}} */ + +# define CWD_STATE_ALLOC(l) emalloc(l) +# define CWD_STATE_FREE(s) efree(s) + +/* {{{ php_zip_extract_file */ +static int php_zip_extract_file(struct zip * za, char *dest, const char *file, size_t file_len, zip_int64_t idx) +{ + php_stream_statbuf ssb; + struct zip_file *zf; + struct zip_stat sb; + char b[8192]; + int n, ret; + php_stream *stream; + char *fullpath; + char *file_dirname_fullpath; + char file_dirname[MAXPATHLEN]; + size_t dir_len, len; + int is_dir_only = 0; + char *path_cleaned; + size_t path_cleaned_len; + cwd_state new_state; + zend_string *file_basename; + + if (idx < 0) { + idx = zip_name_locate(za, file, 0); + if (idx < 0) { + return 0; + } + } + new_state.cwd = CWD_STATE_ALLOC(1); + new_state.cwd[0] = '\0'; + new_state.cwd_length = 0; + + /* Clean/normlize the path and then transform any path (absolute or relative) + to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt) + */ + virtual_file_ex(&new_state, file, NULL, CWD_EXPAND); + path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length); + if(!path_cleaned) { + CWD_STATE_FREE(new_state.cwd); + return 0; + } + path_cleaned_len = strlen(path_cleaned); + + if (path_cleaned_len >= MAXPATHLEN || zip_stat_index(za, idx, 0, &sb) != 0) { + CWD_STATE_FREE(new_state.cwd); + return 0; + } + + /* it is a directory only, see #40228 */ + if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) { + len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, path_cleaned); + is_dir_only = 1; + } else { + memcpy(file_dirname, path_cleaned, path_cleaned_len); + dir_len = zend_dirname(file_dirname, path_cleaned_len); + + if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) { + len = spprintf(&file_dirname_fullpath, 0, "%s", dest); + } else { + len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname); + } + + file_basename = php_basename(path_cleaned, path_cleaned_len, NULL, 0); + + if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { + efree(file_dirname_fullpath); + zend_string_release_ex(file_basename, 0); + CWD_STATE_FREE(new_state.cwd); + return 0; + } + } + + /* let see if the path already exists */ + if (php_stream_stat_path_ex(file_dirname_fullpath, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) { + ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL); + if (!ret) { + efree(file_dirname_fullpath); + if (!is_dir_only) { + zend_string_release_ex(file_basename, 0); + } + CWD_STATE_FREE(new_state.cwd); + return 0; + } + } + + /* it is a standalone directory, job done */ + if (is_dir_only) { + efree(file_dirname_fullpath); + CWD_STATE_FREE(new_state.cwd); + return 1; + } + + len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, ZSTR_VAL(file_basename)); + if (!len) { + efree(file_dirname_fullpath); + zend_string_release_ex(file_basename, 0); + CWD_STATE_FREE(new_state.cwd); + return 0; + } else if (len > MAXPATHLEN) { + php_error_docref(NULL, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); + efree(file_dirname_fullpath); + zend_string_release_ex(file_basename, 0); + CWD_STATE_FREE(new_state.cwd); + return 0; + } + + /* check again the full path, not sure if it + * is required, does a file can have a different + * safemode status as its parent folder? + */ + if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) { + efree(fullpath); + efree(file_dirname_fullpath); + zend_string_release_ex(file_basename, 0); + CWD_STATE_FREE(new_state.cwd); + return 0; + } + + zf = zip_fopen_index(za, idx, 0); + if (zf == NULL) { + n = -1; + goto done; + } + + stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL); + + if (stream == NULL) { + n = -1; + zip_fclose(zf); + goto done; + } + + n = 0; + + while ((n=zip_fread(zf, b, sizeof(b))) > 0) { + php_stream_write(stream, b, n); + } + + if (stream->wrapper->wops->stream_metadata) { + struct utimbuf ut; + + ut.modtime = ut.actime = sb.mtime; + stream->wrapper->wops->stream_metadata(stream->wrapper, fullpath, PHP_STREAM_META_TOUCH, &ut, NULL); + } + + php_stream_close(stream); + n = zip_fclose(zf); + +done: + efree(fullpath); + zend_string_release_ex(file_basename, 0); + efree(file_dirname_fullpath); + CWD_STATE_FREE(new_state.cwd); + + if (n<0) { + return 0; + } else { + return 1; + } +} +/* }}} */ + +static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t filename_len, + char *entry_name, size_t entry_name_len, /* unused if replace >= 0 */ + zip_uint64_t offset_start, zip_uint64_t offset_len, + zend_long replace, /* index to replace, add new file if < 0 */ + zip_flags_t flags +) /* {{{ */ +{ + struct zip_source *zs; + char resolved_path[MAXPATHLEN]; + php_stream_statbuf ssb; + + if (ZIP_OPENBASEDIR_CHECKPATH(filename)) { + return -1; + } + + if (!expand_filepath(filename, resolved_path)) { + php_error_docref(NULL, E_WARNING, "No such file or directory"); + return -1; + } + + if (php_stream_stat_path_ex(resolved_path, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL)) { + php_error_docref(NULL, E_WARNING, "No such file or directory"); + return -1; + } + + if (flags & ZIP_FL_OPEN_FILE_NOW) { + FILE *fd; + fd = fopen(resolved_path, "rb"); + if (!fd) { + return -1; + } + flags ^= ZIP_FL_OPEN_FILE_NOW; + zs = zip_source_filep(obj->za, fd, offset_start, offset_len); + } else { + zs = zip_source_file(obj->za, resolved_path, offset_start, offset_len); + } + if (!zs) { + return -1; + } + /* Replace */ + if (replace >= 0) { + if (zip_file_replace(obj->za, replace, zs, flags) < 0) { + zip_source_free(zs); + return -1; + } + zip_error_clear(obj->za); + return 1; + } + /* Add */ + obj->last_id = zip_file_add(obj->za, entry_name, zs, flags); + if (obj->last_id < 0) { + zip_source_free(zs); + return -1; + } + zip_error_clear(obj->za); + return 1; +} +/* }}} */ + +typedef struct { + zend_long remove_all_path; + char *remove_path; + size_t remove_path_len; + char *add_path; + size_t add_path_len; + zip_flags_t flags; + zip_int32_t comp_method; + zip_uint32_t comp_flags; +#ifdef HAVE_ENCRYPTION + zip_int16_t enc_method; + char *enc_password; +#endif +} zip_options; + +/* Expects opts to be zero-initialized. */ +static int php_zip_parse_options(HashTable *options, zip_options *opts) +/* {{{ */ +{ + zval *option; + + /* default values */ + opts->flags = ZIP_FL_OVERWRITE; + opts->comp_method = -1; /* -1 to not change default */ +#ifdef HAVE_ENCRYPTION + opts->enc_method = -1; /* -1 to not change default */ +#endif + + if ((option = zend_hash_str_find(options, "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_FALSE && Z_TYPE_P(option) != IS_TRUE) { + php_error_docref(NULL, E_WARNING, "Option \"remove_all_path\" must be of type bool, %s given", + zend_zval_value_name(option)); + } + opts->remove_all_path = zval_get_long(option); + } + + if ((option = zend_hash_str_find(options, "comp_method", sizeof("comp_method") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_LONG) { + php_error_docref(NULL, E_WARNING, "Option \"comp_method\" must be of type int, %s given", + zend_zval_value_name(option)); + } + opts->comp_method = zval_get_long(option); + + if ((option = zend_hash_str_find(options, "comp_flags", sizeof("comp_flags") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_LONG) { + php_error_docref(NULL, E_WARNING, "Option \"comp_flags\" must be of type int, %s given", + zend_zval_value_name(option)); + } + opts->comp_flags = zval_get_long(option); + } + } + +#ifdef HAVE_ENCRYPTION + if ((option = zend_hash_str_find(options, "enc_method", sizeof("enc_method") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_LONG) { + php_error_docref(NULL, E_WARNING, "Option \"enc_method\" must be of type int, %s given", + zend_zval_value_name(option)); + } + opts->enc_method = zval_get_long(option); + + if ((option = zend_hash_str_find(options, "enc_password", sizeof("enc_password") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_STRING) { + zend_type_error("Option \"enc_password\" must be of type string, %s given", + zend_zval_value_name(option)); + return -1; + } + opts->enc_password = Z_STRVAL_P(option); + } + } +#endif + + if ((option = zend_hash_str_find(options, "remove_path", sizeof("remove_path") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_STRING) { + zend_type_error("Option \"remove_path\" must be of type string, %s given", + zend_zval_value_name(option)); + return -1; + } + + if (Z_STRLEN_P(option) == 0) { + zend_value_error("Option \"remove_path\" must not be empty"); + return -1; + } + + if (Z_STRLEN_P(option) >= MAXPATHLEN) { + zend_value_error("Option \"remove_path\" must be less than %d bytes", MAXPATHLEN - 1); + return -1; + } + opts->remove_path_len = Z_STRLEN_P(option); + opts->remove_path = Z_STRVAL_P(option); + } + + if ((option = zend_hash_str_find(options, "add_path", sizeof("add_path") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_STRING) { + zend_type_error("Option \"add_path\" must be of type string, %s given", + zend_zval_value_name(option)); + return -1; + } + + if (Z_STRLEN_P(option) == 0) { + zend_value_error("Option \"add_path\" must not be empty"); + return -1; + } + + if (Z_STRLEN_P(option) >= MAXPATHLEN) { + zend_value_error("Option \"add_path\" must be less than %d bytes", MAXPATHLEN - 1); + return -1; + } + opts->add_path_len = Z_STRLEN_P(option); + opts->add_path = Z_STRVAL_P(option); + } + + if ((option = zend_hash_str_find(options, "flags", sizeof("flags") - 1)) != NULL) { + if (Z_TYPE_P(option) != IS_LONG) { + zend_type_error("Option \"flags\" must be of type int, %s given", + zend_zval_value_name(option)); + return -1; + } + opts->flags = Z_LVAL_P(option); + } + + return 1; +} +/* }}} */ + +/* {{{ ZIP_FROM_OBJECT */ +#define ZIP_FROM_OBJECT(intern, object) \ + { \ + ze_zip_object *obj = Z_ZIP_P(object); \ + intern = obj->za; \ + if (!intern) { \ + zend_value_error("Invalid or uninitialized Zip object"); \ + RETURN_THROWS(); \ + } \ + } +/* }}} */ + +/* {{{ RETURN_SB(sb) */ +#ifdef HAVE_ENCRYPTION +#define RETURN_SB(sb) \ + { \ + array_init(return_value); \ + add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \ + add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \ + add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \ + add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \ + add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \ + add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \ + add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \ + add_ascii_assoc_long(return_value, "encryption_method", (zend_long) (sb)->encryption_method); \ + } +#else +#define RETURN_SB(sb) \ + { \ + array_init(return_value); \ + add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \ + add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \ + add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \ + add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \ + add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \ + add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \ + add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \ + } +#endif +/* }}} */ + +static zend_long php_zip_status(ze_zip_object *obj) /* {{{ */ +{ + int zep = obj->err_zip; /* saved err if closed */ + + if (obj->za) { +#if LIBZIP_VERSION_MAJOR < 1 + int syp; + + zip_error_get(obj->za, &zep, &syp); +#else + zip_error_t *err; + + err = zip_get_error(obj->za); + zep = zip_error_code_zip(err); + zip_error_fini(err); +#endif + } + return zep; +} +/* }}} */ + +static zend_long php_zip_last_id(ze_zip_object *obj) /* {{{ */ +{ + return obj->last_id; +} +/* }}} */ + +static zend_long php_zip_status_sys(ze_zip_object *obj) /* {{{ */ +{ + int syp = obj->err_sys; /* saved err if closed */ + + if (obj->za) { +#if LIBZIP_VERSION_MAJOR < 1 + int zep; + + zip_error_get(obj->za, &zep, &syp); +#else + zip_error_t *err; + + err = zip_get_error(obj->za); + syp = zip_error_code_system(err); + zip_error_fini(err); +#endif + } + return syp; +} +/* }}} */ + +static zend_long php_zip_get_num_files(ze_zip_object *obj) /* {{{ */ +{ + if (obj->za) { + zip_int64_t num = zip_get_num_entries(obj->za, 0); + return MIN(num, ZEND_LONG_MAX); + } + return 0; +} +/* }}} */ + +static char * php_zipobj_get_filename(ze_zip_object *obj, int *len) /* {{{ */ +{ + if (obj && obj->filename) { + *len = strlen(obj->filename); + return obj->filename; + } + return NULL; +} +/* }}} */ + +static char * php_zipobj_get_zip_comment(ze_zip_object *obj, int *len) /* {{{ */ +{ + if (obj->za) { + return (char *)zip_get_archive_comment(obj->za, len, 0); + } + return NULL; +} +/* }}} */ + +int php_zip_glob(char *pattern, int pattern_len, zend_long flags, zval *return_value) /* {{{ */ +{ + int cwd_skip = 0; +#ifdef ZTS + char cwd[MAXPATHLEN]; + char work_pattern[MAXPATHLEN]; + char *result; +#endif + php_glob_t globbuf; + size_t n; + int ret; + + if (pattern_len >= MAXPATHLEN) { + php_error_docref(NULL, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN); + return -1; + } + + if ((PHP_GLOB_AVAILABLE_FLAGS & flags) != flags) { + + php_error_docref(NULL, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform"); + return -1; + } + +#ifdef ZTS + if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) { + result = VCWD_GETCWD(cwd, MAXPATHLEN); + if (!result) { + cwd[0] = '\0'; + } +#ifdef PHP_WIN32 + if (IS_SLASH(*pattern)) { + cwd[2] = '\0'; + } +#endif + cwd_skip = strlen(cwd)+1; + + snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern); + pattern = work_pattern; + } +#endif + + globbuf.gl_offs = 0; + if (0 != (ret = php_glob(pattern, flags & PHP_GLOB_FLAGMASK, NULL, &globbuf))) { +#ifdef PHP_GLOB_NOMATCH + if (PHP_GLOB_NOMATCH == ret) { + /* Some glob implementation simply return no data if no matches + were found, others return the PHP_GLOB_NOMATCH error code. + We don't want to treat PHP_GLOB_NOMATCH as an error condition + so that PHP glob() behaves the same on both types of + implementations and so that 'foreach (glob() as ...' + can be used for simple glob() calls without further error + checking. + */ + array_init(return_value); + return 0; + } +#endif + return 0; + } + + /* now catch the FreeBSD style of "no matches" */ + if (!globbuf.gl_pathc || !globbuf.gl_pathv) { + array_init(return_value); + return 0; + } + + /* we assume that any glob pattern will match files from one directory only + so checking the dirname of the first match should be sufficient */ + if (ZIP_OPENBASEDIR_CHECKPATH(globbuf.gl_pathv[0])) { + return -1; + } + + array_init(return_value); + for (n = 0; n < globbuf.gl_pathc; n++) { + /* we need to do this every time since PHP_GLOB_ONLYDIR does not guarantee that + * all directories will be filtered. GNU libc documentation states the + * following: + * If the information about the type of the file is easily available + * non-directories will be rejected but no extra work will be done to + * determine the information for each file. I.e., the caller must still be + * able to filter directories out. + */ + if (flags & PHP_GLOB_ONLYDIR) { + zend_stat_t s = {0}; + + if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) { + continue; + } + + if (S_IFDIR != (s.st_mode & S_IFMT)) { + continue; + } + } + add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip); + } + + ret = globbuf.gl_pathc; + php_globfree(&globbuf); + return ret; +} +/* }}} */ + +int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_value) /* {{{ */ +{ +#ifdef ZTS + char cwd[MAXPATHLEN]; + char work_path[MAXPATHLEN]; + char *result; +#endif + int files_cnt; + zend_string **namelist; + pcre2_match_context *mctx = php_pcre_mctx(); + +#ifdef ZTS + if (!IS_ABSOLUTE_PATH(path, path_len)) { + result = VCWD_GETCWD(cwd, MAXPATHLEN); + if (!result) { + cwd[0] = '\0'; + } +#ifdef PHP_WIN32 + if (IS_SLASH(*path)) { + cwd[2] = '\0'; + } +#endif + snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path); + path = work_path; + } +#endif + + if (ZIP_OPENBASEDIR_CHECKPATH(path)) { + return -1; + } + + files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort); + + if (files_cnt > 0) { + pcre2_code *re = NULL; + pcre2_match_data *match_data = NULL; + uint32_t i, capture_count; + int rc; + + re = pcre_get_compiled_regex(regexp, &capture_count); + if (!re) { + for (i = 0; i < files_cnt; i++) { + zend_string_release_ex(namelist[i], 0); + } + efree(namelist); + php_error_docref(NULL, E_WARNING, "Invalid expression"); + return -1; + } + + array_init(return_value); + + /* only the files, directories are ignored */ + for (i = 0; i < files_cnt; i++) { + zend_stat_t s = {0}; + char fullpath[MAXPATHLEN]; + size_t namelist_len = ZSTR_LEN(namelist[i]); + + if ((namelist_len == 1 && ZSTR_VAL(namelist[i])[0] == '.') || + (namelist_len == 2 && ZSTR_VAL(namelist[i])[0] == '.' && ZSTR_VAL(namelist[i])[1] == '.')) { + zend_string_release_ex(namelist[i], 0); + continue; + } + + if ((path_len + namelist_len + 1) >= MAXPATHLEN) { + php_error_docref(NULL, E_WARNING, "add_path string too long (max: %u, %zu given)", + MAXPATHLEN - 1, (path_len + namelist_len + 1)); + zend_string_release_ex(namelist[i], 0); + break; + } + + match_data = php_pcre_create_match_data(capture_count, re); + if (!match_data) { + /* Allocation failed, but can proceed to the next pattern. */ + zend_string_release_ex(namelist[i], 0); + continue; + } + rc = pcre2_match(re, (PCRE2_SPTR)ZSTR_VAL(namelist[i]), ZSTR_LEN(namelist[i]), 0, 0, match_data, mctx); + php_pcre_free_match_data(match_data); + /* 0 means that the vector is too small to hold all the captured substring offsets */ + if (rc < 0) { + zend_string_release_ex(namelist[i], 0); + continue; + } + + snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, ZSTR_VAL(namelist[i])); + + if (0 != VCWD_STAT(fullpath, &s)) { + php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath); + zend_string_release_ex(namelist[i], 0); + continue; + } + + if (S_IFDIR == (s.st_mode & S_IFMT)) { + zend_string_release_ex(namelist[i], 0); + continue; + } + + add_next_index_string(return_value, fullpath); + zend_string_release_ex(namelist[i], 0); + } + efree(namelist); + } + return files_cnt; +} +/* }}} */ + +/* {{{ ZE2 OO definitions */ +static zend_class_entry *zip_class_entry; +static zend_object_handlers zip_object_handlers; + +static HashTable zip_prop_handlers; + +typedef zend_long (*zip_read_int_t)(ze_zip_object *obj); +typedef char *(*zip_read_const_char_t)(ze_zip_object *obj, int *len); + +typedef struct _zip_prop_handler { + zip_read_int_t read_int_func; + zip_read_const_char_t read_const_char_func; + + int type; +} zip_prop_handler; +/* }}} */ + +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, int rettype) /* {{{ */ +{ + zip_prop_handler hnd; + zend_string *str; + + hnd.read_const_char_func = read_char_func; + hnd.read_int_func = read_int_func; + hnd.type = rettype; + str = zend_string_init_interned(name, strlen(name), 1); + zend_hash_add_mem(prop_handler, str, &hnd, sizeof(zip_prop_handler)); + zend_string_release_ex(str, 1); +} +/* }}} */ + +static zval *php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zval *rv) /* {{{ */ +{ + const char *retchar = NULL; + zend_long retint = 0; + int len = 0; + + if (hnd->read_const_char_func) { + retchar = hnd->read_const_char_func(obj, &len); + } else if (hnd->read_int_func) { + retint = hnd->read_int_func(obj); + } + + switch (hnd->type) { + case IS_STRING: + if (retchar) { + ZVAL_STRINGL(rv, (char *) retchar, len); + } else { + ZVAL_EMPTY_STRING(rv); + } + break; + case IS_LONG: + ZVAL_LONG(rv, retint); + break; + default: + ZVAL_NULL(rv); + } + + return rv; +} +/* }}} */ + +static zval *php_zip_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot) /* {{{ */ +{ + ze_zip_object *obj; + zval *retval = NULL; + zip_prop_handler *hnd = NULL; + + obj = php_zip_fetch_object(object); + + if (obj->prop_handler != NULL) { + hnd = zend_hash_find_ptr(obj->prop_handler, name); + } + + if (hnd == NULL) { + retval = zend_std_get_property_ptr_ptr(object, name, type, cache_slot); + } else if (cache_slot) { + cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL; + } + + return retval; +} +/* }}} */ + + +static zval *php_zip_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot) +{ + ze_zip_object *obj; + zip_prop_handler *hnd = NULL; + + obj = php_zip_fetch_object(object); + + if (obj->prop_handler != NULL) { + hnd = zend_hash_find_ptr(obj->prop_handler, name); + } + + if (hnd != NULL) { + zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name)); + return &EG(error_zval); + } + + return zend_std_write_property(object, name, value, cache_slot); +} + +static zval *php_zip_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv) /* {{{ */ +{ + ze_zip_object *obj; + zval *retval = NULL; + zip_prop_handler *hnd = NULL; + + obj = php_zip_fetch_object(object); + + if (obj->prop_handler != NULL) { + hnd = zend_hash_find_ptr(obj->prop_handler, name); + } + + if (hnd != NULL) { + retval = php_zip_property_reader(obj, hnd, rv); + if (retval == NULL) { + retval = &EG(uninitialized_zval); + } + } else { + retval = zend_std_read_property(object, name, type, cache_slot, rv); + } + + return retval; +} +/* }}} */ + +// todo: make php_zip_has_property return bool as well +static int php_zip_has_property(zend_object *object, zend_string *name, int type, void **cache_slot) /* {{{ */ +{ + ze_zip_object *obj; + zip_prop_handler *hnd = NULL; + bool retval = false; + + obj = php_zip_fetch_object(object); + + if (obj->prop_handler != NULL) { + hnd = zend_hash_find_ptr(obj->prop_handler, name); + } + + if (hnd != NULL) { + zval tmp, *prop; + + if (type == 2) { + retval = true; + } else if ((prop = php_zip_property_reader(obj, hnd, &tmp)) != NULL) { + if (type == 1) { + retval = zend_is_true(&tmp); + } else if (type == 0) { + retval = (Z_TYPE(tmp) != IS_NULL); + } + } + + zval_ptr_dtor(&tmp); + } else { + retval = zend_std_has_property(object, name, type, cache_slot); + } + + return retval; +} +/* }}} */ + +static HashTable *php_zip_get_gc(zend_object *object, zval **gc_data, int *gc_data_count) /* {{{ */ +{ + *gc_data = NULL; + *gc_data_count = 0; + return zend_std_get_properties(object); +} +/* }}} */ + +static HashTable *php_zip_get_properties(zend_object *object)/* {{{ */ +{ + ze_zip_object *obj; + HashTable *props; + zip_prop_handler *hnd; + zend_string *key; + + obj = php_zip_fetch_object(object); + props = zend_std_get_properties(object); + + if (obj->prop_handler == NULL) { + return NULL; + } + + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(obj->prop_handler, key, hnd) { + zval *ret, val; + ret = php_zip_property_reader(obj, hnd, &val); + if (ret == NULL) { + ret = &EG(uninitialized_zval); + } + zend_hash_update(props, key, ret); + } ZEND_HASH_FOREACH_END(); + + return props; +} +/* }}} */ + +#ifdef HAVE_PROGRESS_CALLBACK +static void php_zip_progress_callback_free(void *ptr) +{ + ze_zip_object *obj = ptr; + + if (ZEND_FCC_INITIALIZED(obj->progress_callback)) { + zend_fcc_dtor(&obj->progress_callback); + } +} +#endif + +#ifdef HAVE_CANCEL_CALLBACK +static void php_zip_cancel_callback_free(void *ptr) +{ + ze_zip_object *obj = ptr; + + if (ZEND_FCC_INITIALIZED(obj->cancel_callback)) { + zend_fcc_dtor(&obj->cancel_callback); + } +} +#endif + +static void php_zip_object_free_storage(zend_object *object) /* {{{ */ +{ + ze_zip_object * intern = php_zip_fetch_object(object); + int i; + + if (intern->za) { + if (zip_close(intern->za) != 0) { + php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(intern->za)); + zip_discard(intern->za); + } + } + + if (intern->buffers_cnt>0) { + for (i=0; ibuffers_cnt; i++) { + efree(intern->buffers[i]); + } + efree(intern->buffers); + } + +#ifdef HAVE_PROGRESS_CALLBACK + /* if not properly called by libzip */ + php_zip_progress_callback_free(intern); +#endif + +#ifdef HAVE_CANCEL_CALLBACK + /* if not properly called by libzip */ + php_zip_cancel_callback_free(intern); +#endif + + intern->za = NULL; + zend_object_std_dtor(&intern->zo); + + if (intern->filename) { + efree(intern->filename); + } +} +/* }}} */ + +static zend_object *php_zip_object_new(zend_class_entry *class_type) /* {{{ */ +{ + ze_zip_object *intern; + + intern = zend_object_alloc(sizeof(ze_zip_object), class_type); + intern->prop_handler = &zip_prop_handlers; + zend_object_std_init(&intern->zo, class_type); + object_properties_init(&intern->zo, class_type); + intern->last_id = -1; + + return &intern->zo; +} +/* }}} */ + +/* {{{ Resource dtors */ + +/* {{{ php_zip_free_dir */ +static void php_zip_free_dir(zend_resource *rsrc) +{ + zip_rsrc * zip_int = (zip_rsrc *) rsrc->ptr; + + if (zip_int) { + if (zip_int->za) { + if (zip_close(zip_int->za) != 0) { + php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context"); + } + zip_int->za = NULL; + } + + efree(rsrc->ptr); + + rsrc->ptr = NULL; + } +} +/* }}} */ + +/* {{{ php_zip_free_entry */ +static void php_zip_free_entry(zend_resource *rsrc) +{ + zip_read_rsrc *zr_rsrc = (zip_read_rsrc *) rsrc->ptr; + + if (zr_rsrc) { + if (zr_rsrc->zf) { + zip_fclose(zr_rsrc->zf); + zr_rsrc->zf = NULL; + } + efree(zr_rsrc); + rsrc->ptr = NULL; + } +} +/* }}} */ + +/* }}}*/ + +/* reset macro */ + +/* {{{ function prototypes */ +static PHP_MINIT_FUNCTION(zip); +static PHP_MSHUTDOWN_FUNCTION(zip); +static PHP_MINFO_FUNCTION(zip); +/* }}} */ + +static const zend_module_dep zip_deps[] = { + ZEND_MOD_REQUIRED("pcre") + ZEND_MOD_END +}; + +/* {{{ zip_module_entry */ +zend_module_entry zip_module_entry = { + STANDARD_MODULE_HEADER_EX, NULL, + zip_deps, + "zip", + ext_functions, + PHP_MINIT(zip), + PHP_MSHUTDOWN(zip), + NULL, + NULL, + PHP_MINFO(zip), + PHP_ZIP_VERSION, + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_ZIP +ZEND_GET_MODULE(zip) +#endif +/* set macro */ + +/* {{{ Create new zip using source uri for output */ +PHP_FUNCTION(zip_open) +{ + char resolved_path[MAXPATHLEN + 1]; + zip_rsrc *rsrc_int; + int err = 0; + zend_string *filename; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) { + RETURN_THROWS(); + } + + if (ZSTR_LEN(filename) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) { + RETURN_FALSE; + } + + if(!expand_filepath(ZSTR_VAL(filename), resolved_path)) { + php_error_docref(NULL, E_WARNING, "No such file or directory"); + RETURN_FALSE; + } + + rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc)); + + rsrc_int->za = zip_open(resolved_path, 0, &err); + if (rsrc_int->za == NULL) { + efree(rsrc_int); + RETURN_LONG((zend_long)err); + } + + rsrc_int->index_current = 0; + rsrc_int->num_files = zip_get_num_entries(rsrc_int->za, 0); + + RETURN_RES(zend_register_resource(rsrc_int, le_zip_dir)); +} +/* }}} */ + +/* {{{ Close a Zip archive */ +PHP_FUNCTION(zip_close) +{ + zval * zip; + zip_rsrc *z_rsrc = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip) == FAILURE) { + RETURN_THROWS(); + } + + if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) { + RETURN_THROWS(); + } + + /* really close the zip will break BC :-D */ + zend_list_close(Z_RES_P(zip)); +} +/* }}} */ + +/* {{{ Returns the next file in the archive */ +PHP_FUNCTION(zip_read) +{ + zval *zip_dp; + zip_read_rsrc *zr_rsrc; + int ret; + zip_rsrc *rsrc_int; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_dp) == FAILURE) { + RETURN_THROWS(); + } + + if ((rsrc_int = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip_dp), le_zip_dir_name, le_zip_dir)) == NULL) { + RETURN_THROWS(); + } + + if (rsrc_int && rsrc_int->za) { + if (rsrc_int->index_current >= rsrc_int->num_files) { + RETURN_FALSE; + } + + zr_rsrc = emalloc(sizeof(zip_read_rsrc)); + + ret = zip_stat_index(rsrc_int->za, rsrc_int->index_current, 0, &zr_rsrc->sb); + + if (ret != 0) { + efree(zr_rsrc); + RETURN_FALSE; + } + + zr_rsrc->zip_rsrc_handle = Z_RES_P(zip_dp)->handle; + zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0); + if (zr_rsrc->zf) { + rsrc_int->index_current++; + RETURN_RES(zend_register_resource(zr_rsrc, le_zip_entry)); + } else { + efree(zr_rsrc); + RETURN_FALSE; + } + + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Open a Zip File, pointed by the resource entry */ +/* Dummy function to follow the old API */ +PHP_FUNCTION(zip_entry_open) +{ + zval * zip; + zval * zip_entry; + char *mode = NULL; + size_t mode_len = 0; + zip_read_rsrc * zr_rsrc; + zip_rsrc *z_rsrc; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|s", &zip, &zip_entry, &mode, &mode_len) == FAILURE) { + RETURN_THROWS(); + } + + if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) { + RETURN_THROWS(); + } + + if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) { + RETURN_THROWS(); + } + + if (zr_rsrc->zf != NULL) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Close a zip entry */ +PHP_FUNCTION(zip_entry_close) +{ + zval * zip_entry; + zip_read_rsrc * zr_rsrc; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) { + RETURN_THROWS(); + } + + if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) { + RETURN_THROWS(); + } + + zend_list_close(Z_RES_P(zip_entry)); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Read from an open directory entry */ +PHP_FUNCTION(zip_entry_read) +{ + zval * zip_entry; + zend_long len = 0; + zip_read_rsrc * zr_rsrc; + zend_string *buffer; + int n = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &zip_entry, &len) == FAILURE) { + RETURN_THROWS(); + } + + if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) { + RETURN_THROWS(); + } + + if (len <= 0) { + len = 1024; + } + + if (zr_rsrc->zf) { + buffer = zend_string_safe_alloc(1, len, 0, 0); + n = zip_fread(zr_rsrc->zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); + if (n > 0) { + ZSTR_VAL(buffer)[n] = '\0'; + ZSTR_LEN(buffer) = n; + RETURN_NEW_STR(buffer); + } else { + zend_string_efree(buffer); + RETURN_EMPTY_STRING(); + } + } else { + RETURN_FALSE; + } +} +/* }}} */ + +static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ */ +{ + zval * zip_entry; + zip_read_rsrc * zr_rsrc; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) { + RETURN_THROWS(); + } + + if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) { + RETURN_THROWS(); + } + + if (!zr_rsrc->zf || !zend_hash_index_exists(&EG(regular_list), zr_rsrc->zip_rsrc_handle)) { + RETURN_FALSE; + } + + switch (opt) { + case 0: + RETURN_STRING((char *)zr_rsrc->sb.name); + case 1: + RETURN_LONG((zend_long) (zr_rsrc->sb.comp_size)); + case 2: + RETURN_LONG((zend_long) (zr_rsrc->sb.size)); + case 3: + switch (zr_rsrc->sb.comp_method) { + case 0: + RETURN_STRING("stored"); + case 1: + RETURN_STRING("shrunk"); + case 2: + case 3: + case 4: + case 5: + RETURN_STRING("reduced"); + case 6: + RETURN_STRING("imploded"); + case 7: + RETURN_STRING("tokenized"); + break; + case 8: + RETURN_STRING("deflated"); + case 9: + RETURN_STRING("deflatedX"); + break; + case 10: + RETURN_STRING("implodedX"); + default: + RETURN_FALSE; + } + } + +} +/* }}} */ + +/* {{{ Return the name given a ZZip entry */ +PHP_FUNCTION(zip_entry_name) +{ + php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Return the compressed size of a ZZip entry */ +PHP_FUNCTION(zip_entry_compressedsize) +{ + php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ Return the actual filesize of a ZZip entry */ +PHP_FUNCTION(zip_entry_filesize) +{ + php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); +} +/* }}} */ + +/* {{{ Return a string containing the compression method used on a particular entry */ +PHP_FUNCTION(zip_entry_compressionmethod) +{ + php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3); +} +/* }}} */ + +/* {{{ Create new zip using source uri for output, return TRUE on success or the error code */ +PHP_METHOD(ZipArchive, open) +{ + struct zip *intern; + int err = 0; + zend_long flags = 0; + char *resolved_path; + zend_string *filename; + zval *self = ZEND_THIS; + ze_zip_object *ze_obj; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &filename, &flags) == FAILURE) { + RETURN_THROWS(); + } + + /* We do not use ZIP_FROM_OBJECT, zip init function here */ + ze_obj = Z_ZIP_P(self); + + if (ZSTR_LEN(filename) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) { + RETURN_FALSE; + } + + if (!(resolved_path = expand_filepath(ZSTR_VAL(filename), NULL))) { + php_error_docref(NULL, E_WARNING, "No such file or directory"); + RETURN_FALSE; + } + + if (ze_obj->za) { + /* we already have an opened zip, free it */ + if (zip_close(ze_obj->za) != 0) { + php_error_docref(NULL, E_WARNING, "Empty string as source"); + efree(resolved_path); + RETURN_FALSE; + } + ze_obj->za = NULL; + } + if (ze_obj->filename) { + efree(ze_obj->filename); + ze_obj->filename = NULL; + } + + /* open for write without option to empty the archive */ +#ifdef ZIP_RDONLY + if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) { +#else + if ((flags & ZIP_TRUNCATE) == 0) { +#endif + zend_stat_t st = {0}; + + /* exists and is empty */ + if (VCWD_STAT(resolved_path, &st) == 0 && st.st_size == 0) { + php_error_docref(NULL, E_DEPRECATED, "Using empty file as ZipArchive is deprecated"); + + /* reduce BC break introduced in libzip 1.6.0 + "Do not accept empty files as valid zip archives any longer" */ + flags |= ZIP_TRUNCATE; + } + } + + intern = zip_open(resolved_path, flags, &err); + if (!intern || err) { + efree(resolved_path); + RETURN_LONG((zend_long)err); + } + ze_obj->filename = resolved_path; + ze_obj->filename_len = strlen(resolved_path); + ze_obj->za = intern; + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Set the password for the active archive */ +PHP_METHOD(ZipArchive, setPassword) +{ + struct zip *intern; + zval *self = ZEND_THIS; + char *password; + size_t password_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &password, &password_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (password_len < 1) { + RETURN_FALSE; + } + + int res = zip_set_default_password(intern, (const char *)password); + if (res == 0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ close the zip archive */ +PHP_METHOD(ZipArchive, close) +{ + struct zip *intern; + zval *self = ZEND_THIS; + ze_zip_object *ze_obj; + int err; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + ze_obj = Z_ZIP_P(self); + + err = zip_close(intern); + if (err) { + php_error_docref(NULL, E_WARNING, "%s", zip_strerror(intern)); + /* Save error for property reader */ + #if LIBZIP_VERSION_MAJOR < 1 + zip_error_get(intern, &ze_obj->err_zip, &ze_obj->err_sys); + #else + { + zip_error_t *ziperr; + + ziperr = zip_get_error(intern); + ze_obj->err_zip = zip_error_code_zip(ziperr); + ze_obj->err_sys = zip_error_code_system(ziperr); + zip_error_fini(ziperr); + } + #endif + zip_discard(intern); + } else { + ze_obj->err_zip = 0; + ze_obj->err_sys = 0; + } + + /* clear cache as empty zip are not created but deleted */ + php_clear_stat_cache(1, ze_obj->filename, ze_obj->filename_len); + + efree(ze_obj->filename); + ze_obj->filename = NULL; + ze_obj->filename_len = 0; + ze_obj->za = NULL; + + if (!err) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ close the zip archive */ +PHP_METHOD(ZipArchive, count) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zip_int64_t num; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + num = zip_get_num_entries(intern, 0); + RETVAL_LONG(MIN(num, ZEND_LONG_MAX)); +} +/* }}} */ + +/* {{{ clear the internal status */ +PHP_METHOD(ZipArchive, clearError) +{ + zval *self = ZEND_THIS; + ze_zip_object *ze_obj; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */ + if (ze_obj->za) { + zip_error_clear(ze_obj->za); + } else { + ze_obj->err_zip = 0; + ze_obj->err_sys = 0; + } +} +/* }}} */ + +/* {{{ Returns the status error message, system and/or zip messages */ +PHP_METHOD(ZipArchive, getStatusString) +{ + zval *self = ZEND_THIS; +#if LIBZIP_VERSION_MAJOR < 1 + int zep, syp, len; + char error_string[128]; +#endif + ze_zip_object *ze_obj; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */ + +#if LIBZIP_VERSION_MAJOR < 1 + if (ze_obj->za) { + zip_error_get(ze_obj->za, &zep, &syp); + len = zip_error_to_str(error_string, 128, zep, syp); + } else { + len = zip_error_to_str(error_string, 128, ze_obj->err_zip, ze_obj->err_sys); + } + RETVAL_STRINGL(error_string, len); +#else + if (ze_obj->za) { + zip_error_t *err; + + err = zip_get_error(ze_obj->za); + RETVAL_STRING(zip_error_strerror(err)); + zip_error_fini(err); + } else { + zip_error_t err; + + zip_error_init(&err); + zip_error_set(&err, ze_obj->err_zip, ze_obj->err_sys); + RETVAL_STRING(zip_error_strerror(&err)); + zip_error_fini(&err); + } +#endif +} +/* }}} */ + +/* {{{ Returns the index of the entry named filename in the archive */ +PHP_METHOD(ZipArchive, addEmptyDir) +{ + struct zip *intern; + zval *self = ZEND_THIS; + char *dirname; + size_t dirname_len; + char *s; + zend_long flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", + &dirname, &dirname_len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (dirname_len<1) { + RETURN_FALSE; + } + + if (dirname[dirname_len-1] != '/') { + s=(char *)safe_emalloc(dirname_len, 1, 2); + strcpy(s, dirname); + s[dirname_len] = '/'; + s[dirname_len+1] = '\0'; + } else { + s = dirname; + } + + if ((Z_ZIP_P(self)->last_id = zip_dir_add(intern, (const char *)s, flags)) == -1) { + RETVAL_FALSE; + } else { + zip_error_clear(intern); + RETVAL_TRUE; + } + + if (s != dirname) { + efree(s); + } +} +/* }}} */ + +static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ +{ + zval *self = ZEND_THIS; + char *path = "."; + size_t path_len = 1; + zend_long glob_flags = 0; + HashTable *options = NULL; + zip_options opts = {0}; + int found; + zend_string *pattern; + + /* 1 == glob, 2 == pcre */ + if (type == 1) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|lh", + &pattern, &glob_flags, &options) == FAILURE) { + RETURN_THROWS(); + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sh", + &pattern, &path, &path_len, &options) == FAILURE) { + RETURN_THROWS(); + } + } + + if (ZSTR_LEN(pattern) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + if (options && zend_hash_num_elements(options) > 0 && (php_zip_parse_options(options, &opts) < 0)) { + RETURN_THROWS(); + } + + if (type == 1) { + found = php_zip_glob(ZSTR_VAL(pattern), ZSTR_LEN(pattern), glob_flags, return_value); + } else { + found = php_zip_pcre(pattern, path, path_len, return_value); + } + + if (found > 0) { + int i; + zval *zval_file; + ze_zip_object *ze_obj; + + ze_obj = Z_ZIP_P(self); + + for (i = 0; i < found; i++) { + char *file_stripped, *entry_name; + size_t entry_name_len, file_stripped_len; + char entry_name_buf[MAXPATHLEN]; + zend_string *basename = NULL; + + if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(return_value), i)) != NULL) { + if (opts.remove_all_path) { + basename = php_basename(Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), NULL, 0); + file_stripped = ZSTR_VAL(basename); + file_stripped_len = ZSTR_LEN(basename); + } else if (opts.remove_path && !memcmp(Z_STRVAL_P(zval_file), opts.remove_path, opts.remove_path_len)) { + if (IS_SLASH(Z_STRVAL_P(zval_file)[opts.remove_path_len])) { + file_stripped = Z_STRVAL_P(zval_file) + opts.remove_path_len + 1; + file_stripped_len = Z_STRLEN_P(zval_file) - opts.remove_path_len - 1; + } else { + file_stripped = Z_STRVAL_P(zval_file) + opts.remove_path_len; + file_stripped_len = Z_STRLEN_P(zval_file) - opts.remove_path_len; + } + } else { + file_stripped = Z_STRVAL_P(zval_file); + file_stripped_len = Z_STRLEN_P(zval_file); + } + + if (opts.add_path) { + if ((opts.add_path_len + file_stripped_len) > MAXPATHLEN) { + if (basename) { + zend_string_release_ex(basename, 0); + } + php_error_docref(NULL, E_WARNING, "Entry name too long (max: %d, %zd given)", + MAXPATHLEN - 1, (opts.add_path_len + file_stripped_len)); + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } + snprintf(entry_name_buf, MAXPATHLEN, "%s%s", opts.add_path, file_stripped); + } else { + snprintf(entry_name_buf, MAXPATHLEN, "%s", file_stripped); + } + + entry_name = entry_name_buf; + entry_name_len = strlen(entry_name); + if (basename) { + zend_string_release_ex(basename, 0); + basename = NULL; + } + + if (php_zip_add_file(ze_obj, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), + entry_name, entry_name_len, 0, 0, -1, opts.flags) < 0) { + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } + if (opts.comp_method >= 0) { + if (zip_set_file_compression(ze_obj->za, ze_obj->last_id, opts.comp_method, opts.comp_flags)) { + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } + } +#ifdef HAVE_ENCRYPTION + if (opts.enc_method >= 0) { + if (zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) { + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } + } +#endif + } + } + } else if (found == 0) { + RETURN_EMPTY_ARRAY(); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Add files matching the glob pattern. See php's glob for the pattern syntax. */ +PHP_METHOD(ZipArchive, addGlob) +{ + php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ Add files matching the pcre pattern. See php's pcre for the pattern syntax. */ +PHP_METHOD(ZipArchive, addPattern) +{ + php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); +} +/* }}} */ + +/* {{{ Add a file in a Zip archive using its path and the name to use. */ +PHP_METHOD(ZipArchive, addFile) +{ + zval *self = ZEND_THIS; + char *entry_name = NULL; + size_t entry_name_len = 0; + zend_long offset_start = 0, offset_len = 0; + zend_string *filename; + zend_long flags = ZIP_FL_OVERWRITE; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|slll", + &filename, &entry_name, &entry_name_len, &offset_start, &offset_len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + if (ZSTR_LEN(filename) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + if (entry_name_len == 0) { + entry_name = ZSTR_VAL(filename); + entry_name_len = ZSTR_LEN(filename); + } + + if (php_zip_add_file(Z_ZIP_P(self), ZSTR_VAL(filename), ZSTR_LEN(filename), + entry_name, entry_name_len, offset_start, offset_len, -1, flags) < 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Add a file in a Zip archive using its path and the name to use. */ +PHP_METHOD(ZipArchive, replaceFile) +{ + zval *self = ZEND_THIS; + zend_long index; + zend_long offset_start = 0, offset_len = 0; + zend_string *filename; + zend_long flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Pl|lll", + &filename, &index, &offset_start, &offset_len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + if (ZSTR_LEN(filename) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + if (index < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + if (php_zip_add_file(Z_ZIP_P(self), ZSTR_VAL(filename), ZSTR_LEN(filename), + NULL, 0, offset_start, offset_len, index, flags) < 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Add a file using content and the entry name */ +PHP_METHOD(ZipArchive, addFromString) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_string *buffer; + char *name; + size_t name_len; + ze_zip_object *ze_obj; + struct zip_source *zs; + int pos = 0; + zend_long flags = ZIP_FL_OVERWRITE; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS|l", + &name, &name_len, &buffer, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + ze_obj = Z_ZIP_P(self); + if (ze_obj->buffers_cnt) { + ze_obj->buffers = (char **)safe_erealloc(ze_obj->buffers, sizeof(char *), (ze_obj->buffers_cnt+1), 0); + pos = ze_obj->buffers_cnt++; + } else { + ze_obj->buffers = (char **)emalloc(sizeof(char *)); + ze_obj->buffers_cnt++; + pos = 0; + } + ze_obj->buffers[pos] = (char *)safe_emalloc(ZSTR_LEN(buffer), 1, 1); + memcpy(ze_obj->buffers[pos], ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1); + + zs = zip_source_buffer(intern, ze_obj->buffers[pos], ZSTR_LEN(buffer), 0); + + if (zs == NULL) { + RETURN_FALSE; + } + + ze_obj->last_id = zip_file_add(intern, name, zs, flags); + if (ze_obj->last_id == -1) { + zip_source_free(zs); + RETURN_FALSE; + } else { + zip_error_clear(intern); + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Returns the information about a the zip entry filename */ +PHP_METHOD(ZipArchive, statName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long flags = 0; + struct zip_stat sb; + zend_string *name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(name), ZSTR_LEN(name), flags, sb); + + RETURN_SB(&sb); +} +/* }}} */ + +/* {{{ Returns the zip entry information using its index */ +PHP_METHOD(ZipArchive, statIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index, flags = 0; + + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", + &index, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (zip_stat_index(intern, index, flags, &sb) != 0) { + RETURN_FALSE; + } + RETURN_SB(&sb); +} +/* }}} */ + +/* {{{ Returns the index of the entry named filename in the archive */ +PHP_METHOD(ZipArchive, locateName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long flags = 0; + zend_long idx = -1; + zend_string *name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (ZSTR_LEN(name) < 1) { + RETURN_FALSE; + } + + idx = (zend_long)zip_name_locate(intern, (const char *)ZSTR_VAL(name), flags); + + if (idx >= 0) { + RETURN_LONG(idx); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Returns the name of the file at position index */ +PHP_METHOD(ZipArchive, getNameIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + const char *name; + zend_long flags = 0, index = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", + &index, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + name = zip_get_name(intern, (int) index, flags); + + if (name) { + RETVAL_STRING((char *)name); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Set or remove (NULL/'') the comment of the archive */ +PHP_METHOD(ZipArchive, setArchiveComment) +{ + struct zip *intern; + zval *self = ZEND_THIS; + size_t comment_len; + char * comment; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &comment, &comment_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (comment_len > 0xffff) { + zend_argument_value_error(1, "must be less than 65535 bytes"); + RETURN_THROWS(); + } + + if (zip_set_archive_comment(intern, (const char *)comment, comment_len)) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Returns the comment of an entry using its index */ +PHP_METHOD(ZipArchive, getArchiveComment) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long flags = 0; + const char * comment; + int comment_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + comment = zip_get_archive_comment(intern, &comment_len, (int)flags); + if(comment==NULL) { + RETURN_FALSE; + } + RETURN_STRINGL((char *)comment, (zend_long)comment_len); +} +/* }}} */ + +PHP_METHOD(ZipArchive, setArchiveFlag) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long flag, value; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &flag, &value) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (zip_set_archive_flag(intern, flag, (int)value)) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} + +PHP_METHOD(ZipArchive, getArchiveFlag) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long flag, flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &flag, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + RETURN_LONG(zip_get_archive_flag(intern, flag, flags)); +} + +/* {{{ Set or remove (NULL/'') the comment of an entry using its Name */ +PHP_METHOD(ZipArchive, setCommentName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + size_t comment_len, name_len; + char * comment, *name; + int idx; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &name, &name_len, &comment, &comment_len) == FAILURE) { + RETURN_THROWS(); + } + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (comment_len > 0xffff) { + zend_argument_value_error(2, "must be less than 65535 bytes"); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + if (idx < 0) { + RETURN_FALSE; + } + PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len); +} +/* }}} */ + +/* {{{ Set or remove (NULL/'') the comment of an entry using its index */ +PHP_METHOD(ZipArchive, setCommentIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index; + size_t comment_len; + char * comment; + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", + &index, &comment, &comment_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (comment_len > 0xffff) { + zend_argument_value_error(2, "must be less than 65535 bytes"); + RETURN_THROWS(); + } + + PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len); +} +/* }}} */ + +/* those constants/functions are only available in libzip since 0.11.2 */ +#ifdef ZIP_OPSYS_DEFAULT + +/* {{{ Set external attributes for file in zip, using its name */ +PHP_METHOD(ZipArchive, setExternalAttributesName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + size_t name_len; + char *name; + zend_long flags=0, opsys, attr; + zip_int64_t idx; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|l", + &name, &name_len, &opsys, &attr, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + if (zip_file_set_external_attributes(intern, idx, (zip_flags_t)flags, + (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Set external attributes for file in zip, using its index */ +PHP_METHOD(ZipArchive, setExternalAttributesIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index, flags=0, opsys, attr; + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll|l", + &index, &opsys, &attr, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + if (zip_file_set_external_attributes(intern, (zip_uint64_t)index, + (zip_flags_t)flags, (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get external attributes for file in zip, using its name */ +PHP_METHOD(ZipArchive, getExternalAttributesName) +{ + struct zip *intern; + zval *self = ZEND_THIS, *z_opsys, *z_attr; + size_t name_len; + char *name; + zend_long flags=0; + zip_uint8_t opsys; + zip_uint32_t attr; + zip_int64_t idx; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", + &name, &name_len, &z_opsys, &z_attr, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + if (zip_file_get_external_attributes(intern, idx, + (zip_flags_t)flags, &opsys, &attr) < 0) { + RETURN_FALSE; + } + ZEND_TRY_ASSIGN_REF_LONG(z_opsys, opsys); + ZEND_TRY_ASSIGN_REF_LONG(z_attr, attr); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get external attributes for file in zip, using its index */ +PHP_METHOD(ZipArchive, getExternalAttributesIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS, *z_opsys, *z_attr; + zend_long index, flags=0; + zip_uint8_t opsys; + zip_uint32_t attr; + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lzz|l", + &index, &z_opsys, &z_attr, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + if (zip_file_get_external_attributes(intern, (zip_uint64_t)index, + (zip_flags_t)flags, &opsys, &attr) < 0) { + RETURN_FALSE; + } + ZEND_TRY_ASSIGN_REF_LONG(z_opsys, opsys); + ZEND_TRY_ASSIGN_REF_LONG(z_attr, attr); + RETURN_TRUE; +} +/* }}} */ +#endif /* ifdef ZIP_OPSYS_DEFAULT */ + +#ifdef HAVE_ENCRYPTION +/* {{{ Set encryption method for file in zip, using its name */ +PHP_METHOD(ZipArchive, setEncryptionName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long method; + zip_int64_t idx; + char *name, *password = NULL; + size_t name_len, password_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|s!", + &name, &name_len, &method, &password, &password_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + + if (zip_file_set_encryption(intern, idx, (zip_uint16_t)method, password)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Set encryption method for file in zip, using its index */ +PHP_METHOD(ZipArchive, setEncryptionIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index, method; + char *password = NULL; + size_t password_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|s!", + &index, &method, &password, &password_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (zip_file_set_encryption(intern, index, (zip_uint16_t)method, password)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + +/* {{{ Returns the comment of an entry using its name */ +PHP_METHOD(ZipArchive, getCommentName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + size_t name_len; + int idx; + zend_long flags = 0; + zip_uint32_t comment_len = 0; + const char * comment; + char *name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", + &name, &name_len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + + comment = zip_file_get_comment(intern, idx, &comment_len, (zip_flags_t)flags); + RETURN_STRINGL((char *)comment, comment_len); +} +/* }}} */ + +/* {{{ Returns the comment of an entry using its index */ +PHP_METHOD(ZipArchive, getCommentIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index, flags = 0; + const char * comment; + zip_uint32_t comment_len = 0; + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", + &index, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + comment = zip_file_get_comment(intern, index, &comment_len, (zip_flags_t)flags); + RETURN_STRINGL((char *)comment, comment_len); +} +/* }}} */ + +/* {{{ Set the compression of a file in zip, using its name */ +PHP_METHOD(ZipArchive, setCompressionName) +{ + struct zip *intern; + zval *this = ZEND_THIS; + size_t name_len; + char *name; + zip_int64_t idx; + zend_long comp_method, comp_flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l", + &name, &name_len, &comp_method, &comp_flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, this); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + + if (zip_set_file_compression(intern, (zip_uint64_t)idx, + (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Set the compression of a file in zip, using its index */ +PHP_METHOD(ZipArchive, setCompressionIndex) +{ + struct zip *intern; + zval *this = ZEND_THIS; + zend_long index; + zend_long comp_method, comp_flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l", + &index, &comp_method, &comp_flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, this); + + if (zip_set_file_compression(intern, (zip_uint64_t)index, + (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +#ifdef HAVE_SET_MTIME +/* {{{ Set the modification time of a file in zip, using its name */ +PHP_METHOD(ZipArchive, setMtimeName) +{ + struct zip *intern; + zval *this = ZEND_THIS; + size_t name_len; + char *name; + zip_int64_t idx; + zend_long mtime, flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l", + &name, &name_len, &mtime, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, this); + + if (name_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + idx = zip_name_locate(intern, name, 0); + + if (idx < 0) { + RETURN_FALSE; + } + + if (zip_file_set_mtime(intern, (zip_uint64_t)idx, + (time_t)mtime, (zip_uint32_t)flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Set the modification time of a file in zip, using its index */ +PHP_METHOD(ZipArchive, setMtimeIndex) +{ + struct zip *intern; + zval *this = ZEND_THIS; + zend_long index; + zend_long mtime, flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l", + &index, &mtime, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, this); + + if (zip_file_set_mtime(intern, (zip_uint64_t)index, + (time_t)mtime, (zip_uint32_t)flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + +/* {{{ Delete a file using its index */ +PHP_METHOD(ZipArchive, deleteIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (index < 0) { + RETURN_FALSE; + } + + if (zip_delete(intern, index) < 0) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Delete a file using its index */ +PHP_METHOD(ZipArchive, deleteName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + size_t name_len; + char *name; + struct zip_stat sb; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len < 1) { + RETURN_FALSE; + } + + PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); + if (zip_delete(intern, sb.index)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Rename an entry selected by its index to new_name */ +PHP_METHOD(ZipArchive, renameIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + char *new_name; + size_t new_name_len; + zend_long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &index, &new_name, &new_name_len) == FAILURE) { + RETURN_THROWS(); + } + + if (index < 0) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, self); + + if (new_name_len == 0) { + zend_argument_must_not_be_empty_error(2); + RETURN_THROWS(); + } + + if (zip_file_rename(intern, index, (const char *)new_name, 0) != 0) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Rename an entry selected by its name to new_name */ +PHP_METHOD(ZipArchive, renameName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + struct zip_stat sb; + char *name, *new_name; + size_t name_len, new_name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (new_name_len == 0) { + zend_argument_must_not_be_empty_error(2); + RETURN_THROWS(); + } + + PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); + + if (zip_file_rename(intern, sb.index, (const char *)new_name, 0)) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Changes to the file at position index are reverted */ +PHP_METHOD(ZipArchive, unchangeIndex) +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (index < 0) { + RETURN_FALSE; + } + + if (zip_unchange(intern, index) != 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Changes to the file named 'name' are reverted */ +PHP_METHOD(ZipArchive, unchangeName) +{ + struct zip *intern; + zval *self = ZEND_THIS; + struct zip_stat sb; + char *name; + size_t name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (name_len < 1) { + RETURN_FALSE; + } + + PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); + + if (zip_unchange(intern, sb.index) != 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ All changes to files and global information in archive are reverted */ +PHP_METHOD(ZipArchive, unchangeAll) +{ + struct zip *intern; + zval *self = ZEND_THIS; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (zip_unchange_all(intern) != 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */ +PHP_METHOD(ZipArchive, unchangeArchive) +{ + struct zip *intern; + zval *self = ZEND_THIS; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + if (zip_unchange_archive(intern) != 0) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ Extract one or more file from a zip archive */ +/* TODO: + * - allow index or array of indices + * - replace path + * - patterns + */ +PHP_METHOD(ZipArchive, extractTo) +{ + struct zip *intern; + + zval *self = ZEND_THIS; + zend_string *files_str = NULL; + HashTable *files_ht = NULL; + + php_stream_statbuf ssb; + char *pathto; + size_t pathto_len; + int ret; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH(pathto, pathto_len) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(files_ht, files_str) + ZEND_PARSE_PARAMETERS_END(); + + ZIP_FROM_OBJECT(intern, self); + + if (pathto_len < 1) { + RETURN_FALSE; + } + + if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) { + ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL); + if (!ret) { + RETURN_FALSE; + } + } + + uint32_t nelems, i; + + if (files_str) { + if (!php_zip_extract_file(intern, pathto, ZSTR_VAL(files_str), ZSTR_LEN(files_str), -1)) { + RETURN_FALSE; + } + } else if (files_ht) { + nelems = zend_hash_num_elements(files_ht); + if (nelems == 0 ) { + RETURN_FALSE; + } + for (i = 0; i < nelems; i++) { + zval *zval_file; + if ((zval_file = zend_hash_index_find_deref(files_ht, i)) != NULL) { + switch (Z_TYPE_P(zval_file)) { + case IS_LONG: + break; + case IS_STRING: + if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), -1)) { + RETURN_FALSE; + } + break; + } + } + } + } else { + /* Extract all files */ + zip_int64_t i, filecount = zip_get_num_entries(intern, 0); + + if (filecount == -1) { + php_error_docref(NULL, E_WARNING, "Illegal archive"); + RETURN_FALSE; + } + + for (i = 0; i < filecount; i++) { + const char *file = zip_get_name(intern, i, ZIP_FL_UNCHANGED); + if (!file || !php_zip_extract_file(intern, pathto, file, strlen(file), i)) { + RETURN_FALSE; + } + } + } + + RETURN_TRUE; +} +/* }}} */ + +static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ +{ + struct zip *intern; + zval *self = ZEND_THIS; + + struct zip_stat sb; + struct zip_file *zf; + + zend_long index = -1; + zend_long flags = 0; + zend_long len = 0; + + zend_string *filename; + zend_string *buffer; + + int n = 0; + + if (type == 1) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|ll", &filename, &len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(filename), ZSTR_LEN(filename), flags, sb); + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &index, &len, &flags) == FAILURE) { + RETURN_THROWS(); + } + + ZIP_FROM_OBJECT(intern, self); + + PHP_ZIP_STAT_INDEX(intern, index, 0, sb); + } + + if (sb.size < 1) { + RETURN_EMPTY_STRING(); + } + + if (len < 1) { + len = sb.size; + } + if (index >= 0) { + zf = zip_fopen_index(intern, index, flags); + } else { + zf = zip_fopen(intern, ZSTR_VAL(filename), flags); + } + + if (zf == NULL) { + RETURN_FALSE; + } + + buffer = zend_string_safe_alloc(1, len, 0, 0); + n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); + if (n < 1) { + zend_string_efree(buffer); + RETURN_EMPTY_STRING(); + } + + zip_fclose(zf); + ZSTR_VAL(buffer)[n] = '\0'; + ZSTR_LEN(buffer) = n; + RETURN_NEW_STR(buffer); +} +/* }}} */ + +/* {{{ get the contents of an entry using its name */ +PHP_METHOD(ZipArchive, getFromName) +{ + php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ get the contents of an entry using its index */ +PHP_METHOD(ZipArchive, getFromIndex) +{ + php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +static void php_zip_get_stream(INTERNAL_FUNCTION_PARAMETERS, int type, bool accept_flags) /* {{{ */ +{ + struct zip *intern; + zval *self = ZEND_THIS; + zend_long index; + zend_long flags = 0; + struct zip_stat sb; + char *mode = "rb"; + zend_string *filename; + php_stream *stream; + + if (type) { + if (accept_flags) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &filename, &flags) == FAILURE) { + RETURN_THROWS(); + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) { + RETURN_THROWS(); + } + } + } else { + ZEND_ASSERT(accept_flags); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &index, &flags) == FAILURE) { + RETURN_THROWS(); + } + } + + ZIP_FROM_OBJECT(intern, self); + + if (type) { + PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(filename), ZSTR_LEN(filename), flags, sb); + } else { + PHP_ZIP_STAT_INDEX(intern, index, flags, sb); + } + + stream = php_stream_zip_open(intern, &sb, mode, flags STREAMS_CC); + if (stream) { + php_stream_to_zval(stream, return_value); + } else { + RETURN_FALSE; + } +} + +/* {{{ get a stream for an entry using its name */ +PHP_METHOD(ZipArchive, getStreamName) +{ + php_zip_get_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, /* accept_flags */ true); +} +/* }}} */ + +/* {{{ get a stream for an entry using its index */ +PHP_METHOD(ZipArchive, getStreamIndex) +{ + php_zip_get_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, /* accept_flags */ true); +} +/* }}} */ + +PHP_METHOD(ZipArchive, getStream) +{ + php_zip_get_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, /* accept_flags */ false); +} + +#ifdef HAVE_PROGRESS_CALLBACK +static void php_zip_progress_callback(zip_t *arch, double state, void *ptr) +{ + zval cb_args[1]; + ze_zip_object *obj = ptr; + + ZVAL_DOUBLE(&cb_args[0], state); + zend_call_known_fcc(&obj->progress_callback, NULL, 1, cb_args, NULL); +} + +/* {{{ register a progression callback: void callback(double state); */ +PHP_METHOD(ZipArchive, registerProgressCallback) +{ + struct zip *intern; + double rate; + zend_fcall_info dummy_fci; + zend_fcall_info_cache fcc; + ze_zip_object *obj; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "dF", &rate, &dummy_fci, &fcc) == FAILURE) { + RETURN_THROWS(); + } + + /* Inline ZIP_FROM_OBJECT(intern, self); */ + obj = Z_ZIP_P(ZEND_THIS); + intern = obj->za; + if (!intern) { \ + zend_value_error("Invalid or uninitialized Zip object"); + zend_release_fcall_info_cache(&fcc); + RETURN_THROWS(); + } + + /* register */ + if (zip_register_progress_callback_with_state(intern, rate, php_zip_progress_callback, php_zip_progress_callback_free, obj)) { + RETURN_FALSE; + } + zend_fcc_dup(&obj->progress_callback, &fcc); + + RETURN_TRUE; +} +/* }}} */ +#endif + +#ifdef HAVE_CANCEL_CALLBACK +static int php_zip_cancel_callback(zip_t *arch, void *ptr) +{ + zval cb_retval; + ze_zip_object *obj = ptr; + + zend_call_known_fcc(&obj->cancel_callback, &cb_retval, 0, NULL, NULL); + if (Z_ISUNDEF(cb_retval)) { + /* Cancel if an exception has been thrown */ + return -1; + } + bool failed; + zend_long retval = zval_try_get_long(&cb_retval, &failed); + if (failed) { + zend_type_error("Return value of callback provided to ZipArchive::registerCancelCallback()" + " must be of type int, %s returned", zend_zval_value_name(&cb_retval)); + zval_ptr_dtor(&cb_retval); + return -1; + } + zval_ptr_dtor(&cb_retval); + + return (int) retval; +} + +/* {{{ register a progression callback: int callback(double state); */ +PHP_METHOD(ZipArchive, registerCancelCallback) +{ + struct zip *intern; + zend_fcall_info dummy_fci; + zend_fcall_info_cache fcc; + ze_zip_object *obj; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "F", &dummy_fci, &fcc) == FAILURE) { + RETURN_THROWS(); + } + + /* Inline ZIP_FROM_OBJECT(intern, self); */ + obj = Z_ZIP_P(ZEND_THIS); + intern = obj->za; + if (!intern) { \ + zend_value_error("Invalid or uninitialized Zip object"); + zend_release_fcall_info_cache(&fcc); + RETURN_THROWS(); + } + + /* register */ + if (zip_register_cancel_callback_with_state(intern, php_zip_cancel_callback, php_zip_cancel_callback_free, obj)) { + RETURN_FALSE; + } + zend_fcc_dup(&obj->cancel_callback, &fcc); + + RETURN_TRUE; +} +/* }}} */ +#endif + +#ifdef HAVE_METHOD_SUPPORTED +/* {{{ check if a compression method is available in used libzip */ +PHP_METHOD(ZipArchive, isCompressionMethodSupported) +{ + zend_long method; + bool enc = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|b", &method, &enc) == FAILURE) { + return; + } + RETVAL_BOOL(zip_compression_method_supported((zip_int32_t)method, enc)); +} +/* }}} */ + +/* {{{ check if a encryption method is available in used libzip */ +PHP_METHOD(ZipArchive, isEncryptionMethodSupported) +{ + zend_long method; + bool enc = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|b", &method, &enc) == FAILURE) { + return; + } + RETVAL_BOOL(zip_encryption_method_supported((zip_uint16_t)method, enc)); +} +/* }}} */ +#endif + +static void php_zip_free_prop_handler(zval *el) /* {{{ */ { + pefree(Z_PTR_P(el), 1); +} /* }}} */ + +/* {{{ PHP_MINIT_FUNCTION */ +static PHP_MINIT_FUNCTION(zip) +{ + memcpy(&zip_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + zip_object_handlers.offset = XtOffsetOf(ze_zip_object, zo); + zip_object_handlers.free_obj = php_zip_object_free_storage; + zip_object_handlers.clone_obj = NULL; + zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr; + + zip_object_handlers.get_gc = php_zip_get_gc; + zip_object_handlers.get_properties = php_zip_get_properties; + zip_object_handlers.read_property = php_zip_read_property; + zip_object_handlers.has_property = php_zip_has_property; + zip_object_handlers.write_property = php_zip_write_property; + + zip_class_entry = register_class_ZipArchive(zend_ce_countable); + zip_class_entry->create_object = php_zip_object_new; + zip_class_entry->default_object_handlers = &zip_object_handlers; + + zend_hash_init(&zip_prop_handlers, 0, NULL, php_zip_free_prop_handler, 1); + php_zip_register_prop_handler(&zip_prop_handlers, "lastId", php_zip_last_id, NULL, IS_LONG); + php_zip_register_prop_handler(&zip_prop_handlers, "status", php_zip_status, NULL, IS_LONG); + php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, IS_LONG); + php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, IS_LONG); + php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, php_zipobj_get_filename, IS_STRING); + php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, IS_STRING); + + php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper); + + register_php_zip_symbols(module_number); + + le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number); + le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION */ +static PHP_MSHUTDOWN_FUNCTION(zip) +{ + zend_hash_destroy(&zip_prop_handlers); + php_unregister_url_stream_wrapper("zip"); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION */ +static PHP_MINFO_FUNCTION(zip) +{ + php_info_print_table_start(); + + php_info_print_table_row(2, "Zip", "enabled"); + php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION); +#ifdef HAVE_LIBZIP_VERSION + if (strcmp(LIBZIP_VERSION, zip_libzip_version())) { + php_info_print_table_row(2, "Libzip headers version", LIBZIP_VERSION); + php_info_print_table_row(2, "Libzip library version", zip_libzip_version()); + } else +#endif + { + php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION); + } +#ifdef HAVE_METHOD_SUPPORTED + php_info_print_table_row(2, "BZIP2 compression", + zip_compression_method_supported(ZIP_CM_BZIP2, 1) ? "Yes" : "No"); + php_info_print_table_row(2, "XZ compression", + zip_compression_method_supported(ZIP_CM_XZ, 1) ? "Yes" : "No"); +#ifdef ZIP_CM_ZSTD + php_info_print_table_row(2, "ZSTD compression", + zip_compression_method_supported(ZIP_CM_ZSTD, 1) ? "Yes" : "No"); +#else + php_info_print_table_row(2, "ZSTD compression", "No"); +#endif + php_info_print_table_row(2, "AES-128 encryption", + zip_encryption_method_supported(ZIP_EM_AES_128, 1) ? "Yes" : "No"); + php_info_print_table_row(2, "AES-192 encryption", + zip_encryption_method_supported(ZIP_EM_AES_128, 1) ? "Yes" : "No"); + php_info_print_table_row(2, "AES-256 encryption", + zip_encryption_method_supported(ZIP_EM_AES_128, 1) ? "Yes" : "No"); +#endif + + php_info_print_table_end(); +} +/* }}} */ diff --git a/php85/php_zip.h b/php85/php_zip.h new file mode 100644 index 0000000..01d6c3d --- /dev/null +++ b/php85/php_zip.h @@ -0,0 +1,101 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Pierre-Alain Joye | + +----------------------------------------------------------------------+ +*/ + + +#ifndef PHP_ZIP_H +#define PHP_ZIP_H + +extern zend_module_entry zip_module_entry; +#define phpext_zip_ptr &zip_module_entry + +#ifdef ZTS +#include "TSRM.h" +#endif + +#include + +#ifndef ZIP_OVERWRITE +#define ZIP_OVERWRITE ZIP_TRUNCATE +#endif + +/* since 1.10.1 */ +#ifndef ZIP_LENGTH_TO_END +#define ZIP_LENGTH_TO_END 0 +#endif + +/* Additionnal flags not from libzip */ +#define ZIP_FL_OPEN_FILE_NOW (1u<<30) + +#define PHP_ZIP_VERSION "1.22.6" + +#ifdef HAVE_LIBZIP_VERSION +#define LIBZIP_VERSION_STR zip_libzip_version() +#else +#define LIBZIP_VERSION_STR LIBZIP_VERSION +#endif + +#define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) + +typedef struct _ze_zip_rsrc { + struct zip *za; + zip_uint64_t index_current; + zip_int64_t num_files; +} zip_rsrc; + +typedef zip_rsrc * zip_rsrc_ptr; + +typedef struct _ze_zip_read_rsrc { + struct zip_file *zf; + struct zip_stat sb; + /* Used to check if the zip resource still exists, + * without holding a reference. This works because the IDs are unique. */ + zend_long zip_rsrc_handle; +} zip_read_rsrc; + +/* Extends zend object */ +typedef struct _ze_zip_object { + struct zip *za; + char **buffers; + HashTable *prop_handler; + char *filename; + int filename_len; + int buffers_cnt; + zip_int64_t last_id; + int err_zip; + int err_sys; +#ifdef HAVE_PROGRESS_CALLBACK + zend_fcall_info_cache progress_callback; +#endif +#ifdef HAVE_CANCEL_CALLBACK + zend_fcall_info_cache cancel_callback; +#endif + zend_object zo; +} ze_zip_object; + +static inline ze_zip_object *php_zip_fetch_object(zend_object *obj) { + return (ze_zip_object *)((char*)(obj) - XtOffsetOf(ze_zip_object, zo)); +} + +#define Z_ZIP_P(zv) php_zip_fetch_object(Z_OBJ_P((zv))) + +php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); +php_stream *php_stream_zip_open(struct zip *arch, struct zip_stat *sb, const char *mode, zip_flags_t flags STREAMS_DC); + +extern const php_stream_wrapper php_stream_zip_wrapper; + +#define LIBZIP_ATLEAST(m,n,p) (((m<<16) + (n<<8) + p) <= ((LIBZIP_VERSION_MAJOR<<16) + (LIBZIP_VERSION_MINOR<<8) + LIBZIP_VERSION_MICRO)) + +#endif /* PHP_ZIP_H */ diff --git a/php85/php_zip.stub.php b/php85/php_zip.stub.php new file mode 100644 index 0000000..3473d27 --- /dev/null +++ b/php85/php_zip.stub.php @@ -0,0 +1,824 @@ +args[0].value, &attribute_Deprecated_func_zip_open_0_arg0); + attribute_Deprecated_func_zip_open_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_open_0_arg1; + zend_string *attribute_Deprecated_func_zip_open_0_arg1_str = zend_string_init("use ZipArchive::open() instead", strlen("use ZipArchive::open() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_open_0_arg1, attribute_Deprecated_func_zip_open_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_open_0->args[1].value, &attribute_Deprecated_func_zip_open_0_arg1); + attribute_Deprecated_func_zip_open_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_close", sizeof("zip_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_close_0_arg0; + zend_string *attribute_Deprecated_func_zip_close_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_close_0_arg0, attribute_Deprecated_func_zip_close_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_close_0->args[0].value, &attribute_Deprecated_func_zip_close_0_arg0); + attribute_Deprecated_func_zip_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_close_0_arg1; + zend_string *attribute_Deprecated_func_zip_close_0_arg1_str = zend_string_init("use ZipArchive::close() instead", strlen("use ZipArchive::close() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_close_0_arg1, attribute_Deprecated_func_zip_close_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_close_0->args[1].value, &attribute_Deprecated_func_zip_close_0_arg1); + attribute_Deprecated_func_zip_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_read_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_read", sizeof("zip_read") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_read_0_arg0; + zend_string *attribute_Deprecated_func_zip_read_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_read_0_arg0, attribute_Deprecated_func_zip_read_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_read_0->args[0].value, &attribute_Deprecated_func_zip_read_0_arg0); + attribute_Deprecated_func_zip_read_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_read_0_arg1; + zend_string *attribute_Deprecated_func_zip_read_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_read_0_arg1, attribute_Deprecated_func_zip_read_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_read_0->args[1].value, &attribute_Deprecated_func_zip_read_0_arg1); + attribute_Deprecated_func_zip_read_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_entry_open_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_open", sizeof("zip_entry_open") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + zval attribute_Deprecated_func_zip_entry_open_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_open_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_open_0_arg0, attribute_Deprecated_func_zip_entry_open_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_open_0->args[0].value, &attribute_Deprecated_func_zip_entry_open_0_arg0); + attribute_Deprecated_func_zip_entry_open_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_zip_entry_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_close", sizeof("zip_entry_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + zval attribute_Deprecated_func_zip_entry_close_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_close_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_close_0_arg0, attribute_Deprecated_func_zip_entry_close_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_close_0->args[0].value, &attribute_Deprecated_func_zip_entry_close_0_arg0); + attribute_Deprecated_func_zip_entry_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + + zend_attribute *attribute_Deprecated_func_zip_entry_read_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_read", sizeof("zip_entry_read") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_entry_read_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_read_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_read_0_arg0, attribute_Deprecated_func_zip_entry_read_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_read_0->args[0].value, &attribute_Deprecated_func_zip_entry_read_0_arg0); + attribute_Deprecated_func_zip_entry_read_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_entry_read_0_arg1; + zend_string *attribute_Deprecated_func_zip_entry_read_0_arg1_str = zend_string_init("use ZipArchive::getFromIndex() instead", strlen("use ZipArchive::getFromIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_read_0_arg1, attribute_Deprecated_func_zip_entry_read_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_read_0->args[1].value, &attribute_Deprecated_func_zip_entry_read_0_arg1); + attribute_Deprecated_func_zip_entry_read_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_entry_name_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_name", sizeof("zip_entry_name") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_entry_name_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_name_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_name_0_arg0, attribute_Deprecated_func_zip_entry_name_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_name_0->args[0].value, &attribute_Deprecated_func_zip_entry_name_0_arg0); + attribute_Deprecated_func_zip_entry_name_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_entry_name_0_arg1; + zend_string *attribute_Deprecated_func_zip_entry_name_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_name_0_arg1, attribute_Deprecated_func_zip_entry_name_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_name_0->args[1].value, &attribute_Deprecated_func_zip_entry_name_0_arg1); + attribute_Deprecated_func_zip_entry_name_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_entry_compressedsize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_compressedsize", sizeof("zip_entry_compressedsize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_entry_compressedsize_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_compressedsize_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressedsize_0_arg0, attribute_Deprecated_func_zip_entry_compressedsize_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressedsize_0->args[0].value, &attribute_Deprecated_func_zip_entry_compressedsize_0_arg0); + attribute_Deprecated_func_zip_entry_compressedsize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_entry_compressedsize_0_arg1; + zend_string *attribute_Deprecated_func_zip_entry_compressedsize_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressedsize_0_arg1, attribute_Deprecated_func_zip_entry_compressedsize_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressedsize_0->args[1].value, &attribute_Deprecated_func_zip_entry_compressedsize_0_arg1); + attribute_Deprecated_func_zip_entry_compressedsize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_entry_filesize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_filesize", sizeof("zip_entry_filesize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_entry_filesize_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_filesize_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_filesize_0_arg0, attribute_Deprecated_func_zip_entry_filesize_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_filesize_0->args[0].value, &attribute_Deprecated_func_zip_entry_filesize_0_arg0); + attribute_Deprecated_func_zip_entry_filesize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_entry_filesize_0_arg1; + zend_string *attribute_Deprecated_func_zip_entry_filesize_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_filesize_0_arg1, attribute_Deprecated_func_zip_entry_filesize_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_filesize_0->args[1].value, &attribute_Deprecated_func_zip_entry_filesize_0_arg1); + attribute_Deprecated_func_zip_entry_filesize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_zip_entry_compressionmethod_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zip_entry_compressionmethod", sizeof("zip_entry_compressionmethod") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zval attribute_Deprecated_func_zip_entry_compressionmethod_0_arg0; + zend_string *attribute_Deprecated_func_zip_entry_compressionmethod_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressionmethod_0_arg0, attribute_Deprecated_func_zip_entry_compressionmethod_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressionmethod_0->args[0].value, &attribute_Deprecated_func_zip_entry_compressionmethod_0_arg0); + attribute_Deprecated_func_zip_entry_compressionmethod_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zval attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1; + zend_string *attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1_str = zend_string_init("use ZipArchive::statIndex() instead", strlen("use ZipArchive::statIndex() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1, attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_func_zip_entry_compressionmethod_0->args[1].value, &attribute_Deprecated_func_zip_entry_compressionmethod_0_arg1); + attribute_Deprecated_func_zip_entry_compressionmethod_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +} + +static zend_class_entry *register_class_ZipArchive(zend_class_entry *class_entry_Countable) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZipArchive", class_ZipArchive_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); + zend_class_implements(class_entry, 1, class_entry_Countable); + + zval const_CREATE_value; + ZVAL_LONG(&const_CREATE_value, ZIP_CREATE); + zend_string *const_CREATE_name = zend_string_init_interned("CREATE", sizeof("CREATE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CREATE_name, &const_CREATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CREATE_name); + + zval const_EXCL_value; + ZVAL_LONG(&const_EXCL_value, ZIP_EXCL); + zend_string *const_EXCL_name = zend_string_init_interned("EXCL", sizeof("EXCL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EXCL_name, &const_EXCL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EXCL_name); + + zval const_CHECKCONS_value; + ZVAL_LONG(&const_CHECKCONS_value, ZIP_CHECKCONS); + zend_string *const_CHECKCONS_name = zend_string_init_interned("CHECKCONS", sizeof("CHECKCONS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CHECKCONS_name, &const_CHECKCONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CHECKCONS_name); + + zval const_OVERWRITE_value; + ZVAL_LONG(&const_OVERWRITE_value, ZIP_OVERWRITE); + zend_string *const_OVERWRITE_name = zend_string_init_interned("OVERWRITE", sizeof("OVERWRITE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OVERWRITE_name, &const_OVERWRITE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OVERWRITE_name); +#if defined(ZIP_RDONLY) + + zval const_RDONLY_value; + ZVAL_LONG(&const_RDONLY_value, ZIP_RDONLY); + zend_string *const_RDONLY_name = zend_string_init_interned("RDONLY", sizeof("RDONLY") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_RDONLY_name, &const_RDONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_RDONLY_name); +#endif + + zval const_FL_NOCASE_value; + ZVAL_LONG(&const_FL_NOCASE_value, ZIP_FL_NOCASE); + zend_string *const_FL_NOCASE_name = zend_string_init_interned("FL_NOCASE", sizeof("FL_NOCASE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_NOCASE_name, &const_FL_NOCASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_NOCASE_name); + + zval const_FL_NODIR_value; + ZVAL_LONG(&const_FL_NODIR_value, ZIP_FL_NODIR); + zend_string *const_FL_NODIR_name = zend_string_init_interned("FL_NODIR", sizeof("FL_NODIR") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_NODIR_name, &const_FL_NODIR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_NODIR_name); + + zval const_FL_COMPRESSED_value; + ZVAL_LONG(&const_FL_COMPRESSED_value, ZIP_FL_COMPRESSED); + zend_string *const_FL_COMPRESSED_name = zend_string_init_interned("FL_COMPRESSED", sizeof("FL_COMPRESSED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_COMPRESSED_name, &const_FL_COMPRESSED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_COMPRESSED_name); + + zval const_FL_UNCHANGED_value; + ZVAL_LONG(&const_FL_UNCHANGED_value, ZIP_FL_UNCHANGED); + zend_string *const_FL_UNCHANGED_name = zend_string_init_interned("FL_UNCHANGED", sizeof("FL_UNCHANGED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_UNCHANGED_name, &const_FL_UNCHANGED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_UNCHANGED_name); +#if defined(ZIP_FL_RECOMPRESS) + + zval const_FL_RECOMPRESS_value; + ZVAL_LONG(&const_FL_RECOMPRESS_value, ZIP_FL_RECOMPRESS); + zend_string *const_FL_RECOMPRESS_name = zend_string_init_interned("FL_RECOMPRESS", sizeof("FL_RECOMPRESS") - 1, 1); + zend_class_constant *const_FL_RECOMPRESS = zend_declare_typed_class_constant(class_entry, const_FL_RECOMPRESS_name, &const_FL_RECOMPRESS_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_RECOMPRESS_name); +#endif + + zval const_FL_ENCRYPTED_value; + ZVAL_LONG(&const_FL_ENCRYPTED_value, ZIP_FL_ENCRYPTED); + zend_string *const_FL_ENCRYPTED_name = zend_string_init_interned("FL_ENCRYPTED", sizeof("FL_ENCRYPTED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENCRYPTED_name, &const_FL_ENCRYPTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENCRYPTED_name); + + zval const_FL_OVERWRITE_value; + ZVAL_LONG(&const_FL_OVERWRITE_value, ZIP_FL_OVERWRITE); + zend_string *const_FL_OVERWRITE_name = zend_string_init_interned("FL_OVERWRITE", sizeof("FL_OVERWRITE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_OVERWRITE_name, &const_FL_OVERWRITE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_OVERWRITE_name); + + zval const_FL_LOCAL_value; + ZVAL_LONG(&const_FL_LOCAL_value, ZIP_FL_LOCAL); + zend_string *const_FL_LOCAL_name = zend_string_init_interned("FL_LOCAL", sizeof("FL_LOCAL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_LOCAL_name, &const_FL_LOCAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_LOCAL_name); + + zval const_FL_CENTRAL_value; + ZVAL_LONG(&const_FL_CENTRAL_value, ZIP_FL_CENTRAL); + zend_string *const_FL_CENTRAL_name = zend_string_init_interned("FL_CENTRAL", sizeof("FL_CENTRAL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_CENTRAL_name, &const_FL_CENTRAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_CENTRAL_name); + + zval const_FL_ENC_GUESS_value; + ZVAL_LONG(&const_FL_ENC_GUESS_value, ZIP_FL_ENC_GUESS); + zend_string *const_FL_ENC_GUESS_name = zend_string_init_interned("FL_ENC_GUESS", sizeof("FL_ENC_GUESS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENC_GUESS_name, &const_FL_ENC_GUESS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENC_GUESS_name); + + zval const_FL_ENC_RAW_value; + ZVAL_LONG(&const_FL_ENC_RAW_value, ZIP_FL_ENC_RAW); + zend_string *const_FL_ENC_RAW_name = zend_string_init_interned("FL_ENC_RAW", sizeof("FL_ENC_RAW") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENC_RAW_name, &const_FL_ENC_RAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENC_RAW_name); + + zval const_FL_ENC_STRICT_value; + ZVAL_LONG(&const_FL_ENC_STRICT_value, ZIP_FL_ENC_STRICT); + zend_string *const_FL_ENC_STRICT_name = zend_string_init_interned("FL_ENC_STRICT", sizeof("FL_ENC_STRICT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENC_STRICT_name, &const_FL_ENC_STRICT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENC_STRICT_name); + + zval const_FL_ENC_UTF_8_value; + ZVAL_LONG(&const_FL_ENC_UTF_8_value, ZIP_FL_ENC_UTF_8); + zend_string *const_FL_ENC_UTF_8_name = zend_string_init_interned("FL_ENC_UTF_8", sizeof("FL_ENC_UTF_8") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENC_UTF_8_name, &const_FL_ENC_UTF_8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENC_UTF_8_name); + + zval const_FL_ENC_CP437_value; + ZVAL_LONG(&const_FL_ENC_CP437_value, ZIP_FL_ENC_CP437); + zend_string *const_FL_ENC_CP437_name = zend_string_init_interned("FL_ENC_CP437", sizeof("FL_ENC_CP437") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_ENC_CP437_name, &const_FL_ENC_CP437_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_ENC_CP437_name); + + zval const_FL_OPEN_FILE_NOW_value; + ZVAL_LONG(&const_FL_OPEN_FILE_NOW_value, ZIP_FL_OPEN_FILE_NOW); + zend_string *const_FL_OPEN_FILE_NOW_name = zend_string_init_interned("FL_OPEN_FILE_NOW", sizeof("FL_OPEN_FILE_NOW") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_FL_OPEN_FILE_NOW_name, &const_FL_OPEN_FILE_NOW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_FL_OPEN_FILE_NOW_name); + + zval const_CM_DEFAULT_value; + ZVAL_LONG(&const_CM_DEFAULT_value, ZIP_CM_DEFAULT); + zend_string *const_CM_DEFAULT_name = zend_string_init_interned("CM_DEFAULT", sizeof("CM_DEFAULT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_DEFAULT_name, &const_CM_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_DEFAULT_name); + + zval const_CM_STORE_value; + ZVAL_LONG(&const_CM_STORE_value, ZIP_CM_STORE); + zend_string *const_CM_STORE_name = zend_string_init_interned("CM_STORE", sizeof("CM_STORE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_STORE_name, &const_CM_STORE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_STORE_name); + + zval const_CM_SHRINK_value; + ZVAL_LONG(&const_CM_SHRINK_value, ZIP_CM_SHRINK); + zend_string *const_CM_SHRINK_name = zend_string_init_interned("CM_SHRINK", sizeof("CM_SHRINK") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_SHRINK_name, &const_CM_SHRINK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_SHRINK_name); + + zval const_CM_REDUCE_1_value; + ZVAL_LONG(&const_CM_REDUCE_1_value, ZIP_CM_REDUCE_1); + zend_string *const_CM_REDUCE_1_name = zend_string_init_interned("CM_REDUCE_1", sizeof("CM_REDUCE_1") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_REDUCE_1_name, &const_CM_REDUCE_1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_REDUCE_1_name); + + zval const_CM_REDUCE_2_value; + ZVAL_LONG(&const_CM_REDUCE_2_value, ZIP_CM_REDUCE_2); + zend_string *const_CM_REDUCE_2_name = zend_string_init_interned("CM_REDUCE_2", sizeof("CM_REDUCE_2") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_REDUCE_2_name, &const_CM_REDUCE_2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_REDUCE_2_name); + + zval const_CM_REDUCE_3_value; + ZVAL_LONG(&const_CM_REDUCE_3_value, ZIP_CM_REDUCE_3); + zend_string *const_CM_REDUCE_3_name = zend_string_init_interned("CM_REDUCE_3", sizeof("CM_REDUCE_3") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_REDUCE_3_name, &const_CM_REDUCE_3_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_REDUCE_3_name); + + zval const_CM_REDUCE_4_value; + ZVAL_LONG(&const_CM_REDUCE_4_value, ZIP_CM_REDUCE_4); + zend_string *const_CM_REDUCE_4_name = zend_string_init_interned("CM_REDUCE_4", sizeof("CM_REDUCE_4") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_REDUCE_4_name, &const_CM_REDUCE_4_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_REDUCE_4_name); + + zval const_CM_IMPLODE_value; + ZVAL_LONG(&const_CM_IMPLODE_value, ZIP_CM_IMPLODE); + zend_string *const_CM_IMPLODE_name = zend_string_init_interned("CM_IMPLODE", sizeof("CM_IMPLODE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_IMPLODE_name, &const_CM_IMPLODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_IMPLODE_name); + + zval const_CM_DEFLATE_value; + ZVAL_LONG(&const_CM_DEFLATE_value, ZIP_CM_DEFLATE); + zend_string *const_CM_DEFLATE_name = zend_string_init_interned("CM_DEFLATE", sizeof("CM_DEFLATE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_DEFLATE_name, &const_CM_DEFLATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_DEFLATE_name); + + zval const_CM_DEFLATE64_value; + ZVAL_LONG(&const_CM_DEFLATE64_value, ZIP_CM_DEFLATE64); + zend_string *const_CM_DEFLATE64_name = zend_string_init_interned("CM_DEFLATE64", sizeof("CM_DEFLATE64") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_DEFLATE64_name, &const_CM_DEFLATE64_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_DEFLATE64_name); + + zval const_CM_PKWARE_IMPLODE_value; + ZVAL_LONG(&const_CM_PKWARE_IMPLODE_value, ZIP_CM_PKWARE_IMPLODE); + zend_string *const_CM_PKWARE_IMPLODE_name = zend_string_init_interned("CM_PKWARE_IMPLODE", sizeof("CM_PKWARE_IMPLODE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_PKWARE_IMPLODE_name, &const_CM_PKWARE_IMPLODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_PKWARE_IMPLODE_name); + + zval const_CM_BZIP2_value; + ZVAL_LONG(&const_CM_BZIP2_value, ZIP_CM_BZIP2); + zend_string *const_CM_BZIP2_name = zend_string_init_interned("CM_BZIP2", sizeof("CM_BZIP2") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_BZIP2_name, &const_CM_BZIP2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_BZIP2_name); + + zval const_CM_LZMA_value; + ZVAL_LONG(&const_CM_LZMA_value, ZIP_CM_LZMA); + zend_string *const_CM_LZMA_name = zend_string_init_interned("CM_LZMA", sizeof("CM_LZMA") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_LZMA_name, &const_CM_LZMA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_LZMA_name); +#if defined(ZIP_CM_LZMA2) + + zval const_CM_LZMA2_value; + ZVAL_LONG(&const_CM_LZMA2_value, ZIP_CM_LZMA2); + zend_string *const_CM_LZMA2_name = zend_string_init_interned("CM_LZMA2", sizeof("CM_LZMA2") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_LZMA2_name, &const_CM_LZMA2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_LZMA2_name); +#endif +#if defined(ZIP_CM_ZSTD) + + zval const_CM_ZSTD_value; + ZVAL_LONG(&const_CM_ZSTD_value, ZIP_CM_ZSTD); + zend_string *const_CM_ZSTD_name = zend_string_init_interned("CM_ZSTD", sizeof("CM_ZSTD") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_ZSTD_name, &const_CM_ZSTD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_ZSTD_name); +#endif +#if defined(ZIP_CM_XZ) + + zval const_CM_XZ_value; + ZVAL_LONG(&const_CM_XZ_value, ZIP_CM_XZ); + zend_string *const_CM_XZ_name = zend_string_init_interned("CM_XZ", sizeof("CM_XZ") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_XZ_name, &const_CM_XZ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_XZ_name); +#endif + + zval const_CM_TERSE_value; + ZVAL_LONG(&const_CM_TERSE_value, ZIP_CM_TERSE); + zend_string *const_CM_TERSE_name = zend_string_init_interned("CM_TERSE", sizeof("CM_TERSE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_TERSE_name, &const_CM_TERSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_TERSE_name); + + zval const_CM_LZ77_value; + ZVAL_LONG(&const_CM_LZ77_value, ZIP_CM_LZ77); + zend_string *const_CM_LZ77_name = zend_string_init_interned("CM_LZ77", sizeof("CM_LZ77") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_LZ77_name, &const_CM_LZ77_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_LZ77_name); + + zval const_CM_WAVPACK_value; + ZVAL_LONG(&const_CM_WAVPACK_value, ZIP_CM_WAVPACK); + zend_string *const_CM_WAVPACK_name = zend_string_init_interned("CM_WAVPACK", sizeof("CM_WAVPACK") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_WAVPACK_name, &const_CM_WAVPACK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_WAVPACK_name); + + zval const_CM_PPMD_value; + ZVAL_LONG(&const_CM_PPMD_value, ZIP_CM_PPMD); + zend_string *const_CM_PPMD_name = zend_string_init_interned("CM_PPMD", sizeof("CM_PPMD") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_CM_PPMD_name, &const_CM_PPMD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_CM_PPMD_name); + + zval const_ER_OK_value; + ZVAL_LONG(&const_ER_OK_value, ZIP_ER_OK); + zend_string *const_ER_OK_name = zend_string_init_interned("ER_OK", sizeof("ER_OK") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_OK_name, &const_ER_OK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_OK_name); + + zval const_ER_MULTIDISK_value; + ZVAL_LONG(&const_ER_MULTIDISK_value, ZIP_ER_MULTIDISK); + zend_string *const_ER_MULTIDISK_name = zend_string_init_interned("ER_MULTIDISK", sizeof("ER_MULTIDISK") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_MULTIDISK_name, &const_ER_MULTIDISK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_MULTIDISK_name); + + zval const_ER_RENAME_value; + ZVAL_LONG(&const_ER_RENAME_value, ZIP_ER_RENAME); + zend_string *const_ER_RENAME_name = zend_string_init_interned("ER_RENAME", sizeof("ER_RENAME") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_RENAME_name, &const_ER_RENAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_RENAME_name); + + zval const_ER_CLOSE_value; + ZVAL_LONG(&const_ER_CLOSE_value, ZIP_ER_CLOSE); + zend_string *const_ER_CLOSE_name = zend_string_init_interned("ER_CLOSE", sizeof("ER_CLOSE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_CLOSE_name, &const_ER_CLOSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_CLOSE_name); + + zval const_ER_SEEK_value; + ZVAL_LONG(&const_ER_SEEK_value, ZIP_ER_SEEK); + zend_string *const_ER_SEEK_name = zend_string_init_interned("ER_SEEK", sizeof("ER_SEEK") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_SEEK_name, &const_ER_SEEK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_SEEK_name); + + zval const_ER_READ_value; + ZVAL_LONG(&const_ER_READ_value, ZIP_ER_READ); + zend_string *const_ER_READ_name = zend_string_init_interned("ER_READ", sizeof("ER_READ") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_READ_name, &const_ER_READ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_READ_name); + + zval const_ER_WRITE_value; + ZVAL_LONG(&const_ER_WRITE_value, ZIP_ER_WRITE); + zend_string *const_ER_WRITE_name = zend_string_init_interned("ER_WRITE", sizeof("ER_WRITE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_WRITE_name, &const_ER_WRITE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_WRITE_name); + + zval const_ER_CRC_value; + ZVAL_LONG(&const_ER_CRC_value, ZIP_ER_CRC); + zend_string *const_ER_CRC_name = zend_string_init_interned("ER_CRC", sizeof("ER_CRC") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_CRC_name, &const_ER_CRC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_CRC_name); + + zval const_ER_ZIPCLOSED_value; + ZVAL_LONG(&const_ER_ZIPCLOSED_value, ZIP_ER_ZIPCLOSED); + zend_string *const_ER_ZIPCLOSED_name = zend_string_init_interned("ER_ZIPCLOSED", sizeof("ER_ZIPCLOSED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_ZIPCLOSED_name, &const_ER_ZIPCLOSED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_ZIPCLOSED_name); + + zval const_ER_NOENT_value; + ZVAL_LONG(&const_ER_NOENT_value, ZIP_ER_NOENT); + zend_string *const_ER_NOENT_name = zend_string_init_interned("ER_NOENT", sizeof("ER_NOENT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_NOENT_name, &const_ER_NOENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_NOENT_name); + + zval const_ER_EXISTS_value; + ZVAL_LONG(&const_ER_EXISTS_value, ZIP_ER_EXISTS); + zend_string *const_ER_EXISTS_name = zend_string_init_interned("ER_EXISTS", sizeof("ER_EXISTS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_EXISTS_name, &const_ER_EXISTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_EXISTS_name); + + zval const_ER_OPEN_value; + ZVAL_LONG(&const_ER_OPEN_value, ZIP_ER_OPEN); + zend_string *const_ER_OPEN_name = zend_string_init_interned("ER_OPEN", sizeof("ER_OPEN") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_OPEN_name, &const_ER_OPEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_OPEN_name); + + zval const_ER_TMPOPEN_value; + ZVAL_LONG(&const_ER_TMPOPEN_value, ZIP_ER_TMPOPEN); + zend_string *const_ER_TMPOPEN_name = zend_string_init_interned("ER_TMPOPEN", sizeof("ER_TMPOPEN") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_TMPOPEN_name, &const_ER_TMPOPEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_TMPOPEN_name); + + zval const_ER_ZLIB_value; + ZVAL_LONG(&const_ER_ZLIB_value, ZIP_ER_ZLIB); + zend_string *const_ER_ZLIB_name = zend_string_init_interned("ER_ZLIB", sizeof("ER_ZLIB") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_ZLIB_name, &const_ER_ZLIB_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_ZLIB_name); + + zval const_ER_MEMORY_value; + ZVAL_LONG(&const_ER_MEMORY_value, ZIP_ER_MEMORY); + zend_string *const_ER_MEMORY_name = zend_string_init_interned("ER_MEMORY", sizeof("ER_MEMORY") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_MEMORY_name, &const_ER_MEMORY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_MEMORY_name); + + zval const_ER_CHANGED_value; + ZVAL_LONG(&const_ER_CHANGED_value, ZIP_ER_CHANGED); + zend_string *const_ER_CHANGED_name = zend_string_init_interned("ER_CHANGED", sizeof("ER_CHANGED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_CHANGED_name, &const_ER_CHANGED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_CHANGED_name); + + zval const_ER_COMPNOTSUPP_value; + ZVAL_LONG(&const_ER_COMPNOTSUPP_value, ZIP_ER_COMPNOTSUPP); + zend_string *const_ER_COMPNOTSUPP_name = zend_string_init_interned("ER_COMPNOTSUPP", sizeof("ER_COMPNOTSUPP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_COMPNOTSUPP_name, &const_ER_COMPNOTSUPP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_COMPNOTSUPP_name); + + zval const_ER_EOF_value; + ZVAL_LONG(&const_ER_EOF_value, ZIP_ER_EOF); + zend_string *const_ER_EOF_name = zend_string_init_interned("ER_EOF", sizeof("ER_EOF") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_EOF_name, &const_ER_EOF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_EOF_name); + + zval const_ER_INVAL_value; + ZVAL_LONG(&const_ER_INVAL_value, ZIP_ER_INVAL); + zend_string *const_ER_INVAL_name = zend_string_init_interned("ER_INVAL", sizeof("ER_INVAL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_INVAL_name, &const_ER_INVAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_INVAL_name); + + zval const_ER_NOZIP_value; + ZVAL_LONG(&const_ER_NOZIP_value, ZIP_ER_NOZIP); + zend_string *const_ER_NOZIP_name = zend_string_init_interned("ER_NOZIP", sizeof("ER_NOZIP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_NOZIP_name, &const_ER_NOZIP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_NOZIP_name); + + zval const_ER_INTERNAL_value; + ZVAL_LONG(&const_ER_INTERNAL_value, ZIP_ER_INTERNAL); + zend_string *const_ER_INTERNAL_name = zend_string_init_interned("ER_INTERNAL", sizeof("ER_INTERNAL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_INTERNAL_name, &const_ER_INTERNAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_INTERNAL_name); + + zval const_ER_INCONS_value; + ZVAL_LONG(&const_ER_INCONS_value, ZIP_ER_INCONS); + zend_string *const_ER_INCONS_name = zend_string_init_interned("ER_INCONS", sizeof("ER_INCONS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_INCONS_name, &const_ER_INCONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_INCONS_name); + + zval const_ER_REMOVE_value; + ZVAL_LONG(&const_ER_REMOVE_value, ZIP_ER_REMOVE); + zend_string *const_ER_REMOVE_name = zend_string_init_interned("ER_REMOVE", sizeof("ER_REMOVE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_REMOVE_name, &const_ER_REMOVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_REMOVE_name); + + zval const_ER_DELETED_value; + ZVAL_LONG(&const_ER_DELETED_value, ZIP_ER_DELETED); + zend_string *const_ER_DELETED_name = zend_string_init_interned("ER_DELETED", sizeof("ER_DELETED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_DELETED_name, &const_ER_DELETED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_DELETED_name); + + zval const_ER_ENCRNOTSUPP_value; + ZVAL_LONG(&const_ER_ENCRNOTSUPP_value, ZIP_ER_ENCRNOTSUPP); + zend_string *const_ER_ENCRNOTSUPP_name = zend_string_init_interned("ER_ENCRNOTSUPP", sizeof("ER_ENCRNOTSUPP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_ENCRNOTSUPP_name, &const_ER_ENCRNOTSUPP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_ENCRNOTSUPP_name); + + zval const_ER_RDONLY_value; + ZVAL_LONG(&const_ER_RDONLY_value, ZIP_ER_RDONLY); + zend_string *const_ER_RDONLY_name = zend_string_init_interned("ER_RDONLY", sizeof("ER_RDONLY") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_RDONLY_name, &const_ER_RDONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_RDONLY_name); + + zval const_ER_NOPASSWD_value; + ZVAL_LONG(&const_ER_NOPASSWD_value, ZIP_ER_NOPASSWD); + zend_string *const_ER_NOPASSWD_name = zend_string_init_interned("ER_NOPASSWD", sizeof("ER_NOPASSWD") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_NOPASSWD_name, &const_ER_NOPASSWD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_NOPASSWD_name); + + zval const_ER_WRONGPASSWD_value; + ZVAL_LONG(&const_ER_WRONGPASSWD_value, ZIP_ER_WRONGPASSWD); + zend_string *const_ER_WRONGPASSWD_name = zend_string_init_interned("ER_WRONGPASSWD", sizeof("ER_WRONGPASSWD") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_WRONGPASSWD_name, &const_ER_WRONGPASSWD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_WRONGPASSWD_name); +#if defined(ZIP_ER_OPNOTSUPP) + + zval const_ER_OPNOTSUPP_value; + ZVAL_LONG(&const_ER_OPNOTSUPP_value, ZIP_ER_OPNOTSUPP); + zend_string *const_ER_OPNOTSUPP_name = zend_string_init_interned("ER_OPNOTSUPP", sizeof("ER_OPNOTSUPP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_OPNOTSUPP_name, &const_ER_OPNOTSUPP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_OPNOTSUPP_name); +#endif +#if defined(ZIP_ER_INUSE) + + zval const_ER_INUSE_value; + ZVAL_LONG(&const_ER_INUSE_value, ZIP_ER_INUSE); + zend_string *const_ER_INUSE_name = zend_string_init_interned("ER_INUSE", sizeof("ER_INUSE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_INUSE_name, &const_ER_INUSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_INUSE_name); +#endif +#if defined(ZIP_ER_TELL) + + zval const_ER_TELL_value; + ZVAL_LONG(&const_ER_TELL_value, ZIP_ER_TELL); + zend_string *const_ER_TELL_name = zend_string_init_interned("ER_TELL", sizeof("ER_TELL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_TELL_name, &const_ER_TELL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_TELL_name); +#endif +#if defined(ZIP_ER_COMPRESSED_DATA) + + zval const_ER_COMPRESSED_DATA_value; + ZVAL_LONG(&const_ER_COMPRESSED_DATA_value, ZIP_ER_COMPRESSED_DATA); + zend_string *const_ER_COMPRESSED_DATA_name = zend_string_init_interned("ER_COMPRESSED_DATA", sizeof("ER_COMPRESSED_DATA") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_COMPRESSED_DATA_name, &const_ER_COMPRESSED_DATA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_COMPRESSED_DATA_name); +#endif +#if defined(ZIP_ER_CANCELLED) + + zval const_ER_CANCELLED_value; + ZVAL_LONG(&const_ER_CANCELLED_value, ZIP_ER_CANCELLED); + zend_string *const_ER_CANCELLED_name = zend_string_init_interned("ER_CANCELLED", sizeof("ER_CANCELLED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_CANCELLED_name, &const_ER_CANCELLED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_CANCELLED_name); +#endif +#if defined(ZIP_ER_DATA_LENGTH) + + zval const_ER_DATA_LENGTH_value; + ZVAL_LONG(&const_ER_DATA_LENGTH_value, ZIP_ER_DATA_LENGTH); + zend_string *const_ER_DATA_LENGTH_name = zend_string_init_interned("ER_DATA_LENGTH", sizeof("ER_DATA_LENGTH") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_DATA_LENGTH_name, &const_ER_DATA_LENGTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_DATA_LENGTH_name); +#endif +#if defined(ZIP_ER_NOT_ALLOWED) + + zval const_ER_NOT_ALLOWED_value; + ZVAL_LONG(&const_ER_NOT_ALLOWED_value, ZIP_ER_NOT_ALLOWED); + zend_string *const_ER_NOT_ALLOWED_name = zend_string_init_interned("ER_NOT_ALLOWED", sizeof("ER_NOT_ALLOWED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_NOT_ALLOWED_name, &const_ER_NOT_ALLOWED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_NOT_ALLOWED_name); +#endif +#if defined(ZIP_ER_TRUNCATED_ZIP) + + zval const_ER_TRUNCATED_ZIP_value; + ZVAL_LONG(&const_ER_TRUNCATED_ZIP_value, ZIP_ER_TRUNCATED_ZIP); + zend_string *const_ER_TRUNCATED_ZIP_name = zend_string_init_interned("ER_TRUNCATED_ZIP", sizeof("ER_TRUNCATED_ZIP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_ER_TRUNCATED_ZIP_name, &const_ER_TRUNCATED_ZIP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_ER_TRUNCATED_ZIP_name); +#endif +#if defined(ZIP_AFL_RDONLY) + + zval const_AFL_RDONLY_value; + ZVAL_LONG(&const_AFL_RDONLY_value, ZIP_AFL_RDONLY); + zend_string *const_AFL_RDONLY_name = zend_string_init_interned("AFL_RDONLY", sizeof("AFL_RDONLY") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_AFL_RDONLY_name, &const_AFL_RDONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_AFL_RDONLY_name); +#endif +#if defined(ZIP_AFL_IS_TORRENTZIP) + + zval const_AFL_IS_TORRENTZIP_value; + ZVAL_LONG(&const_AFL_IS_TORRENTZIP_value, ZIP_AFL_IS_TORRENTZIP); + zend_string *const_AFL_IS_TORRENTZIP_name = zend_string_init_interned("AFL_IS_TORRENTZIP", sizeof("AFL_IS_TORRENTZIP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_AFL_IS_TORRENTZIP_name, &const_AFL_IS_TORRENTZIP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_AFL_IS_TORRENTZIP_name); +#endif +#if defined(ZIP_AFL_WANT_TORRENTZIP) + + zval const_AFL_WANT_TORRENTZIP_value; + ZVAL_LONG(&const_AFL_WANT_TORRENTZIP_value, ZIP_AFL_WANT_TORRENTZIP); + zend_string *const_AFL_WANT_TORRENTZIP_name = zend_string_init_interned("AFL_WANT_TORRENTZIP", sizeof("AFL_WANT_TORRENTZIP") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_AFL_WANT_TORRENTZIP_name, &const_AFL_WANT_TORRENTZIP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_AFL_WANT_TORRENTZIP_name); +#endif +#if defined(ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE) + + zval const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_value; + ZVAL_LONG(&const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_value, ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE); + zend_string *const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_name = zend_string_init_interned("AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE", sizeof("AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_name, &const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE_name); +#endif +#if defined(ZIP_OPSYS_DEFAULT) + + zval const_OPSYS_DOS_value; + ZVAL_LONG(&const_OPSYS_DOS_value, ZIP_OPSYS_DOS); + zend_string *const_OPSYS_DOS_name = zend_string_init_interned("OPSYS_DOS", sizeof("OPSYS_DOS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_DOS_name, &const_OPSYS_DOS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_DOS_name); + + zval const_OPSYS_AMIGA_value; + ZVAL_LONG(&const_OPSYS_AMIGA_value, ZIP_OPSYS_AMIGA); + zend_string *const_OPSYS_AMIGA_name = zend_string_init_interned("OPSYS_AMIGA", sizeof("OPSYS_AMIGA") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_AMIGA_name, &const_OPSYS_AMIGA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_AMIGA_name); + + zval const_OPSYS_OPENVMS_value; + ZVAL_LONG(&const_OPSYS_OPENVMS_value, ZIP_OPSYS_OPENVMS); + zend_string *const_OPSYS_OPENVMS_name = zend_string_init_interned("OPSYS_OPENVMS", sizeof("OPSYS_OPENVMS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_OPENVMS_name, &const_OPSYS_OPENVMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_OPENVMS_name); + + zval const_OPSYS_UNIX_value; + ZVAL_LONG(&const_OPSYS_UNIX_value, ZIP_OPSYS_UNIX); + zend_string *const_OPSYS_UNIX_name = zend_string_init_interned("OPSYS_UNIX", sizeof("OPSYS_UNIX") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_UNIX_name, &const_OPSYS_UNIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_UNIX_name); + + zval const_OPSYS_VM_CMS_value; + ZVAL_LONG(&const_OPSYS_VM_CMS_value, ZIP_OPSYS_VM_CMS); + zend_string *const_OPSYS_VM_CMS_name = zend_string_init_interned("OPSYS_VM_CMS", sizeof("OPSYS_VM_CMS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_VM_CMS_name, &const_OPSYS_VM_CMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_VM_CMS_name); + + zval const_OPSYS_ATARI_ST_value; + ZVAL_LONG(&const_OPSYS_ATARI_ST_value, ZIP_OPSYS_ATARI_ST); + zend_string *const_OPSYS_ATARI_ST_name = zend_string_init_interned("OPSYS_ATARI_ST", sizeof("OPSYS_ATARI_ST") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_ATARI_ST_name, &const_OPSYS_ATARI_ST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_ATARI_ST_name); + + zval const_OPSYS_OS_2_value; + ZVAL_LONG(&const_OPSYS_OS_2_value, ZIP_OPSYS_OS_2); + zend_string *const_OPSYS_OS_2_name = zend_string_init_interned("OPSYS_OS_2", sizeof("OPSYS_OS_2") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_OS_2_name, &const_OPSYS_OS_2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_OS_2_name); + + zval const_OPSYS_MACINTOSH_value; + ZVAL_LONG(&const_OPSYS_MACINTOSH_value, ZIP_OPSYS_MACINTOSH); + zend_string *const_OPSYS_MACINTOSH_name = zend_string_init_interned("OPSYS_MACINTOSH", sizeof("OPSYS_MACINTOSH") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_MACINTOSH_name, &const_OPSYS_MACINTOSH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_MACINTOSH_name); + + zval const_OPSYS_Z_SYSTEM_value; + ZVAL_LONG(&const_OPSYS_Z_SYSTEM_value, ZIP_OPSYS_Z_SYSTEM); + zend_string *const_OPSYS_Z_SYSTEM_name = zend_string_init_interned("OPSYS_Z_SYSTEM", sizeof("OPSYS_Z_SYSTEM") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_Z_SYSTEM_name, &const_OPSYS_Z_SYSTEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_Z_SYSTEM_name); + + zval const_OPSYS_CPM_value; + ZVAL_LONG(&const_OPSYS_CPM_value, ZIP_OPSYS_CPM); + zend_string *const_OPSYS_CPM_name = zend_string_init_interned("OPSYS_CPM", sizeof("OPSYS_CPM") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_CPM_name, &const_OPSYS_CPM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_CPM_name); + + zval const_OPSYS_WINDOWS_NTFS_value; + ZVAL_LONG(&const_OPSYS_WINDOWS_NTFS_value, ZIP_OPSYS_WINDOWS_NTFS); + zend_string *const_OPSYS_WINDOWS_NTFS_name = zend_string_init_interned("OPSYS_WINDOWS_NTFS", sizeof("OPSYS_WINDOWS_NTFS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_WINDOWS_NTFS_name, &const_OPSYS_WINDOWS_NTFS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_WINDOWS_NTFS_name); + + zval const_OPSYS_MVS_value; + ZVAL_LONG(&const_OPSYS_MVS_value, ZIP_OPSYS_MVS); + zend_string *const_OPSYS_MVS_name = zend_string_init_interned("OPSYS_MVS", sizeof("OPSYS_MVS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_MVS_name, &const_OPSYS_MVS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_MVS_name); + + zval const_OPSYS_VSE_value; + ZVAL_LONG(&const_OPSYS_VSE_value, ZIP_OPSYS_VSE); + zend_string *const_OPSYS_VSE_name = zend_string_init_interned("OPSYS_VSE", sizeof("OPSYS_VSE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_VSE_name, &const_OPSYS_VSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_VSE_name); + + zval const_OPSYS_ACORN_RISC_value; + ZVAL_LONG(&const_OPSYS_ACORN_RISC_value, ZIP_OPSYS_ACORN_RISC); + zend_string *const_OPSYS_ACORN_RISC_name = zend_string_init_interned("OPSYS_ACORN_RISC", sizeof("OPSYS_ACORN_RISC") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_ACORN_RISC_name, &const_OPSYS_ACORN_RISC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_ACORN_RISC_name); + + zval const_OPSYS_VFAT_value; + ZVAL_LONG(&const_OPSYS_VFAT_value, ZIP_OPSYS_VFAT); + zend_string *const_OPSYS_VFAT_name = zend_string_init_interned("OPSYS_VFAT", sizeof("OPSYS_VFAT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_VFAT_name, &const_OPSYS_VFAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_VFAT_name); + + zval const_OPSYS_ALTERNATE_MVS_value; + ZVAL_LONG(&const_OPSYS_ALTERNATE_MVS_value, ZIP_OPSYS_ALTERNATE_MVS); + zend_string *const_OPSYS_ALTERNATE_MVS_name = zend_string_init_interned("OPSYS_ALTERNATE_MVS", sizeof("OPSYS_ALTERNATE_MVS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_ALTERNATE_MVS_name, &const_OPSYS_ALTERNATE_MVS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_ALTERNATE_MVS_name); + + zval const_OPSYS_BEOS_value; + ZVAL_LONG(&const_OPSYS_BEOS_value, ZIP_OPSYS_BEOS); + zend_string *const_OPSYS_BEOS_name = zend_string_init_interned("OPSYS_BEOS", sizeof("OPSYS_BEOS") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_BEOS_name, &const_OPSYS_BEOS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_BEOS_name); + + zval const_OPSYS_TANDEM_value; + ZVAL_LONG(&const_OPSYS_TANDEM_value, ZIP_OPSYS_TANDEM); + zend_string *const_OPSYS_TANDEM_name = zend_string_init_interned("OPSYS_TANDEM", sizeof("OPSYS_TANDEM") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_TANDEM_name, &const_OPSYS_TANDEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_TANDEM_name); + + zval const_OPSYS_OS_400_value; + ZVAL_LONG(&const_OPSYS_OS_400_value, ZIP_OPSYS_OS_400); + zend_string *const_OPSYS_OS_400_name = zend_string_init_interned("OPSYS_OS_400", sizeof("OPSYS_OS_400") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_OS_400_name, &const_OPSYS_OS_400_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_OS_400_name); + + zval const_OPSYS_OS_X_value; + ZVAL_LONG(&const_OPSYS_OS_X_value, ZIP_OPSYS_OS_X); + zend_string *const_OPSYS_OS_X_name = zend_string_init_interned("OPSYS_OS_X", sizeof("OPSYS_OS_X") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_OS_X_name, &const_OPSYS_OS_X_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_OS_X_name); + + zval const_OPSYS_DEFAULT_value; + ZVAL_LONG(&const_OPSYS_DEFAULT_value, ZIP_OPSYS_DEFAULT); + zend_string *const_OPSYS_DEFAULT_name = zend_string_init_interned("OPSYS_DEFAULT", sizeof("OPSYS_DEFAULT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_OPSYS_DEFAULT_name, &const_OPSYS_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_OPSYS_DEFAULT_name); +#endif + + zval const_EM_NONE_value; + ZVAL_LONG(&const_EM_NONE_value, ZIP_EM_NONE); + zend_string *const_EM_NONE_name = zend_string_init_interned("EM_NONE", sizeof("EM_NONE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_NONE_name, &const_EM_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_NONE_name); + + zval const_EM_TRAD_PKWARE_value; + ZVAL_LONG(&const_EM_TRAD_PKWARE_value, ZIP_EM_TRAD_PKWARE); + zend_string *const_EM_TRAD_PKWARE_name = zend_string_init_interned("EM_TRAD_PKWARE", sizeof("EM_TRAD_PKWARE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_TRAD_PKWARE_name, &const_EM_TRAD_PKWARE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_TRAD_PKWARE_name); +#if defined(HAVE_ENCRYPTION) + + zval const_EM_AES_128_value; + ZVAL_LONG(&const_EM_AES_128_value, ZIP_EM_AES_128); + zend_string *const_EM_AES_128_name = zend_string_init_interned("EM_AES_128", sizeof("EM_AES_128") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_AES_128_name, &const_EM_AES_128_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_AES_128_name); + + zval const_EM_AES_192_value; + ZVAL_LONG(&const_EM_AES_192_value, ZIP_EM_AES_192); + zend_string *const_EM_AES_192_name = zend_string_init_interned("EM_AES_192", sizeof("EM_AES_192") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_AES_192_name, &const_EM_AES_192_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_AES_192_name); + + zval const_EM_AES_256_value; + ZVAL_LONG(&const_EM_AES_256_value, ZIP_EM_AES_256); + zend_string *const_EM_AES_256_name = zend_string_init_interned("EM_AES_256", sizeof("EM_AES_256") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_AES_256_name, &const_EM_AES_256_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_AES_256_name); +#endif + + zval const_EM_UNKNOWN_value; + ZVAL_LONG(&const_EM_UNKNOWN_value, ZIP_EM_UNKNOWN); + zend_string *const_EM_UNKNOWN_name = zend_string_init_interned("EM_UNKNOWN", sizeof("EM_UNKNOWN") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_EM_UNKNOWN_name, &const_EM_UNKNOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_EM_UNKNOWN_name); + + zval const_LIBZIP_VERSION_value; + zend_string *const_LIBZIP_VERSION_value_str = zend_string_init(LIBZIP_VERSION_STR, strlen(LIBZIP_VERSION_STR), 1); + ZVAL_STR(&const_LIBZIP_VERSION_value, const_LIBZIP_VERSION_value_str); + zend_string *const_LIBZIP_VERSION_name = zend_string_init_interned("LIBZIP_VERSION", sizeof("LIBZIP_VERSION") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_LIBZIP_VERSION_name, &const_LIBZIP_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(const_LIBZIP_VERSION_name); + + zval const_LENGTH_TO_END_value; + ZVAL_LONG(&const_LENGTH_TO_END_value, ZIP_LENGTH_TO_END); + zend_string *const_LENGTH_TO_END_name = zend_string_init_interned("LENGTH_TO_END", sizeof("LENGTH_TO_END") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_LENGTH_TO_END_name, &const_LENGTH_TO_END_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_LENGTH_TO_END_name); +#if defined(ZIP_LENGTH_UNCHECKED) + + zval const_LENGTH_UNCHECKED_value; + ZVAL_LONG(&const_LENGTH_UNCHECKED_value, ZIP_LENGTH_UNCHECKED); + zend_string *const_LENGTH_UNCHECKED_name = zend_string_init_interned("LENGTH_UNCHECKED", sizeof("LENGTH_UNCHECKED") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_LENGTH_UNCHECKED_name, &const_LENGTH_UNCHECKED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_LENGTH_UNCHECKED_name); +#endif + + zval property_lastId_default_value; + ZVAL_UNDEF(&property_lastId_default_value); + zend_string *property_lastId_name = zend_string_init("lastId", sizeof("lastId") - 1, 1); + zend_declare_typed_property(class_entry, property_lastId_name, &property_lastId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_lastId_name); + + zval property_status_default_value; + ZVAL_UNDEF(&property_status_default_value); + zend_string *property_status_name = zend_string_init("status", sizeof("status") - 1, 1); + zend_declare_typed_property(class_entry, property_status_name, &property_status_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_status_name); + + zval property_statusSys_default_value; + ZVAL_UNDEF(&property_statusSys_default_value); + zend_string *property_statusSys_name = zend_string_init("statusSys", sizeof("statusSys") - 1, 1); + zend_declare_typed_property(class_entry, property_statusSys_name, &property_statusSys_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_statusSys_name); + + zval property_numFiles_default_value; + ZVAL_UNDEF(&property_numFiles_default_value); + zend_string *property_numFiles_name = zend_string_init("numFiles", sizeof("numFiles") - 1, 1); + zend_declare_typed_property(class_entry, property_numFiles_name, &property_numFiles_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_numFiles_name); + + zval property_filename_default_value; + ZVAL_UNDEF(&property_filename_default_value); + zend_string *property_filename_name = zend_string_init("filename", sizeof("filename") - 1, 1); + zend_declare_typed_property(class_entry, property_filename_name, &property_filename_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_filename_name); + + zval property_comment_default_value; + ZVAL_UNDEF(&property_comment_default_value); + zend_string *property_comment_name = zend_string_init("comment", sizeof("comment") - 1, 1); + zend_declare_typed_property(class_entry, property_comment_name, &property_comment_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_comment_name); + +#if defined(ZIP_FL_RECOMPRESS) + + zend_attribute *attribute_Deprecated_const_FL_RECOMPRESS_0 = zend_add_class_constant_attribute(class_entry, const_FL_RECOMPRESS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); + zval attribute_Deprecated_const_FL_RECOMPRESS_0_arg0; + zend_string *attribute_Deprecated_const_FL_RECOMPRESS_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); + ZVAL_STR(&attribute_Deprecated_const_FL_RECOMPRESS_0_arg0, attribute_Deprecated_const_FL_RECOMPRESS_0_arg0_str); + ZVAL_COPY_VALUE(&attribute_Deprecated_const_FL_RECOMPRESS_0->args[0].value, &attribute_Deprecated_const_FL_RECOMPRESS_0_arg0); + attribute_Deprecated_const_FL_RECOMPRESS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); +#endif + + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setpassword", sizeof("setpassword") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#if defined(HAVE_ENCRYPTION) + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setencryptionname", sizeof("setencryptionname") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setencryptionindex", sizeof("setencryptionindex") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#endif + + return class_entry; +} diff --git a/php85/zip_stream.c b/php85/zip_stream.c new file mode 100644 index 0000000..a323243 --- /dev/null +++ b/php85/zip_stream.c @@ -0,0 +1,390 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Piere-Alain Joye | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "php.h" +#ifdef HAVE_ZIP + +#include "php_streams.h" +#include "ext/standard/file.h" +#include "ext/standard/php_string.h" +#include "fopen_wrappers.h" +#include "php_zip.h" + +/* needed for ssize_t definition */ +#include + +struct php_zip_stream_data_t { + struct zip *za; + struct zip_file *zf; + size_t cursor; + php_stream *stream; +}; + +#define STREAM_DATA_FROM_STREAM() \ + struct php_zip_stream_data_t *self = (struct php_zip_stream_data_t *) stream->abstract; + + +/* {{{ php_zip_ops_read */ +static ssize_t php_zip_ops_read(php_stream *stream, char *buf, size_t count) +{ + ssize_t n = 0; + STREAM_DATA_FROM_STREAM(); + + if (self->zf) { + n = zip_fread(self->zf, buf, count); + if (n < 0) { +#if LIBZIP_VERSION_MAJOR < 1 + int ze, se; + zip_file_error_get(self->zf, &ze, &se); + stream->eof = 1; + php_error_docref(NULL, E_WARNING, "Zip stream error: %s", zip_file_strerror(self->zf)); +#else + zip_error_t *err; + err = zip_file_get_error(self->zf); + stream->eof = 1; + php_error_docref(NULL, E_WARNING, "Zip stream error: %s", zip_error_strerror(err)); + zip_error_fini(err); +#endif + return -1; + } + /* cast count to signed value to avoid possibly negative n + * being cast to unsigned value */ + if (n == 0 || n < (ssize_t)count) { + stream->eof = 1; + } else { + self->cursor += n; + } + } + return n; +} +/* }}} */ + +/* {{{ php_zip_ops_write */ +static ssize_t php_zip_ops_write(php_stream *stream, const char *buf, size_t count) +{ + if (!stream) { + return -1; + } + + return count; +} +/* }}} */ + +/* {{{ php_zip_ops_close */ +static int php_zip_ops_close(php_stream *stream, int close_handle) +{ + STREAM_DATA_FROM_STREAM(); + if (close_handle) { + if (self->zf) { + zip_fclose(self->zf); + self->zf = NULL; + } + + if (self->za) { + zip_close(self->za); + self->za = NULL; + } + } + efree(self); + stream->abstract = NULL; + return EOF; +} +/* }}} */ + +/* {{{ php_zip_ops_flush */ +static int php_zip_ops_flush(php_stream *stream) +{ + if (!stream) { + return 0; + } + + return 0; +} +/* }}} */ + +static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ +{ + struct zip_stat sb; + const char *path = stream->orig_path; + size_t path_len = strlen(stream->orig_path); + char file_dirname[MAXPATHLEN]; + struct zip *za; + char *fragment; + size_t fragment_len; + int err; + zend_string *file_basename; + + fragment = strchr(path, '#'); + if (!fragment) { + return -1; + } + + + if (strncasecmp("zip://", path, 6) == 0) { + path += 6; + } + + fragment_len = strlen(fragment); + + if (fragment_len < 1) { + return -1; + } + path_len = strlen(path); + if (path_len >= MAXPATHLEN) { + return -1; + } + + memcpy(file_dirname, path, path_len - fragment_len); + file_dirname[path_len - fragment_len] = '\0'; + + file_basename = php_basename((char *)path, path_len - fragment_len, NULL, 0); + fragment++; + + if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) { + zend_string_release_ex(file_basename, 0); + return -1; + } + + za = zip_open(file_dirname, ZIP_CREATE, &err); + if (za) { + memset(ssb, 0, sizeof(php_stream_statbuf)); + if (zip_stat(za, fragment, ZIP_FL_NOCASE, &sb) != 0) { + zip_close(za); + zend_string_release_ex(file_basename, 0); + return -1; + } + zip_close(za); + + if (path[path_len-1] != '/') { + ssb->sb.st_size = sb.size; + ssb->sb.st_mode |= S_IFREG; /* regular file */ + } else { + ssb->sb.st_size = 0; + ssb->sb.st_mode |= S_IFDIR; /* regular directory */ + } + + ssb->sb.st_mtime = sb.mtime; + ssb->sb.st_atime = sb.mtime; + ssb->sb.st_ctime = sb.mtime; + ssb->sb.st_nlink = 1; + ssb->sb.st_rdev = -1; +#ifndef PHP_WIN32 + ssb->sb.st_blksize = -1; + ssb->sb.st_blocks = -1; +#endif + ssb->sb.st_ino = -1; + } + zend_string_release_ex(file_basename, 0); + return 0; +} +/* }}} */ + +#if LIBZIP_ATLEAST(1,9,1) +/* {{{ php_zip_ops_seek */ +static int php_zip_ops_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) +{ + int ret = -1; + STREAM_DATA_FROM_STREAM(); + + if (self->zf) { + ret = zip_fseek(self->zf, offset, whence); + *newoffset = zip_ftell(self->zf); + } + + return ret; +} +/* }}} */ + +/* with seek command */ +const php_stream_ops php_stream_zipio_seek_ops = { + php_zip_ops_write, php_zip_ops_read, + php_zip_ops_close, php_zip_ops_flush, + "zip", + php_zip_ops_seek, /* seek */ + NULL, /* cast */ + php_zip_ops_stat, /* stat */ + NULL /* set_option */ +}; +#endif + +/* without seek command */ +const php_stream_ops php_stream_zipio_ops = { + php_zip_ops_write, php_zip_ops_read, + php_zip_ops_close, php_zip_ops_flush, + "zip", + NULL, /* seek */ + NULL, /* cast */ + php_zip_ops_stat, /* stat */ + NULL /* set_option */ +}; + +/* {{{ php_stream_zip_open */ +php_stream *php_stream_zip_open(struct zip *arch, struct zip_stat *sb, const char *mode, zip_flags_t flags STREAMS_DC) +{ + struct zip_file *zf = NULL; + + php_stream *stream = NULL; + struct php_zip_stream_data_t *self; + + if (strncmp(mode,"r", strlen("r")) != 0) { + return NULL; + } + + if (arch) { + zf = zip_fopen_index(arch, sb->index, flags); + if (zf) { + self = emalloc(sizeof(*self)); + + self->za = NULL; /* to keep it open on stream close */ + self->zf = zf; + self->stream = NULL; + self->cursor = 0; +#if LIBZIP_ATLEAST(1,9,1) + if (zip_file_is_seekable(zf) > 0) { + stream = php_stream_alloc(&php_stream_zipio_seek_ops, self, NULL, mode); + } else +#endif + { + stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode); + } + stream->orig_path = estrdup(sb->name); + } + } + + return stream; +} +/* }}} */ + +/* {{{ php_stream_zip_opener */ +php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, + const char *path, + const char *mode, + int options, + zend_string **opened_path, + php_stream_context *context STREAMS_DC) +{ + size_t path_len; + + zend_string *file_basename; + char file_dirname[MAXPATHLEN]; + + struct zip *za; + struct zip_file *zf = NULL; + char *fragment; + size_t fragment_len; + int err; + + php_stream *stream = NULL; + struct php_zip_stream_data_t *self; + + fragment = strchr(path, '#'); + if (!fragment) { + return NULL; + } + + if (strncasecmp("zip://", path, 6) == 0) { + path += 6; + } + + fragment_len = strlen(fragment); + + if (fragment_len < 1) { + return NULL; + } + path_len = strlen(path); + if (path_len >= MAXPATHLEN || mode[0] != 'r') { + return NULL; + } + + memcpy(file_dirname, path, path_len - fragment_len); + file_dirname[path_len - fragment_len] = '\0'; + + file_basename = php_basename(path, path_len - fragment_len, NULL, 0); + fragment++; + + if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) { + zend_string_release_ex(file_basename, 0); + return NULL; + } + + za = zip_open(file_dirname, ZIP_CREATE, &err); + if (za) { + zval *tmpzval; + + if (context && NULL != (tmpzval = php_stream_context_get_option(context, "zip", "password"))) { + if (Z_TYPE_P(tmpzval) != IS_STRING || zip_set_default_password(za, Z_STRVAL_P(tmpzval))) { + php_error_docref(NULL, E_WARNING, "Can't set zip password"); + } + } + + zf = zip_fopen(za, fragment, 0); + if (zf) { + self = emalloc(sizeof(*self)); + + self->za = za; + self->zf = zf; + self->stream = NULL; + self->cursor = 0; +#if LIBZIP_ATLEAST(1,9,1) + if (zip_file_is_seekable(zf) > 0) { + stream = php_stream_alloc(&php_stream_zipio_seek_ops, self, NULL, mode); + } else +#endif + { + stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode); + } + + if (opened_path) { + *opened_path = zend_string_init(path, strlen(path), 0); + } + } else { + zip_close(za); + } + } + + zend_string_release_ex(file_basename, 0); + + if (!stream) { + return NULL; + } else { + return stream; + } +} +/* }}} */ + +static const php_stream_wrapper_ops zip_stream_wops = { + php_stream_zip_opener, + NULL, /* close */ + NULL, /* fstat */ + NULL, /* stat */ + NULL, /* opendir */ + "zip wrapper", + NULL, /* unlink */ + NULL, /* rename */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL /* metadata */ +}; + +const php_stream_wrapper php_stream_zip_wrapper = { + &zip_stream_wops, + NULL, + 0 /* is_url */ +}; +#endif /* HAVE_ZIP */ -- 2.50.0