Commit 7801023fbaa for php.net
commit 7801023fbaa81ceca75746d3c4c2acb226f06710
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Mon Aug 3 08:27:52 2026 -0400
zip: skip the entry name allocation when there is no add_path (#22975)
php_zip_add_file() takes a char*/size_t pair, so without a prefix to
concatenate the zend_string was allocated and released once per entry only
to pass one through. Pass file_stripped directly, and hold basename until
after the call because file_stripped can point into it.
Closes GH-22975
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index 1b5749c53a5..4bc74796889 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -289,7 +289,7 @@ static bool php_zip_extract_file(struct zip * za, char *dest, const char *file,
/* }}} */
static zend_result 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 */
+ const 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
@@ -1846,7 +1846,9 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
file_stripped_len = Z_STRLEN_P(zval_file);
}
- zend_string *entry_name;
+ zend_string *entry_name = NULL;
+ const char *entry_name_str = file_stripped;
+ size_t entry_name_len = file_stripped_len;
if (opts.add_path) {
if ((ZSTR_LEN(opts.add_path) + file_stripped_len) > MAXPATHLEN) {
if (basename) {
@@ -1861,20 +1863,21 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
ZSTR_VAL(opts.add_path), ZSTR_LEN(opts.add_path),
file_stripped, file_stripped_len
);
- } else {
- entry_name = zend_string_init(file_stripped, file_stripped_len, false);
+ entry_name_str = ZSTR_VAL(entry_name);
+ entry_name_len = ZSTR_LEN(entry_name);
}
- ZEND_ASSERT(ZSTR_LEN(entry_name) <= MAXPATHLEN);
+ ZEND_ASSERT(entry_name_len <= MAXPATHLEN);
+
+ const zend_result status = php_zip_add_file(ze_obj, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
+ entry_name_str, entry_name_len, 0, 0, -1, opts.flags);
if (basename) {
zend_string_release_ex(basename, false);
basename = NULL;
}
-
- const zend_result status = php_zip_add_file(ze_obj, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
- ZSTR_VAL(entry_name), ZSTR_LEN(entry_name), 0, 0, -1, opts.flags);
-
- zend_string_release_ex(entry_name, false);
+ if (entry_name) {
+ zend_string_release_ex(entry_name, false);
+ }
if (status == FAILURE) {
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;