Commit b2956e0bb32 for php.net

commit b2956e0bb326913d91bfa22e1059896c6bd7c6b9
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Mon Aug 17 20:40:15 2026 -0400

    Close the keyword UEnumeration on Locale::getKeywords failure

    uloc_getKeywordValue failure destroyed the result array and returned
    without uenum_close(). Close the enumeration on that path. The success
    path already closes it.

    Audited the other uenum_close site in this file (acceptLanguage).

    Closes GH-23351

diff --git a/NEWS b/NEWS
index 5607f31081b..e56e562a4c9 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,8 @@ PHP                                                                        NEWS
   . Fixed Locale::parseLocale() reading past a trailing '-' or '_'.
     (iliaal, Xuyang Zhang)
   . Fixed grapheme_str_split() treating UBRK_DONE as a byte index. (iliaal)
+  . Fixed a leak in Locale::getKeywords() when a keyword value cannot be
+    read. (iliaal)

 - Opcache:
   . Fixed opcache.protect_memory race under ZTS. (realFlowControl)
diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c
index e3894b6f28f..2643f492087 100644
--- a/ext/intl/locale/locale_methods.c
+++ b/ext/intl/locale/locale_methods.c
@@ -776,6 +776,7 @@ PHP_FUNCTION( locale_get_keywords )
 					zend_string_efree( kw_value_str );
 				}
 				zend_array_destroy(Z_ARR_P(return_value));
+				uenum_close( e );
 				RETURN_FALSE;
 			}

diff --git a/ext/intl/tests/locale_get_keywords_failure.phpt b/ext/intl/tests/locale_get_keywords_failure.phpt
new file mode 100644
index 00000000000..823da63ca54
--- /dev/null
+++ b/ext/intl/tests/locale_get_keywords_failure.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Locale::getKeywords() closes the keyword enumeration on failure
+--EXTENSIONS--
+intl
+--SKIPIF--
+<?php
+if (version_compare(INTL_ICU_VERSION, '59.1', '<')) {
+    die('skip for ICU >= 59.1');
+}
+?>
+--FILE--
+<?php
+var_dump(Locale::getKeywords('en@foo=bar!'));
+var_dump(intl_get_error_code() === U_ILLEGAL_ARGUMENT_ERROR);
+?>
+--EXPECT--
+bool(false)
+bool(true)