Commit f6852befa34 for php
commit f6852befa34b1107da57d26ead79e575ccd73e2a
Author: Jorg Sowa <jorg.sowa@gmail.com>
Date: Wed Oct 21 20:05:59 2026 +0200
ext/mbstring: fix over-read in php_mb_rfc1867_getword()
A multibyte lead byte at the end of a multipart field name made the
scan advance by the full character width past the terminating NUL,
reading out of bounds. Advance byte by byte and stop at the
terminator in both advance sites, as php_mb_rfc1867_substring_conf()
already does.
Closes GH-24498
diff --git a/NEWS b/NEWS
index 22760f8d7d1..8bd02dc6d6a 100644
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,8 @@ PHP NEWS
- MBString:
. Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela)
+ . Fixed out-of-bounds read in php_mb_rfc1867_getword() on a multibyte lead
+ byte at the end of a multipart field name. (Jorg Sowa)
- MySQLnd:
. Fixed bug GH-24293 (Segfault on connect with an empty password to a
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index 98beb5f0d3f..fdcd2ef6199 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -607,8 +607,10 @@ static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line,
++pos;
}
} else {
- pos += php_mb_mbchar_bytes(pos, (const mbfl_encoding *)encoding);
-
+ size_t len = php_mb_mbchar_bytes(pos, (const mbfl_encoding *)encoding);
+ while (len-- > 0 && *pos) {
+ ++pos;
+ }
}
}
if (*pos == '\0') {
@@ -620,7 +622,10 @@ static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line,
res = estrndup(*line, pos - *line);
while (*pos == stop) {
- pos += php_mb_mbchar_bytes(pos, (const mbfl_encoding *)encoding);
+ size_t len = php_mb_mbchar_bytes(pos, (const mbfl_encoding *)encoding);
+ while (len-- > 0 && *pos) {
+ ++pos;
+ }
}
*line = pos;
diff --git a/ext/mbstring/tests/mb_rfc1867_getword_overread.phpt b/ext/mbstring/tests/mb_rfc1867_getword_overread.phpt
new file mode 100644
index 00000000000..94bde9d9ff9
--- /dev/null
+++ b/ext/mbstring/tests/mb_rfc1867_getword_overread.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Over-read in php_mb_rfc1867_getword() on a multibyte field name (mbstring.encoding_translation=On)
+--EXTENSIONS--
+mbstring
+--POST_RAW--
+Content-Type: multipart/form-data; boundary=blah
+
+--blah
+
+x
+--blah--
+--INI--
+mbstring.encoding_translation=On
+--FILE--
+<?php
+var_dump(count($_POST));
+echo "Done\n";
+?>
+--EXPECT--
+int(1)
+Done