diff --git a/php8/php_zip.c b/php8/php_zip.c index f131966..43c2da9 100644 --- a/php8/php_zip.c +++ b/php8/php_zip.c @@ -52,11 +52,12 @@ static int le_zip_entry; } /* }}} */ -/* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */ +/* {{{ 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 < 1) { \ - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); \ - RETURN_FALSE; \ + if (path_len == 0) { \ + zend_argument_value_error(1, "cannot be empty"); \ + RETURN_THROWS(); \ } \ if (zip_stat(za, path, flags, &sb) != 0) { \ RETURN_FALSE; \ @@ -334,7 +335,7 @@ typedef struct { #endif } zip_options; -static int php_zip_parse_options(zval *options, zip_options *opts) +static int php_zip_parse_options(HashTable *options, zip_options *opts) /* {{{ */ { zval *option; @@ -347,25 +348,42 @@ static int php_zip_parse_options(zval *options, zip_options *opts) opts->enc_method = -1; /* -1 to not change default */ #endif - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) { + 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_type_name(option)); + } opts->remove_all_path = zval_get_long(option); } - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "comp_method", sizeof("comp_method") - 1)) != NULL) { + 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_type_name(option)); + } opts->comp_method = zval_get_long(option); - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "comp_flags", sizeof("comp_flags") - 1)) != NULL) { + 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_type_name(option)); + } opts->comp_flags = zval_get_long(option); } } #ifdef HAVE_ENCRYPTION - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "enc_method", sizeof("enc_method") - 1)) != NULL) { + 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_type_name(option)); + } opts->enc_method = zval_get_long(option); - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "enc_password", sizeof("enc_password") - 1)) != NULL) { + if ((option = zend_hash_str_find(options, "enc_password", sizeof("enc_password") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "enc_password option expected to be a string"); + zend_type_error("Option \"enc_password\" must be of type string, %s given", + zend_zval_type_name(option)); return -1; } opts->enc_password = Z_STRVAL_P(option); @@ -373,49 +391,50 @@ static int php_zip_parse_options(zval *options, zip_options *opts) } #endif - if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_path", sizeof("remove_path") - 1)) != NULL) { + if ((option = zend_hash_str_find(options, "remove_path", sizeof("remove_path") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "remove_path option expected to be a string"); + zend_type_error("Option \"remove_path\" must be of type string, %s given", + zend_zval_type_name(option)); return -1; } - if (Z_STRLEN_P(option) < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string given as remove_path option"); + if (Z_STRLEN_P(option) == 0) { + zend_value_error("Option \"remove_path\" cannot be empty"); return -1; } if (Z_STRLEN_P(option) >= MAXPATHLEN) { - php_error_docref(NULL, E_WARNING, "remove_path string is too long (max: %d, %zd given)", - MAXPATHLEN - 1, Z_STRLEN_P(option)); + 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(Z_ARRVAL_P(options), "add_path", sizeof("add_path") - 1)) != NULL) { + if ((option = zend_hash_str_find(options, "add_path", sizeof("add_path") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "add_path option expected to be a string"); + zend_type_error("Option \"add_path\" must be of type string, %s given", + zend_zval_type_name(option)); return -1; } - if (Z_STRLEN_P(option) < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string given as the add_path option"); + if (Z_STRLEN_P(option) == 0) { + zend_value_error("Option \"add_path\" cannot be empty"); return -1; } if (Z_STRLEN_P(option) >= MAXPATHLEN) { - php_error_docref(NULL, E_WARNING, "add_path string too long (max: %d, %zd given)", - MAXPATHLEN - 1, Z_STRLEN_P(option)); + 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(Z_ARRVAL_P(options), "flags", sizeof("flags") - 1)) != NULL) { + if ((option = zend_hash_str_find(options, "flags", sizeof("flags") - 1)) != NULL) { if (Z_TYPE_P(option) != IS_LONG) { - php_error_docref(NULL, E_WARNING, "flags option expected to be a integer"); + zend_type_error("Option \"flags\" must be of type int, %s given", + zend_zval_type_name(option)); return -1; } opts->flags = Z_LVAL_P(option); @@ -599,6 +618,7 @@ int php_zip_glob(char *pattern, int pattern_len, zend_long flags, zval *return_v } if ((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; } @@ -1101,8 +1121,7 @@ static PHP_MSHUTDOWN_FUNCTION(zip); static PHP_MINFO_FUNCTION(zip); /* }}} */ -/* {{{ zip_module_entry - */ +/* {{{ zip_module_entry */ zend_module_entry zip_module_entry = { STANDARD_MODULE_HEADER, "zip", @@ -1122,8 +1141,7 @@ ZEND_GET_MODULE(zip) #endif /* set macro */ -/* {{{ proto resource zip_open(string filename) -Create new zip using source uri for output */ +/* {{{ Create new zip using source uri for output */ PHP_FUNCTION(zip_open) { char resolved_path[MAXPATHLEN + 1]; @@ -1136,8 +1154,8 @@ PHP_FUNCTION(zip_open) } if (ZSTR_LEN(filename) == 0) { - php_error_docref(NULL, E_WARNING, "Empty string as source"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) { @@ -1163,8 +1181,7 @@ PHP_FUNCTION(zip_open) } /* }}} */ -/* {{{ proto void zip_close(resource zip) - Close a Zip archive */ +/* {{{ Close a Zip archive */ PHP_FUNCTION(zip_close) { zval * zip; @@ -1183,8 +1200,7 @@ PHP_FUNCTION(zip_close) } /* }}} */ -/* {{{ proto resource zip_read(resource zip) - Returns the next file in the archive */ +/* {{{ Returns the next file in the archive */ PHP_FUNCTION(zip_read) { zval *zip_dp; @@ -1229,8 +1245,7 @@ PHP_FUNCTION(zip_read) } /* }}} */ -/* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode]) - Open a Zip File, pointed by the resource entry */ +/* {{{ Open a Zip File, pointed by the resource entry */ /* Dummy function to follow the old API */ PHP_FUNCTION(zip_entry_open) { @@ -1261,8 +1276,7 @@ PHP_FUNCTION(zip_entry_open) } /* }}} */ -/* {{{ proto bool zip_entry_close(resource zip_ent) - Close a zip entry */ +/* {{{ Close a zip entry */ PHP_FUNCTION(zip_entry_close) { zval * zip_entry; @@ -1280,8 +1294,7 @@ PHP_FUNCTION(zip_entry_close) } /* }}} */ -/* {{{ proto mixed zip_entry_read(resource zip_entry [, int len]) - Read from an open directory entry */ +/* {{{ Read from an open directory entry */ PHP_FUNCTION(zip_entry_read) { zval * zip_entry; @@ -1374,40 +1387,35 @@ static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ } /* }}} */ -/* {{{ proto string zip_entry_name(resource zip_entry) - Return the name given a ZZip entry */ +/* {{{ Return the name given a ZZip entry */ PHP_FUNCTION(zip_entry_name) { php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ -/* {{{ proto int zip_entry_compressedsize(resource zip_entry) - Return the compressed size of a ZZip entry */ +/* {{{ Return the compressed size of a ZZip entry */ PHP_FUNCTION(zip_entry_compressedsize) { php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ -/* {{{ proto int zip_entry_filesize(resource zip_entry) - Return the actual filesize of a ZZip entry */ +/* {{{ Return the actual filesize of a ZZip entry */ PHP_FUNCTION(zip_entry_filesize) { php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); } /* }}} */ -/* {{{ proto string zip_entry_compressionmethod(resource zip_entry) - Return a string containing the compression method used on a particular entry */ +/* {{{ 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); } /* }}} */ -/* {{{ proto mixed ZipArchive::open(string source [, int flags]) -Create new zip using source uri for output, return TRUE on success or the error code */ +/* {{{ Create new zip using source uri for output, return TRUE on success or the error code */ PHP_METHOD(ZipArchive, open) { struct zip *intern; @@ -1426,8 +1434,8 @@ PHP_METHOD(ZipArchive, open) ze_obj = Z_ZIP_P(self); if (ZSTR_LEN(filename) == 0) { - php_error_docref(NULL, E_WARNING, "Empty string as source"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) { @@ -1452,16 +1460,20 @@ PHP_METHOD(ZipArchive, open) ze_obj->filename = NULL; } - /* reduce BC break introduce in libzip 1.6.0 - "Do not accept empty files as valid zip archives any longer" */ - /* 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; /* 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; } } @@ -1478,8 +1490,7 @@ PHP_METHOD(ZipArchive, open) } /* }}} */ -/* {{{ proto resource ZipArchive::setPassword(string password) -Set the password for the active archive */ +/* {{{ Set the password for the active archive */ PHP_METHOD(ZipArchive, setPassword) { struct zip *intern; @@ -1506,8 +1517,7 @@ PHP_METHOD(ZipArchive, setPassword) } /* }}} */ -/* {{{ proto bool ZipArchive::close() -close the zip archive */ +/* {{{ close the zip archive */ PHP_METHOD(ZipArchive, close) { struct zip *intern; @@ -1558,8 +1568,7 @@ PHP_METHOD(ZipArchive, close) } /* }}} */ -/* {{{ proto bool ZipArchive::count() -close the zip archive */ +/* {{{ close the zip archive */ PHP_METHOD(ZipArchive, count) { struct zip *intern; @@ -1577,8 +1586,7 @@ PHP_METHOD(ZipArchive, count) } /* }}} */ -/* {{{ proto string ZipArchive::getStatusString() - * Returns the status error message, system and/or zip messages */ +/* {{{ Returns the status error message, system and/or zip messages */ PHP_METHOD(ZipArchive, getStatusString) { zval *self = ZEND_THIS; @@ -1621,8 +1629,7 @@ PHP_METHOD(ZipArchive, getStatusString) } /* }}} */ -/* {{{ proto bool ZipArchive::addEmptyDir(string dirname [, bool flags = 0]) -Returns the index of the entry named filename in the archive */ +/* {{{ Returns the index of the entry named filename in the archive */ PHP_METHOD(ZipArchive, addEmptyDir) { struct zip *intern; @@ -1671,30 +1678,30 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* char *path = "."; size_t path_len = 1; zend_long glob_flags = 0; - zval *options = NULL; + HashTable *options = NULL; zip_options opts; int found; zend_string *pattern; /* 1 == glob, 2 == pcre */ if (type == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|la", + 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|sa", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sh", &pattern, &path, &path_len, &options) == FAILURE) { RETURN_THROWS(); } } if (ZSTR_LEN(pattern) == 0) { - php_error_docref(NULL, E_NOTICE, "Empty string as pattern"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } - if (options && zend_hash_num_elements(Z_ARRVAL_P(options)) > 0 && (php_zip_parse_options(options, &opts) < 0)) { - RETURN_FALSE; + if (options && zend_hash_num_elements(options) > 0 && (php_zip_parse_options(options, &opts) < 0)) { + RETURN_THROWS(); } if (type == 1) { @@ -1778,24 +1785,21 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* } /* }}} */ -/* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]]) -Add files matching the glob pattern. See php's glob for the pattern syntax. */ +/* {{{ 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); } /* }}} */ -/* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]]) -Add files matching the pcre pattern. See php's pcre for the pattern syntax. */ +/* {{{ 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); } /* }}} */ -/* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length [, int flags = FL_OVERWRITE]]]]) -Add a file in a Zip archive using its path and the name to use. */ +/* {{{ Add a file in a Zip archive using its path and the name to use. */ PHP_METHOD(ZipArchive, addFile) { zval *self = ZEND_THIS; @@ -1811,8 +1815,8 @@ PHP_METHOD(ZipArchive, addFile) } if (ZSTR_LEN(filename) == 0) { - php_error_docref(NULL, E_NOTICE, "Empty string as filename"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (entry_name_len == 0) { @@ -1829,8 +1833,7 @@ PHP_METHOD(ZipArchive, addFile) } /* }}} */ -/* {{{ proto bool ZipArchive::replaceFile(string filepath, int index[, int start [, int length [, int flags = 0]]]) -Add a file in a Zip archive using its path and the name to use. */ +/* {{{ Add a file in a Zip archive using its path and the name to use. */ PHP_METHOD(ZipArchive, replaceFile) { zval *self = ZEND_THIS; @@ -1845,13 +1848,13 @@ PHP_METHOD(ZipArchive, replaceFile) } if (ZSTR_LEN(filename) == 0) { - php_error_docref(NULL, E_NOTICE, "Empty string as filename"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (index < 0) { - php_error_docref(NULL, E_NOTICE, "Invalid negative index"); - RETURN_FALSE; + 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), @@ -1863,8 +1866,7 @@ PHP_METHOD(ZipArchive, replaceFile) } /* }}} */ -/* {{{ proto bool ZipArchive::addFromString(string name, string content [, int flags = FL_OVERWRITE]) -Add a file using content and the entry name */ +/* {{{ Add a file using content and the entry name */ PHP_METHOD(ZipArchive, addFromString) { struct zip *intern; @@ -1913,8 +1915,7 @@ PHP_METHOD(ZipArchive, addFromString) } /* }}} */ -/* {{{ proto array ZipArchive::statName(string filename[, int flags]) -Returns the information about a the zip entry filename */ +/* {{{ Returns the information about a the zip entry filename */ PHP_METHOD(ZipArchive, statName) { struct zip *intern; @@ -1935,8 +1936,7 @@ PHP_METHOD(ZipArchive, statName) } /* }}} */ -/* {{{ proto resource ZipArchive::statIndex(int index[, int flags]) -Returns the zip entry information using its index */ +/* {{{ Returns the zip entry information using its index */ PHP_METHOD(ZipArchive, statIndex) { struct zip *intern; @@ -1959,8 +1959,7 @@ PHP_METHOD(ZipArchive, statIndex) } /* }}} */ -/* {{{ proto int ZipArchive::locateName(string filename[, int flags]) -Returns the index of the entry named filename in the archive */ +/* {{{ Returns the index of the entry named filename in the archive */ PHP_METHOD(ZipArchive, locateName) { struct zip *intern; @@ -1989,8 +1988,7 @@ PHP_METHOD(ZipArchive, locateName) } /* }}} */ -/* {{{ proto string ZipArchive::getNameIndex(int index [, int flags]) -Returns the name of the file at position index */ +/* {{{ Returns the name of the file at position index */ PHP_METHOD(ZipArchive, getNameIndex) { struct zip *intern; @@ -2015,8 +2013,7 @@ PHP_METHOD(ZipArchive, getNameIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::setArchiveComment(string comment) -Set or remove (NULL/'') the comment of the archive */ +/* {{{ Set or remove (NULL/'') the comment of the archive */ PHP_METHOD(ZipArchive, setArchiveComment) { struct zip *intern; @@ -2031,8 +2028,8 @@ PHP_METHOD(ZipArchive, setArchiveComment) ZIP_FROM_OBJECT(intern, self); if (comment_len > 0xffff) { - php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes"); - RETURN_FALSE; + zend_argument_value_error(1, "must be less than 65535 bytes"); + RETURN_THROWS(); } if (zip_set_archive_comment(intern, (const char *)comment, comment_len)) { @@ -2043,8 +2040,7 @@ PHP_METHOD(ZipArchive, setArchiveComment) } /* }}} */ -/* {{{ proto string ZipArchive::getArchiveComment([int flags]) -Returns the comment of an entry using its index */ +/* {{{ Returns the comment of an entry using its index */ PHP_METHOD(ZipArchive, getArchiveComment) { struct zip *intern; @@ -2067,8 +2063,7 @@ PHP_METHOD(ZipArchive, getArchiveComment) } /* }}} */ -/* {{{ proto bool ZipArchive::setCommentName(string name, string comment) -Set or remove (NULL/'') the comment of an entry using its Name */ +/* {{{ Set or remove (NULL/'') the comment of an entry using its Name */ PHP_METHOD(ZipArchive, setCommentName) { struct zip *intern; @@ -2082,15 +2077,16 @@ PHP_METHOD(ZipArchive, setCommentName) RETURN_THROWS(); } - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } ZIP_FROM_OBJECT(intern, self); if (comment_len > 0xffff) { - php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes"); - RETURN_FALSE; + zend_argument_value_error(2, "must be less than 65535 bytes"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); @@ -2101,8 +2097,7 @@ PHP_METHOD(ZipArchive, setCommentName) } /* }}} */ -/* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment) -Set or remove (NULL/'') the comment of an entry using its index */ +/* {{{ Set or remove (NULL/'') the comment of an entry using its index */ PHP_METHOD(ZipArchive, setCommentIndex) { struct zip *intern; @@ -2120,8 +2115,8 @@ PHP_METHOD(ZipArchive, setCommentIndex) ZIP_FROM_OBJECT(intern, self); if (comment_len > 0xffff) { - php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes"); - RETURN_FALSE; + zend_argument_value_error(2, "must be less than 65535 bytes"); + RETURN_THROWS(); } PHP_ZIP_STAT_INDEX(intern, index, 0, sb); @@ -2132,8 +2127,7 @@ PHP_METHOD(ZipArchive, setCommentIndex) /* those constants/functions are only available in libzip since 0.11.2 */ #ifdef ZIP_OPSYS_DEFAULT -/* {{{ proto bool ZipArchive::setExternalAttributesName(string name, int opsys, int attr [, int flags]) -Set external attributes for file in zip, using its name */ +/* {{{ Set external attributes for file in zip, using its name */ PHP_METHOD(ZipArchive, setExternalAttributesName) { struct zip *intern; @@ -2150,11 +2144,13 @@ PHP_METHOD(ZipArchive, setExternalAttributesName) ZIP_FROM_OBJECT(intern, self); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2166,8 +2162,7 @@ PHP_METHOD(ZipArchive, setExternalAttributesName) } /* }}} */ -/* {{{ proto bool ZipArchive::setExternalAttributesIndex(int index, int opsys, int attr [, int flags]) -Set external attributes for file in zip, using its index */ +/* {{{ Set external attributes for file in zip, using its index */ PHP_METHOD(ZipArchive, setExternalAttributesIndex) { struct zip *intern; @@ -2191,8 +2186,7 @@ PHP_METHOD(ZipArchive, setExternalAttributesIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::getExternalAttributesName(string name, int &opsys, int &attr [, int flags]) -Get external attributes for file in zip, using its name */ +/* {{{ Get external attributes for file in zip, using its name */ PHP_METHOD(ZipArchive, getExternalAttributesName) { struct zip *intern; @@ -2211,11 +2205,13 @@ PHP_METHOD(ZipArchive, getExternalAttributesName) ZIP_FROM_OBJECT(intern, self); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2229,8 +2225,7 @@ PHP_METHOD(ZipArchive, getExternalAttributesName) } /* }}} */ -/* {{{ proto bool ZipArchive::getExternalAttributesIndex(int index, int &opsys, int &attr [, int flags]) -Get external attributes for file in zip, using its index */ +/* {{{ Get external attributes for file in zip, using its index */ PHP_METHOD(ZipArchive, getExternalAttributesIndex) { struct zip *intern; @@ -2260,8 +2255,7 @@ PHP_METHOD(ZipArchive, 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 */ +/* {{{ Set encryption method for file in zip, using its name */ PHP_METHOD(ZipArchive, setEncryptionName) { struct zip *intern; @@ -2278,11 +2272,13 @@ PHP_METHOD(ZipArchive, setEncryptionName) ZIP_FROM_OBJECT(intern, self); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2294,8 +2290,7 @@ PHP_METHOD(ZipArchive, setEncryptionName) } /* }}} */ -/* {{{ proto bool ZipArchive::setEncryptionIndex(int index, int method, [string password]) -Set encryption method for file in zip, using its index */ +/* {{{ Set encryption method for file in zip, using its index */ PHP_METHOD(ZipArchive, setEncryptionIndex) { struct zip *intern; @@ -2319,8 +2314,7 @@ PHP_METHOD(ZipArchive, setEncryptionIndex) /* }}} */ #endif -/* {{{ proto string ZipArchive::getCommentName(string name[, int flags]) -Returns the comment of an entry using its name */ +/* {{{ Returns the comment of an entry using its name */ PHP_METHOD(ZipArchive, getCommentName) { struct zip *intern; @@ -2339,12 +2333,13 @@ PHP_METHOD(ZipArchive, getCommentName) ZIP_FROM_OBJECT(intern, self); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); - RETURN_FALSE; + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2354,8 +2349,7 @@ PHP_METHOD(ZipArchive, getCommentName) } /* }}} */ -/* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags]) -Returns the comment of an entry using its index */ +/* {{{ Returns the comment of an entry using its index */ PHP_METHOD(ZipArchive, getCommentIndex) { struct zip *intern; @@ -2378,10 +2372,9 @@ PHP_METHOD(ZipArchive, getCommentIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::setCompressionName(string name, int comp_method[, int comp_flags]) -Set the compression of a file in zip, using its name */ +/* {{{ 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; @@ -2396,11 +2389,13 @@ PHP_METHOD(ZipArchive, setCompressionName) ZIP_FROM_OBJECT(intern, this); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2413,8 +2408,7 @@ PHP_METHOD(ZipArchive, setCompressionName) } /* }}} */ -/* {{{ proto bool ZipArchive::setCompressionIndex(int index, int comp_method[, int comp_flags]) -Set the compression of a file in zip, using its index */ +/* {{{ Set the compression of a file in zip, using its index */ PHP_METHOD(ZipArchive, setCompressionIndex) { struct zip *intern; @@ -2438,10 +2432,9 @@ PHP_METHOD(ZipArchive, setCompressionIndex) /* }}} */ #ifdef HAVE_SET_MTIME -/* {{{ proto bool ZipArchive::setMtimeName(string name, int timestamp[, int flags]) -Set the modification time of a file in zip, using its name */ +/* {{{ 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; @@ -2456,11 +2449,13 @@ PHP_METHOD(ZipArchive, setMtimeName) ZIP_FROM_OBJECT(intern, this); - if (name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + if (name_len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } idx = zip_name_locate(intern, name, 0); + if (idx < 0) { RETURN_FALSE; } @@ -2473,8 +2468,7 @@ PHP_METHOD(ZipArchive, setMtimeName) } /* }}} */ -/* {{{ proto bool ZipArchive::setMtimeIndex(int index, int timestamp[, int flags]) -Set the modification time of a file in zip, using its index */ +/* {{{ Set the modification time of a file in zip, using its index */ PHP_METHOD(ZipArchive, setMtimeIndex) { struct zip *intern; @@ -2498,8 +2492,7 @@ PHP_METHOD(ZipArchive, setMtimeIndex) /* }}} */ #endif -/* {{{ proto bool ZipArchive::deleteIndex(int index) -Delete a file using its index */ +/* {{{ Delete a file using its index */ PHP_METHOD(ZipArchive, deleteIndex) { struct zip *intern; @@ -2524,8 +2517,7 @@ PHP_METHOD(ZipArchive, deleteIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::deleteName(string name) -Delete a file using its index */ +/* {{{ Delete a file using its index */ PHP_METHOD(ZipArchive, deleteName) { struct zip *intern; @@ -2552,8 +2544,7 @@ PHP_METHOD(ZipArchive, deleteName) } /* }}} */ -/* {{{ proto bool ZipArchive::renameIndex(int index, string new_name) -Rename an entry selected by its index to new_name */ +/* {{{ Rename an entry selected by its index to new_name */ PHP_METHOD(ZipArchive, renameIndex) { struct zip *intern; @@ -2572,9 +2563,9 @@ PHP_METHOD(ZipArchive, renameIndex) ZIP_FROM_OBJECT(intern, self); - if (new_name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as new entry name"); - RETURN_FALSE; + if (new_name_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } if (zip_file_rename(intern, index, (const char *)new_name, 0) != 0) { @@ -2585,8 +2576,7 @@ PHP_METHOD(ZipArchive, renameIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::renameName(string name, string new_name) -Rename an entry selected by its name to new_name */ +/* {{{ Rename an entry selected by its name to new_name */ PHP_METHOD(ZipArchive, renameName) { struct zip *intern; @@ -2601,9 +2591,9 @@ PHP_METHOD(ZipArchive, renameName) ZIP_FROM_OBJECT(intern, self); - if (new_name_len < 1) { - php_error_docref(NULL, E_NOTICE, "Empty string as new entry name"); - RETURN_FALSE; + if (new_name_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); @@ -2616,8 +2606,7 @@ PHP_METHOD(ZipArchive, renameName) } /* }}} */ -/* {{{ proto bool ZipArchive::unchangeIndex(int index) -Changes to the file at position index are reverted */ +/* {{{ Changes to the file at position index are reverted */ PHP_METHOD(ZipArchive, unchangeIndex) { struct zip *intern; @@ -2642,8 +2631,7 @@ PHP_METHOD(ZipArchive, unchangeIndex) } /* }}} */ -/* {{{ proto bool ZipArchive::unchangeName(string name) -Changes to the file named 'name' are reverted */ +/* {{{ Changes to the file named 'name' are reverted */ PHP_METHOD(ZipArchive, unchangeName) { struct zip *intern; @@ -2672,8 +2660,7 @@ PHP_METHOD(ZipArchive, unchangeName) } /* }}} */ -/* {{{ proto bool ZipArchive::unchangeAll() -All changes to files and global information in archive are reverted */ +/* {{{ All changes to files and global information in archive are reverted */ PHP_METHOD(ZipArchive, unchangeAll) { struct zip *intern; @@ -2693,8 +2680,7 @@ PHP_METHOD(ZipArchive, unchangeAll) } /* }}} */ -/* {{{ proto bool ZipArchive::unchangeArchive() -Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */ +/* {{{ Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */ PHP_METHOD(ZipArchive, unchangeArchive) { struct zip *intern; @@ -2714,8 +2700,7 @@ PHP_METHOD(ZipArchive, unchangeArchive) } /* }}} */ -/* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files]) -Extract one or more file from a zip archive */ +/* {{{ Extract one or more file from a zip archive */ /* TODO: * - allow index or array of indices * - replace path @@ -2868,24 +2853,21 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ } /* }}} */ -/* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]]) -get the contents of an entry using its name */ +/* {{{ get the contents of an entry using its name */ PHP_METHOD(ZipArchive, getFromName) { php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ -/* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]]) -get the contents of an entry using its index */ +/* {{{ get the contents of an entry using its index */ PHP_METHOD(ZipArchive, getFromIndex) { php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ -/* {{{ proto resource ZipArchive::getStream(string entryname) -get a stream for an entry using its name */ +/* {{{ get a stream for an entry using its name */ PHP_METHOD(ZipArchive, getStream) { struct zip *intern; @@ -2925,35 +2907,23 @@ static void _php_zip_progress_callback(zip_t *arch, double state, void *ptr) ze_zip_object *obj = ptr; ZVAL_DOUBLE(&cb_args[0], state); - if (call_user_function_ex(EG(function_table), NULL, &obj->progress_callback, &cb_retval, 1, cb_args, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) { + if (call_user_function(EG(function_table), NULL, &obj->progress_callback, &cb_retval, 1, cb_args) == SUCCESS && !Z_ISUNDEF(cb_retval)) { zval_ptr_dtor(&cb_retval); } } -/* {{{ proto bool ZipArchive::registerProgressCallback(double rate, callable callback) -register a progression callback: void callback(double state); */ +/* {{{ register a progression callback: void callback(double state); */ PHP_METHOD(ZipArchive, registerProgressCallback) { struct zip *intern; - zval *self = getThis(); + zval *self = ZEND_THIS; double rate; - zval *callback; + zend_fcall_info fci; + zend_fcall_info_cache fcc; ze_zip_object *obj; - if (!self) { - RETURN_FALSE; - } - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "dz", &rate, &callback) == FAILURE) { - return; - } - - /* callable? */ - if (!zend_is_callable(callback, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(callback); - php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "df", &rate, &fci, &fcc) == FAILURE) { + RETURN_THROWS(); } ZIP_FROM_OBJECT(intern, self); @@ -2964,7 +2934,7 @@ PHP_METHOD(ZipArchive, registerProgressCallback) _php_zip_progress_callback_free(obj); /* register */ - ZVAL_COPY(&obj->progress_callback, callback); + ZVAL_COPY(&obj->progress_callback, &fci.function_name); if (zip_register_progress_callback_with_state(intern, rate, _php_zip_progress_callback, _php_zip_progress_callback_free, obj)) { RETURN_FALSE; } @@ -2981,7 +2951,7 @@ static int _php_zip_cancel_callback(zip_t *arch, void *ptr) int retval = 0; ze_zip_object *obj = ptr; - if (call_user_function_ex(EG(function_table), NULL, &obj->cancel_callback, &cb_retval, 0, NULL, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) { + if (call_user_function(EG(function_table), NULL, &obj->cancel_callback, &cb_retval, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) { retval = zval_get_long(&cb_retval); zval_ptr_dtor(&cb_retval); } @@ -2989,40 +2959,27 @@ static int _php_zip_cancel_callback(zip_t *arch, void *ptr) return retval; } -/* {{{ proto bool ZipArchive::registerCancelCallback(callable callback) -register a progression callback: int callback(double state); */ +/* {{{ register a progression callback: int callback(double state); */ PHP_METHOD(ZipArchive, registerCancelCallback) { struct zip *intern; - zval *self = getThis(); - zval *callback; + zval *self = ZEND_THIS; + zend_fcall_info fci; + zend_fcall_info_cache fcc; ze_zip_object *obj; - - if (!self) { - RETURN_FALSE; - } - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "f", &fci, &fcc) == FAILURE) { + RETURN_THROWS(); } ZIP_FROM_OBJECT(intern, self); - /* callable? */ - if (!zend_is_callable(callback, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(callback); - php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; - } - obj = Z_ZIP_P(self); /* free if called twice */ _php_zip_cancel_callback_free(obj); /* register */ - ZVAL_COPY(&obj->cancel_callback, callback); + ZVAL_COPY(&obj->cancel_callback, &fci.function_name); if (zip_register_cancel_callback_with_state(intern, _php_zip_cancel_callback, _php_zip_cancel_callback_free, obj)) { RETURN_FALSE; } @@ -3033,8 +2990,7 @@ PHP_METHOD(ZipArchive, registerCancelCallback) #endif #ifdef HAVE_METHOD_SUPPORTED -/* {{{ proto bool ZipArchive::isCompressionMethodSupported(int method, bool enc) -check if a compression method is available in used libzip */ +/* {{{ check if a compression method is available in used libzip */ PHP_METHOD(ZipArchive, isCompressionMethodSupported) { zend_long method; @@ -3047,8 +3003,7 @@ PHP_METHOD(ZipArchive, isCompressionMethodSupported) } /* }}} */ -/* {{{ proto bool ZipArchive::isEncryptionMethodSupported(int method, bool enc) -check if a encryption method is available in used libzip */ +/* {{{ check if a encryption method is available in used libzip */ PHP_METHOD(ZipArchive, isEncryptionMethodSupported) { zend_long method; @@ -3136,6 +3091,9 @@ static PHP_MINIT_FUNCTION(zip) #ifdef ZIP_CM_LZMA2 REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA2", ZIP_CM_LZMA2); #endif +#ifdef ZIP_CM_ZSTD + REGISTER_ZIP_CLASS_CONST_LONG("CM_ZSTD", ZIP_CM_ZSTD); +#endif #ifdef ZIP_CM_XZ REGISTER_ZIP_CLASS_CONST_LONG("CM_XZ", ZIP_CM_XZ); #endif @@ -3240,8 +3198,7 @@ static PHP_MINIT_FUNCTION(zip) } /* }}} */ -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ +/* {{{ PHP_MSHUTDOWN_FUNCTION */ static PHP_MSHUTDOWN_FUNCTION(zip) { zend_hash_destroy(&zip_prop_handlers); @@ -3250,8 +3207,7 @@ static PHP_MSHUTDOWN_FUNCTION(zip) } /* }}} */ -/* {{{ PHP_MINFO_FUNCTION - */ +/* {{{ PHP_MINFO_FUNCTION */ static PHP_MINFO_FUNCTION(zip) { php_info_print_table_start(); diff --git a/php8/php_zip.h b/php8/php_zip.h index ddc35df..92df580 100644 --- a/php8/php_zip.h +++ b/php8/php_zip.h @@ -31,7 +31,7 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.19.0" +#define PHP_ZIP_VERSION "1.19.1-dev" #define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) diff --git a/php8/php_zip.stub.php b/php8/php_zip.stub.php index da8e373..01f055f 100644 --- a/php8/php_zip.stub.php +++ b/php8/php_zip.stub.php @@ -2,44 +2,66 @@ /** @generate-function-entries */ -/** @return resource|int|false */ +/** + * @return resource|int|false + * @deprecated + */ function zip_open(string $filename) {} /** * @param resource $zip + * @deprecated */ function zip_close($zip): void {} /** * @param resource $zip * @return resource|false + * @deprecated */ function zip_read($zip) {} /** * @param resource $zip_dp * @param resource $zip_entry + * @deprecated */ function zip_entry_open($zip_dp, $zip_entry, string $mode = 'rb'): bool {} /** * @param resource $zip_ent + * @deprecated */ function zip_entry_close($zip_ent): bool {} -/** @param resource $zip_entry */ +/** + * @param resource $zip_entry + * @deprecated + */ function zip_entry_read($zip_entry, int $len = 1024): string|false {} -/** @param resource $zip_entry */ +/** + * @param resource $zip_entry + * @deprecated + */ function zip_entry_name($zip_entry): string|false {} -/** @param resource $zip_entry */ +/** + * @param resource $zip_entry + * @deprecated + */ function zip_entry_compressedsize($zip_entry): int|false {} -/** @param resource $zip_entry */ +/** + * @param resource $zip_entry + * @deprecated + */ function zip_entry_filesize($zip_entry): int|false {} -/** @param resource $zip_entry */ +/** + * @param resource $zip_entry + * @deprecated + */ function zip_entry_compressionmethod($zip_entry): string|false {} class ZipArchive @@ -161,10 +183,18 @@ class ZipArchive /** @return bool */ public function setExternalAttributesIndex(int $index, int $opsys, int $attr, int $flags = 0) {} - /** @return bool */ + /** + * @param int $opsys + * @param int $attr + * @return bool + */ public function getExternalAttributesName(string $name, &$opsys, &$attr, int $flags = 0) {} - /** @return bool */ + /** + * @param int $opsys + * @param int $attr + * @return bool + */ public function getExternalAttributesIndex(int $index, &$opsys, &$attr, int $flags = 0) {} #endif @@ -194,9 +224,9 @@ class ZipArchive #ifdef HAVE_METHOD_SUPPORTED /** @return bool */ - public static function isCompressionMethodSupported(int $method, bool $enc): bool {} + public static function isCompressionMethodSupported(int $method, bool $enc = true): bool {} /** @return bool */ - public static function isEncryptionMethodSupported(int $method, bool $enc): bool {} + public static function isEncryptionMethodSupported(int $method, bool $enc = true): bool {} #endif } diff --git a/php8/php_zip_arginfo.h b/php8/php_zip_arginfo.h index c1e8f24..87222c9 100644 --- a/php8/php_zip_arginfo.h +++ b/php8/php_zip_arginfo.h @@ -1,4 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. */ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: 880148896a71ad9bd076bb42c735ff1b83cd0731 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -271,9 +272,9 @@ ZEND_END_ARG_INFO() #endif #if defined(HAVE_METHOD_SUPPORTED) -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_isCompressionMethodSupported, 0, 2, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ZipArchive_isCompressionMethodSupported, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, method, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, enc, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enc, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() #endif @@ -366,16 +367,16 @@ ZEND_METHOD(ZipArchive, isEncryptionMethodSupported); static const zend_function_entry ext_functions[] = { - ZEND_FE(zip_open, arginfo_zip_open) - ZEND_FE(zip_close, arginfo_zip_close) - ZEND_FE(zip_read, arginfo_zip_read) - ZEND_FE(zip_entry_open, arginfo_zip_entry_open) - ZEND_FE(zip_entry_close, arginfo_zip_entry_close) - ZEND_FE(zip_entry_read, arginfo_zip_entry_read) - ZEND_FE(zip_entry_name, arginfo_zip_entry_name) - ZEND_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize) - ZEND_FE(zip_entry_filesize, arginfo_zip_entry_filesize) - ZEND_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod) + ZEND_DEP_FE(zip_open, arginfo_zip_open) + ZEND_DEP_FE(zip_close, arginfo_zip_close) + ZEND_DEP_FE(zip_read, arginfo_zip_read) + ZEND_DEP_FE(zip_entry_open, arginfo_zip_entry_open) + ZEND_DEP_FE(zip_entry_close, arginfo_zip_entry_close) + ZEND_DEP_FE(zip_entry_read, arginfo_zip_entry_read) + ZEND_DEP_FE(zip_entry_name, arginfo_zip_entry_name) + ZEND_DEP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize) + ZEND_DEP_FE(zip_entry_filesize, arginfo_zip_entry_filesize) + ZEND_DEP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod) ZEND_FE_END }; diff --git a/tests/bug53885.phpt b/tests/bug53885.phpt index 602eae8..fecbf55 100644 --- a/tests/bug53885.phpt +++ b/tests/bug53885.phpt @@ -3,6 +3,7 @@ Bug #53885 (ZipArchive segfault with FL_UNCHANGED on empty archive) --SKIPIF-- = 80000) die('skip only for PHP < 8'); ?> --FILE-- open($fname); +$nx->open($fname); $nx->locateName("a",ZIPARCHIVE::FL_UNCHANGED); $nx->statName("a",ZIPARCHIVE::FL_UNCHANGED); ?> diff --git a/tests/bug53885_php8.phpt b/tests/bug53885_php8.phpt new file mode 100644 index 0000000..19fb350 --- /dev/null +++ b/tests/bug53885_php8.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #53885 (ZipArchive segfault with FL_UNCHANGED on empty archive) +--SKIPIF-- + +--FILE-- +open($fname); +$nx->locateName("a",ZIPARCHIVE::FL_UNCHANGED); +$nx->statName("a",ZIPARCHIVE::FL_UNCHANGED); +?> +==DONE== +--CLEAN-- + +--EXPECTF-- +Deprecated: ZipArchive::open(): Using empty file as ZipArchive is deprecated in %s +==DONE== diff --git a/tests/bug7214.phpt b/tests/bug7214.phpt index f791b79..d5c7f3e 100644 --- a/tests/bug7214.phpt +++ b/tests/bug7214.phpt @@ -5,6 +5,8 @@ Bug #7214 (zip_entry_read() binary safe) /* $Id$ */ if(!extension_loaded('zip')) die('skip'); ?> +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- open($file)) { echo $zip->getArchiveComment() . "\n"; $idx = $zip->locateName('foo'); -echo $zip->getCommentName('foo') . "\n"; -echo $zip->getCommentIndex($idx); +var_dump($zip->getCommentName('foo')); +var_dump($zip->getCommentIndex($idx)); -echo $zip->getCommentName('') . "\n"; +try { + echo $zip->getCommentName('') . "\n"; +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $zip->close(); ?> ---EXPECTF-- +--EXPECT-- Zip archive comment -foo comment -foo comment -Notice: ZipArchive::getCommentName(): Empty string as entry name in %s on line %d +string(11) "foo comment" +string(11) "foo comment" +ZipArchive::getCommentName(): Argument #1 ($name) cannot be empty diff --git a/tests/oo_open.phpt b/tests/oo_open.phpt index 0760db3..bd251e7 100644 --- a/tests/oo_open.phpt +++ b/tests/oo_open.phpt @@ -4,6 +4,7 @@ zip::open() function = 80000) die('skip PHP < 8 only'); ?> --FILE-- +--FILE-- +open($dirname . 'nofile'); +if ($r !== TRUE) { + echo "ER_OPEN: ok\n"; +} else { + echo "ER_OPEN: FAILED\n"; +} + +$r = $zip->open($dirname . 'nofile', ZIPARCHIVE::CREATE); +if (!$r) { + echo "create: failed\n"; +} else { + echo "create: ok\n"; +} +@unlink($dirname . 'nofile'); + +$zip = new ZipArchive; +try { + $zip->open(''); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +if (!$zip->open($dirname . 'test.zip')) { + exit("failed 1\n"); +} + +if ($zip->status == ZIPARCHIVE::ER_OK) { + echo "OK\n"; +} else { + echo "failed\n"; +} +?> +--EXPECT-- +ER_OPEN: ok +create: ok +ZipArchive::open(): Argument #1 ($filename) cannot be empty +OK diff --git a/tests/oo_setcomment_error.phpt b/tests/oo_setcomment_error.phpt index a8f1e47..b5b251b 100644 --- a/tests/oo_setcomment_error.phpt +++ b/tests/oo_setcomment_error.phpt @@ -3,6 +3,7 @@ setComment error behavior --SKIPIF-- = 80000) die('skip PHP < 8 only'); ?> --FILE-- +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +$zip->addFromString('entry1.txt', 'entry #1'); +$zip->addFromString('entry2.txt', 'entry #2'); + +$longComment = str_repeat('a', 0x10000); + +try { + var_dump($zip->setArchiveComment($longComment)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump($zip->setCommentName('entry1.txt', $longComment)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump($zip->setCommentIndex(1, $longComment)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +$zip->close(); +?> +--EXPECT-- +ZipArchive::setArchiveComment(): Argument #1 ($comment) must be less than 65535 bytes +ZipArchive::setCommentName(): Argument #2 ($comment) must be less than 65535 bytes +ZipArchive::setCommentIndex(): Argument #2 ($comment) must be less than 65535 bytes +--CLEAN-- + diff --git a/tests/oo_setcompression.phpt b/tests/oo_setcompression.phpt index 8a746a8..fd5fb54 100644 --- a/tests/oo_setcompression.phpt +++ b/tests/oo_setcompression.phpt @@ -5,6 +5,8 @@ setCompressionName and setCompressionIndex methods /* $Id$ */ if (!extension_loaded('zip')) die('skip'); ?> +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +--INI-- +error_reporting=24575 --FILE-- +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +getMessage() . \PHP_EOL; +} + +echo "Test case 2:\n"; +$zip = zip_open("/non_exisitng_directory/test_procedural.zip"); +echo is_resource($zip) ? "OK" : "Failure"; +?> +--EXPECTF-- +Test case 1: +Deprecated: Function zip_open() is deprecated in %s on line %d +zip_open(): Argument #1 ($filename) cannot be empty +Test case 2: + +Deprecated: Function zip_open() is deprecated in %s on line %d +Failure From d94273e08d507ede72467ee2eb3bd229410efac0 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Fri, 28 Aug 2020 15:41:27 +0200 Subject: [PATCH] Improve type declarations for Zend APIs Voidification of Zend API which always succeeded Use bool argument types instead of int for boolean arguments Use bool return type for functions which return true/false (1/0) Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics --- php8/php_zip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php8/php_zip.c b/php8/php_zip.c index 43c2da9..c1a569a 100644 --- a/php8/php_zip.c +++ b/php8/php_zip.c @@ -1290,7 +1290,8 @@ PHP_FUNCTION(zip_entry_close) RETURN_THROWS(); } - RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(zip_entry))); + zend_list_close(Z_RES_P(zip_entry)); + RETURN_TRUE; } /* }}} */ From 6e93832682dc8d86540341f5c996d56798b6b691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 24 Aug 2020 20:42:29 +0200 Subject: [PATCH] Move custom type checks to ZPP Closes GH-6034 --- php8/php_zip.c | 61 ++++++++++++++++++++---------------------- php8/php_zip.stub.php | 7 ++--- php8/php_zip_arginfo.h | 4 +-- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/php8/php_zip.c b/php8/php_zip.c index c1a569a..6ebbc42 100644 --- a/php8/php_zip.c +++ b/php8/php_zip.c @@ -2712,16 +2712,20 @@ PHP_METHOD(ZipArchive, extractTo) struct zip *intern; zval *self = ZEND_THIS; - zval *zval_files = NULL; + zend_string *files_str = NULL; + HashTable *files_ht = NULL; + zval *zval_file = NULL; php_stream_statbuf ssb; char *pathto; size_t pathto_len; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|z", &pathto, &pathto_len, &zval_files) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH(pathto, pathto_len) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(files_str, files_ht) + ZEND_PARSE_PARAMETERS_END(); ZIP_FROM_OBJECT(intern, self); @@ -2736,37 +2740,29 @@ PHP_METHOD(ZipArchive, extractTo) } } - if (zval_files && Z_TYPE_P(zval_files) != IS_NULL) { - uint32_t nelems, i; + uint32_t nelems, i; - switch (Z_TYPE_P(zval_files)) { - case IS_STRING: - if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files))) { - RETURN_FALSE; - } - break; - case IS_ARRAY: - nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files)); - if (nelems == 0 ) { - RETURN_FALSE; - } - for (i = 0; i < nelems; i++) { - if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), 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))) { - RETURN_FALSE; - } - break; + if (files_str) { + if (!php_zip_extract_file(intern, pathto, ZSTR_VAL(files_str), ZSTR_LEN(files_str))) { + RETURN_FALSE; + } + } else if (files_ht) { + nelems = zend_hash_num_elements(files_ht); + if (nelems == 0 ) { + RETURN_FALSE; + } + for (i = 0; i < nelems; i++) { + if ((zval_file = zend_hash_index_find(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))) { + RETURN_FALSE; } - } + break; } - break; - default: - zend_argument_type_error(2, "must be of type array|string|null, %s given", zend_zval_type_name(zval_files)); - RETURN_THROWS(); + } } } else { /* Extract all files */ @@ -2784,6 +2780,7 @@ PHP_METHOD(ZipArchive, extractTo) } } } + RETURN_TRUE; } /* }}} */ diff --git a/php8/php_zip.stub.php b/php8/php_zip.stub.php index 01f055f..cde2662 100644 --- a/php8/php_zip.stub.php +++ b/php8/php_zip.stub.php @@ -161,11 +161,8 @@ public function unchangeIndex(int $index) {} /** @return bool */ public function unchangeName(string $name) {} - /** - * @param array|string|null $files - * @return bool - */ - public function extractTo(string $pathto, $files = null) {} + /** @return bool */ + public function extractTo(string $pathto, array|string|null $files = null) {} /** @return string|false */ public function getFromName(string $entryname, int $len = 0, int $flags = 0) {} diff --git a/php8/php_zip_arginfo.h b/php8/php_zip_arginfo.h index 87222c9..c9f90d5 100644 --- a/php8/php_zip_arginfo.h +++ b/php8/php_zip_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 880148896a71ad9bd076bb42c735ff1b83cd0731 */ + * Stub hash: 49f168c537e48f8a3998d67812a5e2e6a2463533 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -175,7 +175,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_extractTo, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, pathto, IS_STRING, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, files, "null") + ZEND_ARG_TYPE_MASK(0, files, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_getFromName, 0, 0, 1) From 80a363601506de6e9038c8e794d0c797cd64b997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 11 Sep 2020 00:23:54 +0200 Subject: [PATCH] Consolidate new union type ZPP macro names They will now follow the canonical order of types. Older macros are left intact due to maintaining BC. --- php8/php_zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php8/php_zip.c b/php8/php_zip.c index 6ebbc42..96baaba 100644 --- a/php8/php_zip.c +++ b/php8/php_zip.c @@ -2724,7 +2724,7 @@ PHP_METHOD(ZipArchive, extractTo) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_PATH(pathto, pathto_len) Z_PARAM_OPTIONAL - Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(files_str, files_ht) + Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(files_ht, files_str) ZEND_PARSE_PARAMETERS_END(); ZIP_FROM_OBJECT(intern, self);