Skip to content

Commit ae7dbd8

Browse files
committed
GHSA-74r9-qxhc-fx53: [mbstring] Fix out-of-bounds access in mbfl_name2encoding_ex()
Fixes GHSA-74r9-qxhc-fx53 Fixes CVE-2026-6104
1 parent 19cc220 commit ae7dbd8

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

ext/mbstring/libmbfl/mbfl/mbfl_encoding.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len)
349349
/* search MIME charset name */
350350
for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) {
351351
if ((*encoding)->mime_name) {
352-
if (strncasecmp((*encoding)->mime_name, name, name_len) == 0 && (*encoding)->mime_name[name_len] == '\0') {
352+
size_t mime_len = strlen((*encoding)->mime_name);
353+
if (mime_len == name_len && strncasecmp((*encoding)->mime_name, name, name_len) == 0) {
353354
return *encoding;
354355
}
355356
}
@@ -359,7 +360,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len)
359360
for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) {
360361
if ((*encoding)->aliases) {
361362
for (const char **alias = (*encoding)->aliases; *alias; alias++) {
362-
if (strncasecmp(name, *alias, name_len) == 0 && (*alias)[name_len] == '\0') {
363+
size_t alias_len = strlen(*alias);
364+
if (alias_len == name_len && strncasecmp(name, *alias, name_len) == 0) {
363365
return *encoding;
364366
}
365367
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
GHSA-74r9-qxhc-fx53: Out-of-bounds access in mbfl_name2encoding_ex()
3+
--CREDITS--
4+
Akshay Jain (AkshayJainG)
5+
--EXTENSIONS--
6+
mbstring
7+
--FILE--
8+
<?php
9+
10+
$encoding = "UTF-8\x00AAAAAAAAAAAAAAAA";
11+
$alias = "binary\x00AAAAAAAAAAAAAAAA";
12+
$var = 'foo';
13+
14+
function test($c) {
15+
try {
16+
$c();
17+
} catch (Throwable $e) {
18+
echo $e::class, ': ', $e->getMessage(), "\n";
19+
}
20+
}
21+
22+
ini_set('mbstring.detect_order', $encoding);
23+
ini_set('mbstring.detect_order', $alias);
24+
ini_set('mbstring.http_output', $encoding);
25+
ini_set('mbstring.http_output', $alias);
26+
27+
test(fn () => mb_convert_encoding('foo', $encoding, $encoding));
28+
test(fn () => mb_convert_encoding('foo', $alias, $alias));
29+
test(fn () => mb_detect_encoding('foo', $encoding));
30+
test(fn () => mb_detect_encoding('foo', $alias));
31+
test(fn () => mb_convert_variables($encoding, $alias, $var));
32+
test(fn () => mb_detect_order($encoding));
33+
test(fn () => mb_detect_order($alias));
34+
35+
?>
36+
--EXPECTF--
37+
Warning: ini_set(): INI setting contains invalid encoding "UTF-8" in %s on line %d
38+
39+
Warning: ini_set(): INI setting contains invalid encoding "binary" in %s on line %d
40+
41+
Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d
42+
43+
Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d
44+
ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "UTF-8"
45+
ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "binary"
46+
ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "UTF-8"
47+
ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "binary"
48+
ValueError: mb_convert_variables(): Argument #2 ($from_encoding) contains invalid encoding "binary"
49+
ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "UTF-8"
50+
ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "binary"

0 commit comments

Comments
 (0)