Replace MailSo\Base\Utils::ClearFileName() with new better MailSo\Base\Utils::SecureFileName()

This commit is contained in:
the-djmaze 2022-10-17 10:32:40 +02:00
parent a5bff8674a
commit dcc8db23b1
3 changed files with 34 additions and 38 deletions

View file

@ -148,35 +148,47 @@ abstract class Utils
'SHIFT_JIS' => 'SJIS' 'SHIFT_JIS' => 'SJIS'
]; ];
public static function MbConvertEncoding(string $sInputString, ?string $sInputFromEncoding, string $sInputToEncoding) : string public static function MbConvertEncoding(string $sInputString, ?string $sFromEncoding, string $sToEncoding) : string
{ {
if ($sInputFromEncoding) { if ($sFromEncoding) {
$sInputFromEncoding = \strtoupper($sInputFromEncoding); $sFromEncoding = \strtoupper($sFromEncoding);
if (isset(static::$RenameEncoding[$sInputFromEncoding])) { if (isset(static::$RenameEncoding[$sFromEncoding])) {
$sInputFromEncoding = static::$RenameEncoding[$sInputFromEncoding]; $sFromEncoding = static::$RenameEncoding[$sFromEncoding];
} }
if (!static::MbSupportedEncoding($sInputFromEncoding)) { /*
if ('BASE64' === $sFromEncoding) {
\base64_decode($sFromEncoding);
$sFromEncoding = null;
} else if ('UUENCODE' === $sFromEncoding) {
\convert_uudecode($sFromEncoding);
$sFromEncoding = null;
} else if ('QUOTED-PRINTABLE' === $sFromEncoding) {
\quoted_printable_decode($sFromEncoding);
$sFromEncoding = null;
} else
*/
if (!static::MbSupportedEncoding($sFromEncoding)) {
if (\function_exists('iconv')) { if (\function_exists('iconv')) {
$sResult = \iconv($sInputFromEncoding, "{$sInputToEncoding}//IGNORE", $sInputString); $sResult = \iconv($sFromEncoding, "{$sToEncoding}//IGNORE", $sInputString);
return (false !== $sResult) ? $sResult : $sInputString; return (false !== $sResult) ? $sResult : $sInputString;
} }
\error_log("Unsupported encoding {$sInputFromEncoding}"); \error_log("Unsupported encoding {$sFromEncoding}");
$sInputFromEncoding = null; $sFromEncoding = null;
// return $sInputString; // return $sInputString;
} }
} }
\mb_substitute_character('none'); \mb_substitute_character('none');
$sResult = \mb_convert_encoding($sInputString, \strtoupper($sInputToEncoding), $sInputFromEncoding); $sResult = \mb_convert_encoding($sInputString, \strtoupper($sToEncoding), $sFromEncoding);
\mb_substitute_character(0xFFFD); \mb_substitute_character(0xFFFD);
return (false !== $sResult) ? $sResult : $sInputString; return (false !== $sResult) ? $sResult : $sInputString;
} }
public static function ConvertEncoding(string $sInputString, string $sInputFromEncoding, string $sInputToEncoding) : string public static function ConvertEncoding(string $sInputString, string $sFromEncoding, string $sToEncoding) : string
{ {
$sFromEncoding = static::NormalizeCharset($sInputFromEncoding); $sFromEncoding = static::NormalizeCharset($sFromEncoding);
$sToEncoding = static::NormalizeCharset($sInputToEncoding); $sToEncoding = static::NormalizeCharset($sToEncoding);
if ('' === \trim($sInputString) || ($sFromEncoding === $sToEncoding && Enumerations\Charset::UTF_8 !== $sFromEncoding)) if ('' === \trim($sInputString) || ($sFromEncoding === $sToEncoding && Enumerations\Charset::UTF_8 !== $sFromEncoding))
{ {
@ -802,17 +814,11 @@ abstract class Utils
return false; return false;
} }
public static function ClearFileName(string $sFileName) : string # Replace ampersand, spaces and reserved characters (based on Win95 VFAT)
# en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
public static function SecureFileName(string $sFileName) : string
{ {
return static::Trim(static::ClearNullBite( return \preg_replace('#[|\\\\?*<":>+\\[\\]/&\\s\\pC]#su', '-', $sFileName);
static::StripSpaces(
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))));
}
public static function ClearXss(string $sValue) : string
{
return static::Trim(static::ClearNullBite(
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue)));
} }
public static function Trim(string $sValue) : string public static function Trim(string $sValue) : string
@ -1063,12 +1069,9 @@ abstract class Utils
public static function Utf7ModifiedToUtf8(string $sStr) : string public static function Utf7ModifiedToUtf8(string $sStr) : string
{ {
// imap_mutf7_to_utf8() is broken and doesn't support U+10000 and up, // imap_mutf7_to_utf8() doesn't support U+10000 and up,
// thats why mmb_convert_encoding is used // thats why mb_convert_encoding is used
$sResult = static::MbConvertEncoding($sStr, 'UTF7-IMAP', 'UTF-8'); return static::MbConvertEncoding($sStr, 'UTF7-IMAP', 'UTF-8');
// ucnv U_FILE_ACCESS_ERROR
// $sResult = \UConverter::transcode($sStr, \UConverter::UTF8, \UConverter::IMAP_MAILBOX, ['to_subst' => '<27>']);
return (false === $sResult) ? $sStr : $sResult;
} }
public static function Utf8ToUtf7Modified(string $sStr) : string public static function Utf8ToUtf7Modified(string $sStr) : string
@ -1077,8 +1080,6 @@ abstract class Utils
? \imap_utf8_to_mutf7($sStr) ? \imap_utf8_to_mutf7($sStr)
// : \mb_convert_encoding($sStr, 'UTF7-IMAP', 'UTF-8'); // : \mb_convert_encoding($sStr, 'UTF7-IMAP', 'UTF-8');
: static::MbConvertEncoding($sStr, 'UTF-8', 'UTF7-IMAP'); : static::MbConvertEncoding($sStr, 'UTF-8', 'UTF7-IMAP');
// ucnv U_FILE_ACCESS_ERROR
// $sResult = \UConverter::transcode($sStr, \UConverter::IMAP_MAILBOX, \UConverter::UTF8);
return (false === $sResult) ? $sStr : $sResult; return (false === $sResult) ? $sStr : $sResult;
} }
@ -1107,11 +1108,6 @@ abstract class Utils
// && \is_callable($mFunctionNameOrNames); // && \is_callable($mFunctionNameOrNames);
} }
public static function ClearNullBite($mValue) : string
{
return \str_replace('%00', '', $mValue);
}
public static function CharsetDetect(string $sStr) : string public static function CharsetDetect(string $sStr) : string
{ {
$mResult = ''; $mResult = '';

View file

@ -172,7 +172,7 @@ class Attachment implements \JsonSerializable
'Uid' => (string) $this->Uid(), 'Uid' => (string) $this->Uid(),
'MimeIndex' => (string) $this->MimeIndex(), 'MimeIndex' => (string) $this->MimeIndex(),
'MimeType' => $this->MimeType(), 'MimeType' => $this->MimeType(),
'FileName' => \MailSo\Base\Utils::ClearFileName(\MailSo\Base\Utils::ClearXss($this->FileName(true))), 'FileName' => \MailSo\Base\Utils::SecureFileName($this->FileName(true)),
'EstimatedSize' => $this->EstimatedSize(), 'EstimatedSize' => $this->EstimatedSize(),
'Cid' => $this->Cid(), 'Cid' => $this->Cid(),
'ContentLocation' => $this->ContentLocation(), 'ContentLocation' => $this->ContentLocation(),

View file

@ -191,7 +191,7 @@ trait Response
'Folder' => $mResult['Folder'], 'Folder' => $mResult['Folder'],
'Uid' => $mResult['Uid'], 'Uid' => $mResult['Uid'],
'MimeType' => 'message/rfc822', 'MimeType' => 'message/rfc822',
'FileName' => (\strlen($sSubject) ? \MailSo\Base\Utils::ClearXss($sSubject) : 'message-'.$mResult['Uid']) . '.eml' 'FileName' => (\strlen($sSubject) ? \MailSo\Base\Utils::SecureFileName($sSubject) : 'message-'.$mResult['Uid']) . '.eml'
)); ));
if ('Message' === $sParent) if ('Message' === $sParent)