Commit 391ec277d54 for php.net

commit 391ec277d5497dc0a801fd193905d021f1fb34a0
Author: David Carlier <devnexen@gmail.com>
Date:   Fri Apr 10 06:05:44 2026 +0100

    Fix GH-21698: memory leak in ZipArchive::addGlob on early returns.

    globfree was not called on the no-matches path and on the
    open_basedir reject path, leaking the glob_t contents populated by a
    successful glob() call.

    close GH-21702

diff --git a/NEWS b/NEWS
index 2071326cf6e..07653ef6a37 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,10 @@ PHP                                                                        NEWS
 - XSL:
   . Fixed bug GH-21600 (Segfault on module shutdown). (David Carlier)

+- Zip:
+  . Fixed bug GH-21698 (memory leak with ZipArchive::addGlob()
+    early return statements). (David Carlier)
+
 09 Apr 2026, PHP 8.4.20

 - Bz2:
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index 75ae4aa9191..d25cfe04326 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -675,12 +675,14 @@ int php_zip_glob(char *pattern, int pattern_len, zend_long flags, zval *return_v

 	/* now catch the FreeBSD style of "no matches" */
 	if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
+		globfree(&globbuf);
 		return 0;
 	}

 	/* we assume that any glob pattern will match files from one directory only
 	   so checking the dirname of the first match should be sufficient */
 	if (ZIP_OPENBASEDIR_CHECKPATH(globbuf.gl_pathv[0])) {
+		globfree(&globbuf);
 		return -1;
 	}

diff --git a/ext/zip/tests/gh21698.phpt b/ext/zip/tests/gh21698.phpt
new file mode 100644
index 00000000000..d77b2152e72
--- /dev/null
+++ b/ext/zip/tests/gh21698.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-21698 (ZipArchive::addGlob memory leak when open_basedir rejects the match)
+--EXTENSIONS--
+zip
+--FILE--
+<?php
+$zipfile = __DIR__ . '/gh21698.zip';
+$zip = new ZipArchive();
+$zip->open($zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+
+ini_set('open_basedir', '/nonexistent_dir_for_gh21698');
+var_dump($zip->addGlob(__FILE__, 0, []));
+$zip->close();
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/gh21698.zip');
+?>
+--EXPECTF--
+Warning: ZipArchive::addGlob(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d
+bool(false)