Commit 5838b68a14c for php

commit 5838b68a14ce2d9692a71cb5ed7f9ece69ab1886
Author: Kamil Tekiela <tekiela246@gmail.com>
Date:   Mon Oct 12 14:26:46 2026 +0100

    ext/mbstring: Fix truncated encoding names resolving to full names (#23974)

    Closes GH-23958

diff --git a/NEWS b/NEWS
index aaed43baa2c..ee0c8117693 100644
--- a/NEWS
+++ b/NEWS
@@ -168,6 +168,7 @@ PHP                                                                        NEWS
     a truncated UTF-8 sequence). (Lazizbek Ergashev)
   . Fixed mbstring functions emitting surrogates in UTF-8 output and flagging
     it as valid UTF-8. (Nicolas Grekas)
+  . Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela)

 - MySQLi:
   . Fix GH-22854: Fixed failed assertion when accessing mysqli property after
diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
index f1e25dc7537..adbedc3f0c1 100644
--- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
+++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
@@ -339,7 +339,7 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len)
 			int8_t offset = mbfl_encoding_ptr_list_after_hashing[key];
 			if (offset >= 0) {
 				encoding = mbfl_encoding_ptr_list + offset;
-				if (strncasecmp((*encoding)->name, name, name_len) == 0) {
+				if (strlen((*encoding)->name) == name_len && strncasecmp((*encoding)->name, name, name_len) == 0) {
 					return *encoding;
 				}
 			}
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index 6fbeb43fc1b..7e0b47deae9 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -275,7 +275,7 @@ static const mbfl_encoding *php_mb_get_encoding(zend_string *encoding_name, uint
 }

 static const mbfl_encoding *php_mb_get_encoding_or_pass(const char *encoding_name, size_t encoding_name_len) {
-	if (strncmp(encoding_name, "pass", encoding_name_len) == 0) {
+	if (encoding_name_len == strlen("pass") && strncmp(encoding_name, "pass", encoding_name_len) == 0) {
 		return &mbfl_encoding_pass;
 	}

@@ -335,7 +335,7 @@ static zend_result php_mb_parse_encoding_list(const char *value, size_t value_le
 			}
 			size_t p1_length = p - p1 + 1;
 			/* convert to the encoding number and check encoding */
-			if (strncasecmp(p1, "auto", p1_length) == 0) {
+			if (p1_length == strlen("auto") && strncasecmp(p1, "auto", p1_length) == 0) {
 				if (!included_auto) {
 					const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list);
 					const size_t identify_list_size = MBSTRG(default_detect_order_list_size);
diff --git a/ext/mbstring/tests/gh15824.phpt b/ext/mbstring/tests/gh15824.phpt
index 570bb2b9d03..553eb2b58e3 100644
--- a/ext/mbstring/tests/gh15824.phpt
+++ b/ext/mbstring/tests/gh15824.phpt
@@ -17,8 +17,8 @@
 echo "== mime name ==\n";
 var_dump(mb_detect_encoding('abc', 'ANSI_X3.4-1968, ISO-8859-1'));
 var_dump(mb_detect_encoding('abc', 'CP50220, ANSI_X3.4-1968'));
-/* last comma is not mistake, intentionally */
-var_dump(mb_detect_encoding(bin2hex('1b24422422242424262428242a1b2842'), 'CP50220, ANSI_X3.4-1968,', false));
+
+var_dump(mb_detect_encoding(bin2hex('1b24422422242424262428242a1b2842'), 'CP50220, ANSI_X3.4-1968', false));
 var_dump(mb_detect_encoding('😄', 'US-ASCII, UTF-8-Mobile#KDDI-B, UTF-8'));
 ?>
 --EXPECT--
diff --git a/ext/mbstring/tests/gh23958.phpt b/ext/mbstring/tests/gh23958.phpt
new file mode 100644
index 00000000000..6d5a586e159
--- /dev/null
+++ b/ext/mbstring/tests/gh23958.phpt
@@ -0,0 +1,35 @@
+--TEST--
+GH-23958: Truncated encoding names must not be accepted
+--EXTENSIONS--
+mbstring
+--FILE--
+<?php
+foreach (['pa', 'UCS-', '',] as $name) {
+    try {
+        mb_http_output($name);
+    } catch (ValueError $e) {
+        echo $e->getMessage(), "\n";
+    }
+}
+try {
+    mb_detect_order('aut');
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump(ini_set('mbstring.detect_order', ','));
+
+try {
+    mb_detect_encoding(bin2hex('1b24422422242424262428242a1b2842'), 'CP50220, ANSI_X3.4-1968,', false);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+?>
+--EXPECTF--
+mb_http_output(): Argument #1 ($encoding) must be a valid encoding, "pa" given
+mb_http_output(): Argument #1 ($encoding) must be a valid encoding, "UCS-" given
+mb_http_output(): Argument #1 ($encoding) must be a valid encoding, "" given
+mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "aut"
+
+Warning: ini_set(): INI setting contains invalid encoding "" in %s on line %d
+bool(false)
+mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding ""