Commit 56ee76f8204 for php.net
commit 56ee76f82045ab728f3e63e20bf9530621e829cb
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date: Sun May 3 20:11:17 2026 +0200
GHSA-74r9-qxhc-fx53: [mbstring] Fix out-of-bounds access in mbfl_name2encoding_ex()
Fixes GHSA-74r9-qxhc-fx53
Fixes CVE-2026-6104
diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
index 6e44f68b857..f1e25dc7537 100644
--- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
+++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c
@@ -349,7 +349,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len)
/* search MIME charset name */
for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) {
if ((*encoding)->mime_name) {
- if (strncasecmp((*encoding)->mime_name, name, name_len) == 0 && (*encoding)->mime_name[name_len] == '\0') {
+ size_t mime_len = strlen((*encoding)->mime_name);
+ if (mime_len == name_len && strncasecmp((*encoding)->mime_name, name, name_len) == 0) {
return *encoding;
}
}
@@ -359,7 +360,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len)
for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) {
if ((*encoding)->aliases) {
for (const char **alias = (*encoding)->aliases; *alias; alias++) {
- if (strncasecmp(name, *alias, name_len) == 0 && (*alias)[name_len] == '\0') {
+ size_t alias_len = strlen(*alias);
+ if (alias_len == name_len && strncasecmp(name, *alias, name_len) == 0) {
return *encoding;
}
}
diff --git a/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt
new file mode 100644
index 00000000000..e58be7e50d8
--- /dev/null
+++ b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt
@@ -0,0 +1,50 @@
+--TEST--
+GHSA-74r9-qxhc-fx53: Out-of-bounds access in mbfl_name2encoding_ex()
+--CREDITS--
+Akshay Jain (AkshayJainG)
+--EXTENSIONS--
+mbstring
+--FILE--
+<?php
+
+$encoding = "UTF-8\x00AAAAAAAAAAAAAAAA";
+$alias = "binary\x00AAAAAAAAAAAAAAAA";
+$var = 'foo';
+
+function test($c) {
+ try {
+ $c();
+ } catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+ }
+}
+
+ini_set('mbstring.detect_order', $encoding);
+ini_set('mbstring.detect_order', $alias);
+ini_set('mbstring.http_output', $encoding);
+ini_set('mbstring.http_output', $alias);
+
+test(fn () => mb_convert_encoding('foo', $encoding, $encoding));
+test(fn () => mb_convert_encoding('foo', $alias, $alias));
+test(fn () => mb_detect_encoding('foo', $encoding));
+test(fn () => mb_detect_encoding('foo', $alias));
+test(fn () => mb_convert_variables($encoding, $alias, $var));
+test(fn () => mb_detect_order($encoding));
+test(fn () => mb_detect_order($alias));
+
+?>
+--EXPECTF--
+Warning: ini_set(): INI setting contains invalid encoding "UTF-8" in %s on line %d
+
+Warning: ini_set(): INI setting contains invalid encoding "binary" in %s on line %d
+
+Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d
+
+Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d
+ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "UTF-8"
+ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "binary"
+ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "UTF-8"
+ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "binary"
+ValueError: mb_convert_variables(): Argument #2 ($from_encoding) contains invalid encoding "binary"
+ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "UTF-8"
+ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "binary"