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

Weilin Du <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Date: 2026-08-18T22:38:49+08:00

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

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  Bound getSingletonPos before reading the next separator (#23350)

Changed paths:
  A  ext/intl/tests/locale_parse_trailing_separator.phpt
  M  NEWS
  M  ext/intl/locale/locale_methods.cpp


Diff:

diff --git a/NEWS b/NEWS
index 79171a05fe1b..63ec75891ce0 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ PHP                                                                        NEWS
     the ICU constructor adopts the TimeZone. (iliaal)
   . Fixed bug GH-23094 (NumberFormatter parsing offsets use UTF-16 positions
     for UTF-8 strings). (ColumbusLabs)
+  . Fixed Locale::parseLocale() reading past a trailing '-' or '_'.
+    (iliaal, Xuyang Zhang)
 
 - Opcache:
   . Fixed opcache.protect_memory race under ZTS. (realFlowControl)
diff --git a/ext/intl/locale/locale_methods.cpp b/ext/intl/locale/locale_methods.cpp
index f98ea55a1858..1bcdf9ded6b3 100644
--- a/ext/intl/locale/locale_methods.cpp
+++ b/ext/intl/locale/locale_methods.cpp
@@ -281,7 +281,7 @@ static zend_off_t getSingletonPos(const char* str)
 					break;
 				} else {
 					/* delimiter found; check for singleton */
-					if( isIDSeparator(*(str+i+2)) ){
+					if( (size_t)i + 2 < len && isIDSeparator(*(str+i+2)) ){
 						/* a singleton; so send the position of separator before singleton */
 						result = i+1;
 						break;
diff --git a/ext/intl/tests/locale_parse_trailing_separator.phpt b/ext/intl/tests/locale_parse_trailing_separator.phpt
new file mode 100644
index 000000000000..96b2139b72c3
--- /dev/null
+++ b/ext/intl/tests/locale_parse_trailing_separator.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Locale::parseLocale() does not read past a trailing '-' or '_'
+--EXTENSIONS--
+intl
+--FILE--
+<?php
+/* Enough lengths that the byte past the end clears the allocation. */
+foreach (['-', '_'] as $sep) {
+    for ($len = 1; $len <= 64; $len++) {
+        Locale::parseLocale(str_repeat('a', $len) . $sep);
+    }
+}
+
+$locales = [
+    'en-',
+    'foo-',
+    'en_US-',
+    'en_',
+    'de-CH-x-',
+];
+
+foreach ($locales as $locale) {
+    echo $locale, ': ';
+    var_export(Locale::parseLocale($locale));
+    echo "\n";
+}
+?>
+--EXPECT--
+en-: array (
+  'language' => 'en',
+)
+foo-: array (
+  'language' => 'foo',
+)
+en_US-: array (
+  'language' => 'en',
+  'region' => 'US',
+)
+en_: array (
+  'language' => 'en',
+)
+de-CH-x-: array (
+  'language' => 'de',
+  'region' => 'CH',
+)
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.