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)"