diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php index 46e118c27..f47d042ee 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php @@ -601,6 +601,16 @@ END; return $sResult; } + /** + * @param string $sInputValue + * + * @return string + */ + public static function DecodeFlowedFormat($sInputValue) + { + return \preg_replace('/ ([\r]?[\n])/m', ' ', $sInputValue); + } + /** * @param string $sEncodedValue * @param string $sIncomingCharset = '' diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php index eaf460485..624f2beb8 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php @@ -285,6 +285,22 @@ class BodyStructure return $bResult; } + /** + * @return bool + */ + public function IsFlowedFormat() + { + $bResult = !empty($this->aBodyParams['format']) && + 'flowed' === \strtolower(\trim($this->aBodyParams['format'])); + + if ($bResult && \in_array(\strtolower($this->MailEncodingName()), array('base64', 'quoted-printable'))) + { + $bResult = false; + } + + return $bResult; + } + /** * @return array|null */ diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/Message.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/Message.php index 7424f1bbf..dd8c2cf93 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/Message.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/Message.php @@ -751,8 +751,8 @@ class Message $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8; } - $sHtmlParts = array(); - $sPlainParts = array(); + $aHtmlParts = array(); + $aPlainParts = array(); foreach ($aTextParts as $oPart) { @@ -782,22 +782,27 @@ class Message if ('text/html' === $oPart->ContentType()) { - $sHtmlParts[] = $sText; + $aHtmlParts[] = $sText; } else { - $sPlainParts[] = $sText; + if ($oPart->IsFlowedFormat()) + { + $sText = \MailSo\Base\Utils::DecodeFlowedFormat($sText); + } + + $aPlainParts[] = $sText; } } } - if (0 < \count($sHtmlParts)) + if (0 < \count($aHtmlParts)) { - $this->sHtml = \implode('
', $sHtmlParts); + $this->sHtml = \implode('
', $aHtmlParts); } else { - $this->sPlain = \trim(\implode("\n", $sPlainParts)); + $this->sPlain = \trim(\implode("\n", $aPlainParts)); } $aMatch = array(); @@ -813,7 +818,7 @@ class Message $this->bPgpEncrypted = true; } - unset($sHtmlParts, $sPlainParts, $aMatch); + unset($aHtmlParts, $aPlainParts, $aMatch); } // if (empty($this->sPgpSignature) && 'multipart/signed' === \strtolower($this->sContentType) && diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Enumerations/Parameter.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Enumerations/Parameter.php index 8facb3ecd..c175df43d 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Enumerations/Parameter.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Enumerations/Parameter.php @@ -21,6 +21,7 @@ class Parameter const CHARSET = 'charset'; const NAME = 'name'; const FILENAME = 'filename'; + const FORMAT = 'format'; const BOUNDARY = 'boundary'; const PROTOCOL = 'protocol'; } diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Part.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Part.php index 9ae9c3aa5..2e19af03f 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Part.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Part.php @@ -210,6 +210,27 @@ class Part \MailSo\Mime\Enumerations\Header::CONTENT_LOCATION)) : ''; } + /** + * @return bool + */ + public function IsFlowedFormat() + { + $bResult = false; + if ($this->Headers) + { + $bResult = 'flowed' === \trim(\strtolower($this->Headers->ParameterValue( + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, + \MailSo\Mime\Enumerations\Parameter::FORMAT))); + + if ($bResult && \in_array(\strtolower($this->MailEncodingName()), array('base64', 'quoted-printable'))) + { + $bResult = false; + } + } + + return $bResult; + } + /** * @return string */