[php-src] PHP-8.5: Merge branch 'PHP-8.4' into PHP-8.5

David Carlier <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: David Carlier (devnexen)
Date: 2026-08-08T21:27:19+01:00

Commit: https://github.com/php/php-src/commit/d5f57318613e2d51155d4e6b5ba76fc2ac2914ec
Raw diff: https://github.com/php/php-src/commit/d5f57318613e2d51155d4e6b5ba76fc2ac2914ec.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  ext/zip: addGlob() and addPattern() ignore their default options.

Changed paths:
  A  ext/zip/tests/addGlob_default_options.phpt
  A  ext/zip/tests/addPattern_default_options.phpt
  M  ext/zip/php_zip.c


Diff:

diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index fbb8594013a4..d2f1f0326eee 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -58,6 +58,12 @@ static int le_zip_entry;
 	}
 /* }}} */
 
+#ifdef HAVE_ENCRYPTION
+#define PHP_ZIP_DEFAULT_OPTIONS { .enc_method = -1, .comp_method = -1, .flags = ZIP_FL_OVERWRITE }
+#else
+#define PHP_ZIP_DEFAULT_OPTIONS { .comp_method = -1, .flags = ZIP_FL_OVERWRITE }
+#endif
+
 /* {{{ php_zip_set_file_comment */
 static bool php_zip_set_file_comment(struct zip *za, zip_uint64_t index, const char *comment, size_t comment_len)
 {
@@ -367,13 +373,6 @@ 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",
@@ -1709,7 +1708,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
 	size_t  path_len = 1;
 	zend_long glob_flags = 0;
 	HashTable *options = NULL;
-	zip_options opts = {0};
+	zip_options opts = PHP_ZIP_DEFAULT_OPTIONS;
 	int found;
 	zend_string *pattern;
 
diff --git a/ext/zip/tests/addGlob_default_options.phpt b/ext/zip/tests/addGlob_default_options.phpt
new file mode 100644
index 000000000000..f1951e849e07
--- /dev/null
+++ b/ext/zip/tests/addGlob_default_options.phpt
@@ -0,0 +1,79 @@
+--TEST--
+ZipArchive::addGlob() uses the default options when none are supplied
+--EXTENSIONS--
+zip
+--FILE--
+<?php
+$dir = __DIR__ . '/addglob_default_options_dir';
+@mkdir($dir);
+$src = $dir . '/data.txt';
+file_put_contents($src, str_repeat('The quick brown fox. ', 3000));
+$archive = $dir . '/test.zip';
+
+function stat_first(string $archive): array
+{
+    $zip = new ZipArchive();
+    $zip->open($archive);
+    $sb = $zip->statIndex(0);
+    $zip->close();
+
+    return $sb;
+}
+
+function add_glob(string $archive, string $pattern, ?array $options): bool
+{
+    $zip = new ZipArchive();
+    $zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+    $added = $options === null
+        ? $zip->addGlob($pattern)
+        : $zip->addGlob($pattern, 0, $options);
+    $zip->close();
+
+    return is_array($added);
+}
+
+/* comp_method defaults to "leave it to libzip", i.e. deflate, not CM_STORE. */
+foreach (['no options' => null, 'empty options' => []] as $label => $options) {
+    echo "-- $label --", PHP_EOL;
+    @unlink($archive);
+    var_dump(add_glob($archive, $dir . '/*.txt', $options));
+    $sb = stat_first($archive);
+    var_dump($sb['comp_method'] === ZipArchive::CM_DEFLATE);
+    var_dump($sb['comp_size'] < $sb['size']);
+}
+
+/* flags defaults to FL_OVERWRITE, so an existing entry is replaced. */
+echo '-- overwrites an existing entry --', PHP_EOL;
+@unlink($archive);
+$zip = new ZipArchive();
+$zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+$zip->addFromString($src, 'placeholder');
+var_dump(is_array($zip->addGlob($dir . '/*.txt')));
+$zip->close();
+
+$zip = new ZipArchive();
+$zip->open($archive);
+var_dump($zip->numFiles);
+var_dump($zip->getFromName($src) === file_get_contents($src));
+$zip->close();
+?>
+--CLEAN--
+<?php
+$dir = __DIR__ . '/addglob_default_options_dir';
+@unlink($dir . '/test.zip');
+@unlink($dir . '/data.txt');
+@rmdir($dir);
+?>
+--EXPECT--
+-- no options --
+bool(true)
+bool(true)
+bool(true)
+-- empty options --
+bool(true)
+bool(true)
+bool(true)
+-- overwrites an existing entry --
+bool(true)
+int(1)
+bool(true)
diff --git a/ext/zip/tests/addPattern_default_options.phpt b/ext/zip/tests/addPattern_default_options.phpt
new file mode 100644
index 000000000000..404e47e5291c
--- /dev/null
+++ b/ext/zip/tests/addPattern_default_options.phpt
@@ -0,0 +1,79 @@
+--TEST--
+ZipArchive::addPattern() uses the default options when none are supplied
+--EXTENSIONS--
+zip
+--FILE--
+<?php
+$dir = __DIR__ . DIRECTORY_SEPARATOR . 'addpattern_default_options_dir';
+@mkdir($dir);
+$src = $dir . DIRECTORY_SEPARATOR . 'data.txt';
+file_put_contents($src, str_repeat('The quick brown fox. ', 3000));
+$archive = $dir . DIRECTORY_SEPARATOR . 'test.zip';
+
+function stat_first(string $archive): array
+{
+    $zip = new ZipArchive();
+    $zip->open($archive);
+    $sb = $zip->statIndex(0);
+    $zip->close();
+
+    return $sb;
+}
+
+function add_pattern(string $archive, string $pattern, string $path, ?array $options): bool
+{
+    $zip = new ZipArchive();
+    $zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+    $added = $options === null
+        ? $zip->addPattern($pattern, $path)
+        : $zip->addPattern($pattern, $path, $options);
+    $zip->close();
+
+    return is_array($added);
+}
+
+/* comp_method defaults to "leave it to libzip", i.e. deflate, not CM_STORE. */
+foreach (['no options' => null, 'empty options' => []] as $label => $options) {
+    echo "-- $label --", PHP_EOL;
+    @unlink($archive);
+    var_dump(add_pattern($archive, '/^data\.txt$/', $dir, $options));
+    $sb = stat_first($archive);
+    var_dump($sb['comp_method'] === ZipArchive::CM_DEFLATE);
+    var_dump($sb['comp_size'] < $sb['size']);
+}
+
+/* flags defaults to FL_OVERWRITE, so an existing entry is replaced. */
+echo '-- overwrites an existing entry --', PHP_EOL;
+@unlink($archive);
+$zip = new ZipArchive();
+$zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+$zip->addFromString($src, 'placeholder');
+var_dump(is_array($zip->addPattern('/^data\.txt$/', $dir)));
+$zip->close();
+
+$zip = new ZipArchive();
+$zip->open($archive);
+var_dump($zip->numFiles);
+var_dump($zip->getFromIndex(0) === file_get_contents($src));
+$zip->close();
+?>
+--CLEAN--
+<?php
+$dir = __DIR__ . DIRECTORY_SEPARATOR . 'addpattern_default_options_dir';
+@unlink($dir . DIRECTORY_SEPARATOR . 'test.zip');
+@unlink($dir . DIRECTORY_SEPARATOR . 'data.txt');
+@rmdir($dir);
+?>
+--EXPECT--
+-- no options --
+bool(true)
+bool(true)
+bool(true)
+-- empty options --
+bool(true)
+bool(true)
+bool(true)
+-- overwrites an existing entry --
+bool(true)
+int(1)
+bool(true)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.