diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/HeaderCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/HeaderCollection.php index 5b3674dbe..2704909c9 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/HeaderCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/HeaderCollection.php @@ -136,14 +136,12 @@ class HeaderCollection extends \MailSo\Base\Collection $sHeadersValue = \rtrim($sHeadersValue); } - if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2)) { - $sHeadersValue = \ltrim($sHeadersValue); - } - - if ('=?' === \substr($sHeadersValue, 0, 2)) { - $sValue .= $sHeadersValue; + // RFC 5322 unfolding removes the line break and keeps the folding + // whitespace; RFC 2047 6.2 drops it only between two encoded words. + if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2) && '?=' === \substr($sValue, -2)) { + $sValue .= \ltrim($sHeadersValue); } else { - $sValue .= "\n".$sHeadersValue; + $sValue .= ' '.\ltrim($sHeadersValue); } } else { if (null !== $sName) { diff --git a/test/header-unfold.php b/test/header-unfold.php new file mode 100644 index 000000000..4b33c8d2f --- /dev/null +++ b/test/header-unfold.php @@ -0,0 +1,51 @@ +ValueByName('Subject'); +} + +$cases = [ + // plain word, then a folded encoded word: the space stays + "Traiter les =?utf-8?Q?vuln=C3=A9rabilit=C3=A9s?= de vos\r\n =?utf-8?Q?=C3=A9quipements?= : plan de =?utf-8?Q?rem=C3=A9diation?= et\r\n checklist =?utf-8?Q?sign=C3=A9e?=" + => 'Traiter les vulnérabilités de vos équipements : plan de remédiation et checklist signée', + // two encoded words split across lines: no space between them (RFC 2047 §6.2) + "=?utf-8?Q?r=C3=A9pon?=\r\n =?utf-8?Q?se?=" => 'réponse', + "=?utf-8?B?w6l0w6k=?=\r\n\t=?utf-8?B?IGZpbg==?=" => 'été fin', + // encoded word, then a folded plain word: the space stays + "=?utf-8?Q?r=C3=A9union?=\r\n demain" => 'réunion demain', + // no encoding at all + "Hello\r\n world" => 'Hello world', +]; +foreach ($cases as $raw => $want) { + // exact: a fold is one space, never two ("et checklist" ended up in replies) + $got = subject($raw); + check($got === $want, "got [{$got}], want [{$want}]"); +} + +echo "header-unfold: ".count($cases)." checks OK\n";