From 2fc9d5cff091e39f2b75b1d1a3e0034a2a499c3d Mon Sep 17 00:00:00 2001 From: djmaze Date: Tue, 31 Aug 2021 08:12:00 +0200 Subject: [PATCH] Try to resolve issue #137 --- .../0.0.0/app/libraries/MailSo/Base/Utils.php | 224 ++++++++---------- 1 file changed, 98 insertions(+), 126 deletions(-) diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php b/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php index 5164b9306..c308d1469 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php @@ -33,31 +33,6 @@ abstract class Utils /x END; - /** - * @var array - */ - public static $SuppostedCharsets = array( - 'iso-8859-1', 'iso-8859-2', 'iso-8859-3', 'iso-8859-4', 'iso-8859-5', 'iso-8859-6', - 'iso-8859-7', 'iso-8859-8', 'iso-8859-9', 'iso-8859-10', 'iso-8859-11', 'iso-8859-12', - 'iso-8859-13', 'iso-8859-14', 'iso-8859-15', 'iso-8859-16', - 'koi8-r', 'koi8-u', 'koi8-ru', - 'cp1125', 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1257', 'cp949', 'cp1133', - 'cp850', 'cp866', 'cp1255', 'cp1256', 'cp862', 'cp874', 'cp932', 'cp950', 'cp1258', - 'windows-1250', 'windows-1251', 'windows-1252', 'windows-1253', 'windows-1254', 'windows-1255', - 'windows-1256', 'windows-1257', 'windows-1258', 'windows-874', - 'macroman', 'maccentraleurope', 'maciceland', 'maccroatian', 'macromania', 'maccyrillic', - 'macukraine', 'macgreek', 'macturkish', 'macintosh', 'machebrew', 'macarabic', - 'euc-jp', 'shift_jis', 'iso-2022-jp', 'iso-2022-jp-2', 'iso-2022-jp-1', - 'euc-cn', 'gb2312', 'hz', 'gbk', 'gb18030', 'euc-tw', 'big5', 'big5-hkscs', - 'iso-2022-cn', 'iso-2022-cn-ext', 'euc-kr', 'iso-2022-kr', 'johab', - 'armscii-8', 'georgian-academy', 'georgian-ps', 'koi8-t', - 'tis-620', 'macthai', 'mulelao-1', - 'viscii', 'tcvn', 'hp-roman8', 'nextstep', - 'utf-8', 'ucs-2', 'ucs-2be', 'ucs-2le', 'ucs-4', 'ucs-4be', 'ucs-4le', - 'utf-16', 'utf-16be', 'utf-16le', 'utf-32', 'utf-32be', 'utf-32le', 'utf-7', - 'c99', 'java', 'ucs-2-internal', 'ucs-4-internal' - ); - /** * @var array */ @@ -167,23 +142,23 @@ END; case 'ascii': case 'us-asci': case 'us-ascii': - $sEncoding = $bAsciAsUtf8 ? \MailSo\Base\Enumerations\Charset::UTF_8 : - \MailSo\Base\Enumerations\Charset::ISO_8859_1; + $sEncoding = $bAsciAsUtf8 ? Enumerations\Charset::UTF_8 : + Enumerations\Charset::ISO_8859_1; break; case 'unicode-1-1-utf-7': case 'unicode-1-utf-7': case 'unicode-utf-7': - $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_7; + $sEncoding = Enumerations\Charset::UTF_7; break; case 'utf8': case 'utf-8': - $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_8; + $sEncoding = Enumerations\Charset::UTF_8; break; case 'utf7imap': case 'utf-7imap': case 'utf7-imap': case 'utf-7-imap': - $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_7_IMAP; + $sEncoding = Enumerations\Charset::UTF_7_IMAP; break; case 'ks-c-5601-1987': case 'ks_c_5601-1987': @@ -195,7 +170,7 @@ END; break; case 'iso-8859-i': case 'iso-8859-8-i': - $sEncoding = \MailSo\Base\Enumerations\Charset::ISO_8859_8; + $sEncoding = Enumerations\Charset::ISO_8859_8; break; } @@ -206,12 +181,12 @@ END; { $sCharset = static::NormalizeCharset($sCharset); - if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $sCharset && + if (Enumerations\Charset::UTF_8 !== $sCharset && static::IsUtf8($sValue) && - false === \strpos($sCharset, \MailSo\Base\Enumerations\Charset::ISO_2022_JP) + false === \strpos($sCharset, Enumerations\Charset::ISO_2022_JP) ) { - $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8; + $sCharset = Enumerations\Charset::UTF_8; } return $sCharset; @@ -264,14 +239,28 @@ END; return $sFilePath; } - public static function ValidateCharsetName(string $sCharset) : bool + public static function MbSupportedEncoding(string $sEncoding) : bool { - $sCharset = \strtolower(static::NormalizeCharset($sCharset)); - return 0 < \strlen($sCharset) && (\in_array($sCharset, array(\MailSo\Base\Enumerations\Charset::UTF_7_IMAP)) || - \in_array($sCharset, static::$SuppostedCharsets)); + static $aSupportedEncodings = null; + if (null === $aSupportedEncodings) { + $aSupportedEncodings = \mb_list_encodings(); + $aSupportedEncodings = \array_map('strtoupper', \array_unique( + \array_merge( + $aSupportedEncodings, + \call_user_func_array( + 'array_merge', + \array_map( + 'mb_encoding_aliases', + $aSupportedEncodings + ) + ) + ) + )); + } + return \in_array(\strtoupper($sEncoding), $aSupportedEncodings); } - public static function MbConvertEncoding(string $sInputString, string $sInputFromEncoding, string $sInputToEncoding) : string + public static function MbConvertEncoding(string $sInputString, ?string $sInputFromEncoding, string $sInputToEncoding) : string { static $sMbstringSubCh = null; if (null === $sMbstringSubCh) @@ -279,11 +268,24 @@ END; $sMbstringSubCh = \mb_substitute_character(); } + if ($sInputFromEncoding) { + $sInputFromEncoding = \strtoupper($sInputFromEncoding); + if (!static::MbSupportedEncoding($sInputFromEncoding)) { + $sInputFromEncoding = null; +// return $sInputString; +/* + if (\function_exists('iconv')) { + return \iconv($sInputFromEncoding, $sInputToEncoding, $sInputString); + } +*/ + } + } + \mb_substitute_character('none'); - $sResult = \mb_convert_encoding($sInputString, \strtoupper($sInputToEncoding), \strtoupper($sInputFromEncoding)); + $sResult = \mb_convert_encoding($sInputString, \strtoupper($sInputToEncoding), $sInputFromEncoding); \mb_substitute_character($sMbstringSubCh); - return $sResult; + return (false !== $sResult) ? $sResult : $sInputString; } public static function ConvertEncoding(string $sInputString, string $sInputFromEncoding, string $sInputToEncoding) : string @@ -293,74 +295,44 @@ END; $sFromEncoding = static::NormalizeCharset($sInputFromEncoding); $sToEncoding = static::NormalizeCharset($sInputToEncoding); - if ('' === \trim($sResult) || ($sFromEncoding === $sToEncoding && \MailSo\Base\Enumerations\Charset::UTF_8 !== $sFromEncoding)) + if ('' === \trim($sResult) || ($sFromEncoding === $sToEncoding && Enumerations\Charset::UTF_8 !== $sFromEncoding)) { - return $sResult; + return $sInputString; } - $bUnknown = false; - switch (true) - { - default: - $bUnknown = true; - break; - - case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::ISO_8859_1 && - $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && - \function_exists('utf8_encode')): - - $sResult = \utf8_encode($sResult); - break; - - case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && - $sToEncoding === \MailSo\Base\Enumerations\Charset::ISO_8859_1 && - \function_exists('utf8_decode')): - - $sResult = \utf8_decode($sResult); - break; - - case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP && - $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_8): - - $sResult = static::Utf7ModifiedToUtf8($sResult); - if (false === $sResult) - { - $sResult = $sInputString; - } - break; - - case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && - $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP): - - $sResult = static::Utf8ToUtf7Modified($sResult); - if (false === $sResult) - { - $sResult = $sInputString; - } - break; - - case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP): - - $sResult = static::ConvertEncoding( - static::ModifiedToPlainUtf7($sResult), - \MailSo\Base\Enumerations\Charset::UTF_7, - $sToEncoding - ); - break; - - case (\in_array(\strtolower($sFromEncoding), static::$SuppostedCharsets)): - - $sResult = static::MbConvertEncoding($sResult, $sFromEncoding, $sToEncoding); - $sResult = (false !== $sResult) ? $sResult : $sInputString; - break; + if ($sFromEncoding === Enumerations\Charset::ISO_8859_1 + && $sToEncoding === Enumerations\Charset::UTF_8 + && \function_exists('utf8_encode')) { + return \utf8_encode($sInputString); } - if ($bUnknown) - { - $sResult = \mb_convert_encoding($sResult, $sToEncoding); + if ($sFromEncoding === Enumerations\Charset::UTF_8 + && $sToEncoding === Enumerations\Charset::ISO_8859_1 + && \function_exists('utf8_decode')) { + return \utf8_decode($sInputString); } - return $sResult; + if ($sFromEncoding === Enumerations\Charset::UTF_7_IMAP + && $sToEncoding === Enumerations\Charset::UTF_8) { + $sResult = static::Utf7ModifiedToUtf8($sInputString); + return (false !== $sResult) ? $sResult : $sInputString; + } + + if ($sFromEncoding === Enumerations\Charset::UTF_8 + && $sToEncoding === Enumerations\Charset::UTF_7_IMAP) { + $sResult = static::Utf8ToUtf7Modified($sInputString); + return (false !== $sResult) ? $sResult : $sInputString; + } + + if ($sFromEncoding === Enumerations\Charset::UTF_7_IMAP) { + return static::ConvertEncoding( + static::ModifiedToPlainUtf7($sInputString), + Enumerations\Charset::UTF_7, + $sToEncoding + ); + } + + return static::MbConvertEncoding($sInputString, $sFromEncoding, $sToEncoding); } public static function IsAscii(string $sValue) : bool @@ -441,12 +413,12 @@ END; public static function DecodeHeaderValue(string $sEncodedValue, string $sIncomingCharset = '', string $sForcedIncomingCharset = '') : string { $sValue = $sEncodedValue; - if (0 < \strlen($sIncomingCharset)) + if (\strlen($sIncomingCharset)) { $sIncomingCharset = static::NormalizeCharsetByValue($sIncomingCharset, $sValue); $sValue = static::ConvertEncoding($sValue, $sIncomingCharset, - \MailSo\Base\Enumerations\Charset::UTF_8); + Enumerations\Charset::UTF_8); } $sValue = \preg_replace('/\?=[\n\r\t\s]{1,5}=\?/m', '?==?', $sValue); @@ -502,9 +474,9 @@ END; } } - if (0 < \strlen($aTempArr[0])) + if (\strlen($aTempArr[0])) { - $sCharset = 0 === \strlen($sForcedIncomingCharset) ? $aTempArr[0] : $sForcedIncomingCharset; + $sCharset = \strlen($sForcedIncomingCharset) ? $sForcedIncomingCharset : $aTempArr[0]; $sCharset = static::NormalizeCharset($sCharset, true); if ('' === $sMainCharset) @@ -537,15 +509,15 @@ END; $aParts[$iIndex][2] = static::NormalizeCharsetByValue($aParts[$iIndex][2], $aParts[$iIndex][1]); $sValue = \str_replace($aParts[$iIndex][0], - static::ConvertEncoding($aParts[$iIndex][1], $aParts[$iIndex][2], \MailSo\Base\Enumerations\Charset::UTF_8), + static::ConvertEncoding($aParts[$iIndex][1], $aParts[$iIndex][2], Enumerations\Charset::UTF_8), $sValue); } } - if ($bOneCharset && 0 < \strlen($sMainCharset)) + if ($bOneCharset && \strlen($sMainCharset)) { $sMainCharset = static::NormalizeCharsetByValue($sMainCharset, $sValue); - $sValue = static::ConvertEncoding($sValue, $sMainCharset, \MailSo\Base\Enumerations\Charset::UTF_8); + $sValue = static::ConvertEncoding($sValue, $sMainCharset, Enumerations\Charset::UTF_8); } return $sValue; @@ -567,7 +539,7 @@ END; foreach ($aHeaders as $sLine) { - if (0 < \strlen($sLine)) + if (\strlen($sLine)) { $sFirst = \substr($sLine,0,1); if (' ' === $sFirst || "\t" === $sFirst) @@ -606,17 +578,17 @@ END; public static function EncodeUnencodedValue(string $sEncodeType, string $sValue) : string { $sValue = \trim($sValue); - if (0 < \strlen($sValue) && !static::IsAscii($sValue)) + if (\strlen($sValue) && !static::IsAscii($sValue)) { switch (\strtoupper($sEncodeType)) { case 'B': - $sValue = '=?'.\strtolower(\MailSo\Base\Enumerations\Charset::UTF_8). + $sValue = '=?'.\strtolower(Enumerations\Charset::UTF_8). '?B?'.\base64_encode($sValue).'?='; break; case 'Q': - $sValue = '=?'.\strtolower(\MailSo\Base\Enumerations\Charset::UTF_8). + $sValue = '=?'.\strtolower(Enumerations\Charset::UTF_8). '?Q?'.\str_replace(array('?', ' ', '_'), array('=3F', '_', '=5F'), \quoted_printable_encode($sValue)).'?='; break; @@ -665,7 +637,7 @@ END; $sAttrName = \trim($sAttrName); $sValue = \trim($sValue); - if (0 < \strlen($sValue) && !static::IsAscii($sValue)) + if (\strlen($sValue) && !static::IsAscii($sValue)) { $sValue = static::AttributeRfc2231Encode($sAttrName, $sValue); } @@ -680,7 +652,7 @@ END; public static function GetAccountNameFromEmail(string $sEmail) : string { $sResult = ''; - if (0 < \strlen($sEmail)) + if (\strlen($sEmail)) { $iPos = \strrpos($sEmail, '@'); $sResult = (false === $iPos) ? $sEmail : \substr($sEmail, 0, $iPos); @@ -692,7 +664,7 @@ END; public static function GetDomainFromEmail(string $sEmail) : string { $sResult = ''; - if (0 < \strlen($sEmail)) + if (\strlen($sEmail)) { $iPos = \strrpos($sEmail, '@'); if (false !== $iPos && 0 < $iPos) @@ -884,7 +856,7 @@ END; ); $sExt = static::GetFileExtension($sFileName); - if (0 < \strlen($sExt) && isset($aMimeTypes[$sExt])) + if (\strlen($sExt) && isset($aMimeTypes[$sExt])) { $sResult = $aMimeTypes[$sExt]; } @@ -955,7 +927,7 @@ END; public static function ResetTimeLimit(int $iTimeToReset = 15, int $iTimeToAdd = 120) : bool { $iTime = \time(); - if ($iTime < \MailSo\Base\Loader::$InitTime + 5) + if ($iTime < Loader::$InitTime + 5) { // do nothing first 5s return true; @@ -1301,7 +1273,7 @@ END; { $aResult = array(); $sSequence = \trim($sSequence); - if (0 < \strlen($sSequence)) + if (\strlen($sSequence)) { $aSequence = \explode(',', $sSequence); foreach ($aSequence as $sItem) @@ -1787,7 +1759,7 @@ END; $mResult = \mb_detect_encoding($sStr, 'auto', true); } - return \is_string($mResult) && 0 < \strlen($mResult) ? $mResult : ''; + return \is_string($mResult) && \strlen($mResult) ? $mResult : ''; } public static function Md5Rand(string $sAdditionalSalt = '') : string @@ -1821,7 +1793,7 @@ END; public static function IdnToUtf8(string $sStr, bool $bLowerIfAscii = false) : string { - if (0 < \strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr)) + if (\strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr)) { try { @@ -1845,7 +1817,7 @@ END; $sDomain = static::GetDomainFromEmail($sStr); } - if (0 < \strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain)) + if (\strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain)) { try { @@ -1859,12 +1831,12 @@ END; public static function HashToId(string $sHash, string $sSalt = '') : int { - $sData = $sHash ? @\MailSo\Base\Crypt::Decrypt(\hex2bin($sHash), \md5($sSalt)) : null; + $sData = $sHash ? Crypt::Decrypt(\hex2bin($sHash), \md5($sSalt)) : null; $aMatch = array(); - if ($sData && preg_match('/^id:(\d+)$/', $sData, $aMatch) && isset($aMatch[1])) + if ($sData && \preg_match('/^id:(\d+)$/', $sData, $aMatch) && isset($aMatch[1])) { - return is_numeric($aMatch[1]) ? (int) $aMatch[1] : null; + return \is_numeric($aMatch[1]) ? (int) $aMatch[1] : null; } return null; @@ -1872,6 +1844,6 @@ END; public static function IdToHash(int $iID, string $sSalt = '') : string { - return \bin2hex(\MailSo\Base\Crypt::Encrypt('id:'.$iID, \md5($sSalt))); + return \bin2hex(Crypt::Encrypt('id:'.$iID, \md5($sSalt))); } }