Commit 0056d013bf5 for php.net
commit 0056d013bf505302e2477e02d795627709842327
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 4e301bdbc8b..5103b4a9679 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@ PHP NEWS
- LDAP:
. Fix memory leak in ldap_set_options(). (ndossche)
+- Mbstring
+ . Fixed bug GH-20674 (Fix GH-20674 mb_decode_mimeheader does not handle
+ separator). (Yuya Hamada)
+
- SPL:
. Fixed bug GH-20678 (resource created by GlobIterator crashes with fclose()).
(David Carlier)
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index 1d5c27a2a38..5839945d475 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -6395,13 +6395,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)"