summaryrefslogtreecommitdiff
path: root/ext/zip/php_zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zip/php_zip.c')
-rw-r--r--ext/zip/php_zip.c203
1 files changed, 130 insertions, 73 deletions
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index d3ec27bafe..cd1d7cd425 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -30,8 +30,6 @@
#include "ext/pcre/php_pcre.h"
#include "ext/standard/php_filestat.h"
#include "php_zip.h"
-#include "lib/zip.h"
-#include "lib/zipint.h"
/* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
static PHP_NAMED_FUNCTION(zif_zip_open);
@@ -53,6 +51,24 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_close);
#endif
#endif
+#if PHP_VERSION_ID < 50400
+#define ARG_PATH "s"
+#define KEY_ARG_DC
+#define KEY_ARG_CC
+#else
+#define ARG_PATH "p"
+#define KEY_ARG_DC , const zend_literal *key
+#define KEY_ARG_CC , key
+#endif
+
+#if PHP_VERSION_ID < 50500
+#define TYPE_ARG_DC
+#define TYPE_ARG_CC
+#else
+#define TYPE_ARG_DC , int type
+#define TYPE_ARG_CC , type
+#endif
+
/* {{{ Resource le */
static int le_zip_dir;
#define le_zip_dir_name "Zip Directory"
@@ -154,7 +170,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
size_t path_cleaned_len;
cwd_state new_state;
- new_state.cwd = (char*)malloc(1);
+ new_state.cwd = (char*)emalloc(1);
new_state.cwd[0] = '\0';
new_state.cwd_length = 0;
@@ -191,7 +207,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
efree(file_dirname_fullpath);
efree(file_basename);
- free(new_state.cwd);
+ efree(new_state.cwd);
return 0;
}
}
@@ -215,7 +231,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
efree(file_dirname_fullpath);
if (!is_dir_only) {
efree(file_basename);
- free(new_state.cwd);
+ efree(new_state.cwd);
}
return 0;
}
@@ -224,7 +240,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
/* it is a standalone directory, job done */
if (is_dir_only) {
efree(file_dirname_fullpath);
- free(new_state.cwd);
+ efree(new_state.cwd);
return 1;
}
@@ -232,13 +248,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
if (!len) {
efree(file_dirname_fullpath);
efree(file_basename);
- free(new_state.cwd);
+ efree(new_state.cwd);
return 0;
} else if (len > MAXPATHLEN) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
efree(file_dirname_fullpath);
efree(file_basename);
- free(new_state.cwd);
+ efree(new_state.cwd);
return 0;
}
@@ -250,7 +266,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
efree(fullpath);
efree(file_dirname_fullpath);
efree(file_basename);
- free(new_state.cwd);
+ efree(new_state.cwd);
return 0;
}
@@ -285,7 +301,7 @@ done:
efree(fullpath);
efree(file_basename);
efree(file_dirname_fullpath);
- free(new_state.cwd);
+ efree(new_state.cwd);
if (n<0) {
return 0;
@@ -299,7 +315,6 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */
{
struct zip_source *zs;
- int cur_idx;
char resolved_path[MAXPATHLEN];
zval exists_flag;
@@ -321,25 +336,11 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
if (!zs) {
return -1;
}
-
- cur_idx = zip_name_locate(za, (const char *)entry_name, 0);
- /* TODO: fix _zip_replace */
- if (cur_idx<0) {
- /* reset the error */
- if (za->error.str) {
- _zip_error_fini(&za->error);
- }
- _zip_error_init(&za->error);
- } else {
- if (zip_delete(za, cur_idx) == -1) {
- zip_source_free(zs);
- return -1;
- }
- }
-
- if (zip_add(za, entry_name, zs) == -1) {
+ if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
+ zip_source_free(zs);
return -1;
} else {
+ zip_error_clear(za);
return 1;
}
}
@@ -417,7 +418,7 @@ static int php_zip_parse_options(zval *options, long *remove_all_path,
ze_zip_object *obj = (ze_zip_object*) zend_object_store_get_object(object TSRMLS_CC); \
intern = obj->za; \
if (!intern) { \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized Zip object"); \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or uninitialized Zip object"); \
RETURN_FALSE; \
} \
}
@@ -780,7 +781,11 @@ static const zend_function_entry zip_functions[] = {
PHP_FE(zip_entry_name, arginfo_zip_entry_name)
PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize)
PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod)
+#ifdef PHP_FE_END
PHP_FE_END
+#else
+ {NULL,NULL,NULL}
+#endif
};
/* }}} */
@@ -869,7 +874,7 @@ static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zv
}
/* }}} */
-static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member TYPE_ARG_DC KEY_ARG_DC TSRMLS_DC) /* {{{ */
{
ze_zip_object *obj;
zval tmp_member;
@@ -884,24 +889,27 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type,
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
+#if PHP_VERSION_ID >= 50400
key = NULL;
+#endif
}
ret = FAILURE;
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
if (obj->prop_handler != NULL) {
+#if PHP_VERSION_ID >= 50400
if (key) {
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
- } else {
+ } else
+#endif
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
- }
}
if (ret == FAILURE) {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
+ retval = std_hnd->get_property_ptr_ptr(object, member TYPE_ARG_CC KEY_ARG_CC TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -911,7 +919,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type,
}
/* }}} */
-static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval* php_zip_read_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */
{
ze_zip_object *obj;
zval tmp_member;
@@ -925,18 +933,21 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
+#if PHP_VERSION_ID >= 50400
key = NULL;
+#endif
}
ret = FAILURE;
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
if (obj->prop_handler != NULL) {
+#if PHP_VERSION_ID >= 50400
if (key) {
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
- } else {
+ } else
+#endif
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
- }
}
if (ret == SUCCESS) {
@@ -949,7 +960,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
}
} else {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
+ retval = std_hnd->read_property(object, member, type KEY_ARG_CC TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -959,7 +970,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
}
/* }}} */
-static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
+static int php_zip_has_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */
{
ze_zip_object *obj;
zval tmp_member;
@@ -972,18 +983,21 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
+#if PHP_VERSION_ID >= 50400
key = NULL;
+#endif
}
ret = FAILURE;
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
if (obj->prop_handler != NULL) {
+#if PHP_VERSION_ID >= 50400
if (key) {
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
- } else {
+ } else
+#endif
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
- }
}
if (ret == SUCCESS) {
@@ -1005,7 +1019,7 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend
zval_ptr_dtor(&tmp);
} else {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->has_property(object, member, type, key TSRMLS_CC);
+ retval = std_hnd->has_property(object, member, type KEY_ARG_CC TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -1059,7 +1073,8 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
}
if (intern->za) {
if (zip_close(intern->za) != 0) {
- _zip_free(intern->za);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context");
+ return;
}
intern->za = NULL;
}
@@ -1096,6 +1111,9 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
{
+#if PHP_VERSION_ID < 50400
+ zval *tmp;
+#endif
ze_zip_object *intern;
zend_object_value retval;
@@ -1116,8 +1134,13 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_
intern->zo.ce = class_type;
#endif
- object_properties_init(&intern->zo, class_type);
+#if PHP_VERSION_ID < 50400
+ zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
+ (void *) &tmp, sizeof(zval *));
+#else
+ object_properties_init(&intern->zo, class_type);
+#endif
retval.handle = zend_objects_store_put(intern,
NULL,
(zend_objects_free_object_storage_t) php_zip_object_free_storage,
@@ -1140,7 +1163,7 @@ static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC)
if (zip_int) {
if (zip_int->za) {
if (zip_close(zip_int->za) != 0) {
- _zip_free(zip_int->za);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context");
}
zip_int->za = NULL;
}
@@ -1159,13 +1182,7 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC)
if (zr_rsrc) {
if (zr_rsrc->zf) {
- if (zr_rsrc->zf->za) {
- zip_fclose(zr_rsrc->zf);
- } else {
- if (zr_rsrc->zf->src)
- zip_source_free(zr_rsrc->zf->src);
- free(zr_rsrc->zf);
- }
+ zip_fclose(zr_rsrc->zf);
zr_rsrc->zf = NULL;
}
efree(zr_rsrc);
@@ -1195,7 +1212,7 @@ zend_module_entry zip_module_entry = {
NULL,
NULL,
PHP_MINFO(zip),
- PHP_ZIP_VERSION_STRING,
+ PHP_ZIP_VERSION,
STANDARD_MODULE_PROPERTIES
};
/* }}} */
@@ -1215,7 +1232,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open)
zip_rsrc *rsrc_int;
int err = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) {
return;
}
@@ -1498,7 +1515,7 @@ static ZIPARCHIVE_METHOD(open)
zval *this = getThis();
ze_zip_object *ze_obj = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &filename, &filename_len, &flags) == FAILURE) {
return;
}
@@ -1523,7 +1540,8 @@ static ZIPARCHIVE_METHOD(open)
if (ze_obj->za) {
/* we already have an opened zip, free it */
if (zip_close(ze_obj->za) != 0) {
- _zip_free(ze_obj->za);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
+ RETURN_FALSE;
}
ze_obj->za = NULL;
}
@@ -1543,6 +1561,38 @@ static ZIPARCHIVE_METHOD(open)
}
/* }}} */
+/* {{{ proto resource ZipArchive::setPassword(string password)
+Set the password for the active archive */
+static ZIPARCHIVE_METHOD(setPassword)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *password;
+ int password_len;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &password, &password_len) == FAILURE) {
+ return;
+ }
+
+ if (password_len < 1) {
+ RETURN_FALSE;
+ } else {
+ int res = zip_set_default_password(intern, (const char *)password);
+ if (res == 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+ }
+}
+/* }}} */
+
/* {{{ proto bool ZipArchive::close()
close the zip archive */
static ZIPARCHIVE_METHOD(close)
@@ -1552,7 +1602,7 @@ static ZIPARCHIVE_METHOD(close)
ze_zip_object *ze_obj;
if (!this) {
- RETURN_FALSE;
+ RETURN_FALSE;
}
ZIP_FROM_OBJECT(intern, this);
@@ -1560,7 +1610,7 @@ static ZIPARCHIVE_METHOD(close)
ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
if (zip_close(intern)) {
- RETURN_FALSE;
+ zip_discard(intern);
}
efree(ze_obj->filename);
@@ -1637,6 +1687,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
if (zip_add_dir(intern, (const char *)s) == -1) {
RETVAL_FALSE;
}
+ zip_error_clear(intern);
RETVAL_TRUE;
}
@@ -1654,7 +1705,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
char *path = NULL;
char *remove_path = NULL;
char *add_path = NULL;
- int pattern_len, add_path_len = 0, remove_path_len = 0, path_len = 0;
+ int pattern_len, add_path_len, remove_path_len = 0, path_len = 0;
long remove_all_path = 0;
long flags = 0;
zval *options = NULL;
@@ -1667,12 +1718,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
ZIP_FROM_OBJECT(intern, this);
/* 1 == glob, 2==pcre */
if (type == 1) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|la",
&pattern, &pattern_len, &flags, &options) == FAILURE) {
return;
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sa",
&pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
return;
}
@@ -1703,13 +1754,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
zval **zval_file = NULL;
for (i = 0; i < found; i++) {
- char *file, *file_stripped, *entry_name;
+ char *file_stripped, *entry_name;
size_t entry_name_len, file_stripped_len;
char entry_name_buf[MAXPATHLEN];
char *basename = NULL;
if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) {
- file = Z_STRVAL_PP(zval_file);
if (remove_all_path) {
php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0,
&basename, (size_t *)&file_stripped_len TSRMLS_CC);
@@ -1786,7 +1836,7 @@ static ZIPARCHIVE_METHOD(addFile)
ZIP_FROM_OBJECT(intern, this);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sll",
&filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
return;
}
@@ -1856,16 +1906,18 @@ static ZIPARCHIVE_METHOD(addFromString)
/* TODO: fix _zip_replace */
if (cur_idx >= 0) {
if (zip_delete(intern, cur_idx) == -1) {
- goto fail;
+ zip_source_free(zs);
+ RETURN_FALSE;
}
}
- if (zip_add(intern, name, zs) != -1) {
+ if (zip_add(intern, name, zs) == -1) {
+ zip_source_free(zs);
+ RETURN_FALSE;
+ } else {
+ zip_error_clear(intern);
RETURN_TRUE;
}
-fail:
- zip_source_free(zs);
- RETURN_FALSE;
}
/* }}} */
@@ -1886,7 +1938,7 @@ static ZIPARCHIVE_METHOD(statName)
ZIP_FROM_OBJECT(intern, this);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l",
&name, &name_len, &flags) == FAILURE) {
return;
}
@@ -1942,7 +1994,7 @@ static ZIPARCHIVE_METHOD(locateName)
ZIP_FROM_OBJECT(intern, this);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l",
&name, &name_len, &flags) == FAILURE) {
return;
}
@@ -2522,7 +2574,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
ZIP_FROM_OBJECT(intern, this);
if (type == 1) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
return;
}
PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb);
@@ -2598,7 +2650,7 @@ static ZIPARCHIVE_METHOD(getStream)
ZIP_FROM_OBJECT(intern, this);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) {
return;
}
@@ -2621,6 +2673,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1)
+ ZEND_ARG_INFO(0, password)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
ZEND_END_ARG_INFO()
@@ -2733,6 +2789,7 @@ ZEND_END_ARG_INFO()
/* {{{ ze_zip_object_class_functions */
static const zend_function_entry zip_class_functions[] = {
ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(setPassword, arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
@@ -2875,7 +2932,7 @@ static PHP_MINFO_FUNCTION(zip)
php_info_print_table_row(2, "Zip", "enabled");
php_info_print_table_row(2, "Extension Version","$Id$");
- php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING);
+ php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
php_info_print_table_end();