Commit 85913fc61b5 for php.net
commit 85913fc61b57b28b74a9803f3055bdced5c31656
Author: Yuya Hamada <youkidearitai@gmail.com>
Date: Wed Dec 10 21:16:44 2025 +0900
Fix GH-20674 mb_decode_mimeheader does not handle separator
`?= =?` is skipped if long term, so skip space character.
Add test case from RFC2047 and fix last pattern
See: https://www.ietf.org/rfc/rfc2047#section-8
diff --git a/NEWS b/NEWS
index 534daec19b3..181c00bd838 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,8 @@ PHP NEWS
. ini_set() with mbstring.detect_order changes the order of mb_detect_order
as intended, since mbstring.detect_order is an INI_ALL setting. (tobee94)
. Added GB18030-2022 to default encoding list for zh-CN. (HeRaNO)
+ . Fixed bug GH-20674 (Fix GH-20674 mb_decode_mimeheader does not handle
+ separator). (Yuya Hamada)
- Opcache:
. Fixed bug GH-20051 (apache2 shutdowns when restart is requested during
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index 7422c600284..118986411a8 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -6675,13 +6675,15 @@ static zend_string* mb_mime_header_decode(zend_string *input, const mbfl_encodin
p = temp;
/* Decoding of MIME encoded word was successful;
* Try to collapse a run of whitespace */
- if (p < e && (*p == '\n' || *p == '\r')) {
+ if (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')) {
do {
p++;
} while (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' '));
/* We will only actually output a space if this is not immediately followed
* by another valid encoded word */
space_pending = true;
+ } else {
+ space_pending = false;
}
continue;
}
diff --git a/ext/mbstring/tests/gh20674.phpt b/ext/mbstring/tests/gh20674.phpt
new file mode 100644
index 00000000000..2fb8206037d
--- /dev/null
+++ b/ext/mbstring/tests/gh20674.phpt
@@ -0,0 +1,40 @@
+--TEST--
+GH-20674 (mb_decode_mimeheader does not handle separator)
+--EXTENSIONS--
+mbstring
+--FILE--
+<?php
+
+$subject = '=?us-ascii?Q?The_PH?= =?us-ascii?Q?P_8.5?=';
+var_dump(mb_decode_mimeheader($subject));
+
+// mb_decode_mimeheader's backward compatible for TAB(\t)
+$subject = "=?us-ascii?Q?The_PH?=\t=?us-ascii?Q?P_8.5?=";
+var_dump(mb_decode_mimeheader($subject));
+
+$subject = "=?us-ascii?Q?The_PH?=\t =?us-ascii?Q?P_8.5?=";
+var_dump(mb_decode_mimeheader($subject));
+
+$subject = "=?us-ascii?Q?The_PH?= \t =?us-ascii?Q?P_8.5?=";
+var_dump(mb_decode_mimeheader($subject));
+
+// from RFC 2047 https://www.ietf.org/rfc/rfc2047#section-8
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a?=)"));
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a?= b)"));
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a_b?=)"));
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)"));
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)"));
+var_dump(mb_decode_mimeheader("(=?ISO-8859-1?Q?a?=
+ =?ISO-8859-1?Q?b?=)"));
+?>
+--EXPECTF--
+string(11) "The PHP 8.5"
+string(11) "The PHP 8.5"
+string(11) "The PHP 8.5"
+string(11) "The PHP 8.5"
+string(3) "(a)"
+string(5) "(a b)"
+string(5) "(a b)"
+string(4) "(ab)"
+string(4) "(ab)"
+string(4) "(ab)"