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.c162
1 files changed, 147 insertions, 15 deletions
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index cdf77f20cd..d83272f564 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -28,6 +28,11 @@
#include "ext/standard/php_string.h"
#include "ext/pcre/php_pcre.h"
#include "ext/standard/php_filestat.h"
+#if PHP_VERSION_ID >= 70200
+#include "zend_interfaces.h"
+#elif defined(HAVE_SPL)
+#include "ext/spl/spl_iterators.h"
+#endif
#include "php_zip.h"
/* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
@@ -379,6 +384,20 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char
/* }}} */
/* {{{ 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); \
@@ -390,6 +409,7 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char
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 int php_zip_status(struct zip *za) /* {{{ */
@@ -786,6 +806,9 @@ static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, z
hnd.read_const_char_from_obj_func = read_char_from_obj_func;
hnd.type = rettype;
zend_hash_str_add_mem(prop_handler, name, strlen(name), &hnd, sizeof(zip_prop_handler));
+
+ /* Register for reflection */
+ zend_declare_property_null(zip_class_entry, name, strlen(name), ZEND_ACC_PUBLIC);
}
/* }}} */
@@ -1537,6 +1560,23 @@ static ZIPARCHIVE_METHOD(close)
}
/* }}} */
+/* {{{ proto bool ZipArchive::count()
+close the zip archive */
+static ZIPARCHIVE_METHOD(count)
+{
+ struct zip *intern;
+ zval *self = getThis();
+
+ if (!self) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, self);
+
+ RETVAL_LONG(zip_get_num_files(intern));
+}
+/* }}} */
+
/* {{{ proto string ZipArchive::getStatusString()
* Returns the status error message, system and/or zip messages */
static ZIPARCHIVE_METHOD(getStatusString)
@@ -2229,6 +2269,74 @@ static ZIPARCHIVE_METHOD(getExternalAttributesIndex)
/* }}} */
#endif /* ifdef ZIP_OPSYS_DEFAULT */
+#ifdef HAVE_ENCRYPTION
+/* {{{ proto bool ZipArchive::setEncryptionName(string name, int method, [string password])
+Set encryption method for file in zip, using its name */
+static ZIPARCHIVE_METHOD(setEncryptionName)
+{
+ struct zip *intern;
+ zval *self = getThis();
+ zend_long method;
+ zip_int64_t idx;
+ char *name, *password = NULL;
+ size_t name_len, password_len;
+
+ if (!self) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, self);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|s",
+ &name, &name_len, &method, &password, &password_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len < 1) {
+ php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
+ }
+
+ 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;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::setEncryptionIndex(int index, int method, [string password])
+Set encryption method for file in zip, using its index */
+static ZIPARCHIVE_METHOD(setEncryptionIndex)
+{
+ struct zip *intern;
+ zval *self = getThis();
+ zend_long index, method;
+ char *password = NULL;
+ size_t password_len;
+
+ if (!self) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, self);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|s",
+ &index, &method, &password, &password_len) == FAILURE) {
+ return;
+ }
+
+ if (zip_file_set_encryption(intern, index, (zip_uint16_t)method, password)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+#endif
+
/* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
Returns the comment of an entry using its name */
static ZIPARCHIVE_METHOD(getCommentName)
@@ -2959,6 +3067,20 @@ ZEND_END_ARG_INFO()
#endif /* ifdef ZIP_OPSYS_DEFAULT */
/* }}} */
+#ifdef HAVE_ENCRYPTION
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_name, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, method)
+ ZEND_ARG_INFO(0, password)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_index, 0, 0, 2)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, method)
+ ZEND_ARG_INFO(0, password)
+ZEND_END_ARG_INFO()
+#endif
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcompname, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, method)
@@ -2976,6 +3098,7 @@ 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(count, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(addFromString, arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
@@ -3010,6 +3133,10 @@ static const zend_function_entry zip_class_functions[] = {
ZIPARCHIVE_ME(getExternalAttributesIndex, arginfo_ziparchive_getextattrindex, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(setCompressionName, arginfo_ziparchive_setcompname, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(setCompressionIndex, arginfo_ziparchive_setcompindex, ZEND_ACC_PUBLIC)
+#ifdef HAVE_ENCRYPTION
+ ZIPARCHIVE_ME(setEncryptionName, arginfo_ziparchive_setencryption_name, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(setEncryptionIndex, arginfo_ziparchive_setencryption_index, ZEND_ACC_PUBLIC)
+#endif
PHP_FE_END
};
/* }}} */
@@ -3044,6 +3171,11 @@ static PHP_MINIT_FUNCTION(zip)
php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG);
php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING);
php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING);
+#if PHP_VERSION_ID >= 70200
+ zend_class_implements(zip_class_entry, 1, zend_ce_countable);
+#elif defined(HAVE_SPL)
+ zend_class_implements(zip_class_entry, 1, spl_ce_Countable);
+#endif
REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
@@ -3054,6 +3186,7 @@ static PHP_MINIT_FUNCTION(zip)
REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
+
#ifdef ZIP_FL_ENC_GUESS
/* Default filename encoding policy. */
REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_GUESS", ZIP_FL_ENC_GUESS);
@@ -3071,20 +3204,6 @@ static PHP_MINIT_FUNCTION(zip)
REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_CP437", ZIP_FL_ENC_CP437);
#endif
-/* XXX The below are rather not implemented or to check whether makes sense to expose. */
-/*#ifdef ZIP_FL_RECOMPRESS
- REGISTER_ZIP_CLASS_CONST_LONG("FL_RECOMPRESS", ZIP_FL_RECOMPRESS);
-#endif
-#ifdef ZIP_FL_ENCRYPTED
- REGISTER_ZIP_CLASS_CONST_LONG("FL_ENCRYPTED", ZIP_FL_ENCRYPTED);
-#endif
-#ifdef ZIP_FL_LOCAL
- REGISTER_ZIP_CLASS_CONST_LONG("FL_LOCAL", ZIP_FL_LOCAL);
-#endif
-#ifdef ZIP_FL_CENTRAL
- REGISTER_ZIP_CLASS_CONST_LONG("FL_CENTRAL", ZIP_FL_CENTRAL);
-#endif */
-
REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
@@ -3139,7 +3258,8 @@ static PHP_MINIT_FUNCTION(zip)
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_2", ZIP_OPSYS_OS_2);
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MACINTOSH", ZIP_OPSYS_MACINTOSH);
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_SYSTEM", ZIP_OPSYS_Z_SYSTEM);
- REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM", ZIP_OPSYS_CPM);
+ REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM", ZIP_OPSYS_CPM); // typo kept for BC
+ REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_CPM", ZIP_OPSYS_CPM);
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_WINDOWS_NTFS", ZIP_OPSYS_WINDOWS_NTFS);
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MVS", ZIP_OPSYS_MVS);
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VSE", ZIP_OPSYS_VSE);
@@ -3154,6 +3274,13 @@ static PHP_MINIT_FUNCTION(zip)
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DEFAULT", ZIP_OPSYS_DEFAULT);
#endif /* ifdef ZIP_OPSYS_DEFAULT */
+#ifdef HAVE_ENCRYPTION
+ REGISTER_ZIP_CLASS_CONST_LONG("EM_NONE", ZIP_EM_NONE);
+ REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_128", ZIP_EM_AES_128);
+ REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_192", ZIP_EM_AES_192);
+ REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_256", ZIP_EM_AES_256);
+#endif
+
php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper);
le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number);
@@ -3181,7 +3308,12 @@ static PHP_MINFO_FUNCTION(zip)
php_info_print_table_row(2, "Zip", "enabled");
php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
+#if HAVE_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
php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
+#endif
php_info_print_table_end();
}