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 afc7808bb..bea06f027 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
@@ -20,11 +20,7 @@ abstract class Utils
public static function NormalizeCharset(string $sEncoding, bool $bAsciAsUtf8 = false) : string
{
- $sEncoding = \strtolower($sEncoding);
-
- $sEncoding = \preg_replace('/^iso8/', 'iso-8', $sEncoding);
- $sEncoding = \preg_replace('/^cp-([\d])/', 'cp$1', $sEncoding);
- $sEncoding = \preg_replace('/^windows?12/', 'windows-12', $sEncoding);
+ $sEncoding = \preg_replace('/^iso8/', 'iso-8', \strtolower($sEncoding));
switch ($sEncoding)
{
@@ -32,38 +28,40 @@ abstract class Utils
case 'ascii':
case 'us-asci':
case 'us-ascii':
- $sEncoding = $bAsciAsUtf8 ? Enumerations\Charset::UTF_8 :
+ return $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 = 'utf-7';
- break;
+ return 'utf-7';
+
case 'utf8':
case 'utf-8':
- $sEncoding = Enumerations\Charset::UTF_8;
- break;
+ return Enumerations\Charset::UTF_8;
+
case 'utf7imap':
case 'utf-7imap':
case 'utf7-imap':
case 'utf-7-imap':
- $sEncoding = 'utf7-imap';
- break;
+ return 'utf7-imap';
+
case 'ks-c-5601-1987':
case 'ks_c_5601-1987':
case 'ks_c_5601_1987':
- $sEncoding = 'euc-kr';
- break;
+ return 'euc-kr';
+
case 'x-gbk':
- $sEncoding = 'gb2312';
- break;
+ return 'gb2312';
+
case 'iso-8859-i':
case 'iso-8859-8-i':
- $sEncoding = 'iso-8859-8';
- break;
+ return 'iso-8859-8';
}
+ $sEncoding = \preg_replace('/^cp-([\d])/', 'cp$1', $sEncoding);
+ $sEncoding = \preg_replace('/^windows?12/', 'windows-12', $sEncoding);
+
return $sEncoding;
}
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php
index 1e07425eb..289b53e5b 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/BodyStructure.php
@@ -52,11 +52,6 @@ class BodyStructure
*/
private $sDisposition;
- /**
- * @var array
- */
- private $aDispositionParams;
-
/**
* @var string
*/
@@ -65,23 +60,18 @@ class BodyStructure
/**
* @var string
*/
- private $sLanguage;
+ private $sLanguage = '';
/**
* @var string
*/
- private $sLocation;
+ private $sLocation = '';
/**
* @var int
*/
private $iSize;
- /**
- * @var int
- */
- private $iTextLineCount;
-
/**
* @var string
*/
@@ -92,35 +82,14 @@ class BodyStructure
*/
private $aSubParts;
- function __construct(string $sContentType, ?string $sCharset, array $aBodyParams, ?string $sContentID,
- ?string $sDescription, ?string $sMailEncodingName, ?string $sDisposition, ?array $aDispositionParams, string $sFileName,
- ?string $sLanguage, ?string $sLocation, int $iSize, int $iTextLineCount, string $sPartID, array $aSubParts)
- {
- $this->sContentType = $sContentType;
- $this->sCharset = $sCharset;
- $this->aBodyParams = $aBodyParams;
- $this->sContentID = $sContentID;
- $this->sDescription = $sDescription;
- $this->sMailEncodingName = $sMailEncodingName;
- $this->sDisposition = $sDisposition;
- $this->aDispositionParams = $aDispositionParams;
- $this->sFileName = $sFileName;
- $this->sLanguage = $sLanguage;
- $this->sLocation = $sLocation;
- $this->iSize = $iSize;
- $this->iTextLineCount = $iTextLineCount;
- $this->sPartID = $sPartID;
- $this->aSubParts = $aSubParts;
- }
-
- public function MailEncodingName() : ?string
+ public function MailEncodingName() : string
{
return $this->sMailEncodingName;
}
public function PartID() : string
{
- return (string) $this->sPartID;
+ return $this->sPartID;
}
public function FileName() : string
@@ -141,7 +110,7 @@ class BodyStructure
public function EstimatedSize() : int
{
$fCoefficient = 1;
- switch (\strtolower($this->MailEncodingName()))
+ switch ($this->sMailEncodingName)
{
case 'base64':
$fCoefficient = 0.75;
@@ -151,68 +120,63 @@ class BodyStructure
break;
}
- return (int) ($this->Size() * $fCoefficient);
+ return (int) ($this->iSize * $fCoefficient);
}
- public function Charset() : ?string
+ public function Charset() : string
{
return $this->sCharset;
}
public function ContentID() : string
{
- return (null === $this->sContentID) ? '' : $this->sContentID;
+ return $this->sContentID;
}
public function ContentLocation() : string
{
- return (null === $this->sLocation) ? '' : $this->sLocation;
+ return $this->sLocation;
}
public function IsInline() : bool
{
- return (null === $this->sDisposition) ?
- (\strlen($this->ContentID())) : ('inline' === strtolower($this->sDisposition));
+ return 'inline' === $this->sDisposition || \strlen($this->sContentID);
}
public function IsImage() : bool
{
- return 'image' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
+ return 'image' === \MailSo\Base\Utils::ContentTypeType($this->sContentType, $this->sFileName);
}
public function IsArchive() : bool
{
- return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
+ return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->sContentType, $this->sFileName);
}
public function IsPdf() : bool
{
- return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
+ return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->sContentType, $this->sFileName);
}
public function IsDoc() : bool
{
- return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
+ return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->sContentType, $this->sFileName);
}
public function IsPgpSignature() : bool
{
- return \in_array(\strtolower($this->ContentType()),
+ return \in_array($this->sContentType,
array('application/pgp-signature', 'application/pkcs7-signature'));
}
public function IsAttachBodyPart() : bool
{
- $bResult = (
- (null !== $this->sDisposition && 'attachment' === \strtolower($this->sDisposition))
- );
-
- if (!$bResult && null !== $this->sContentType)
- {
- $sContentType = \strtolower($this->sContentType);
- $bResult = false === \strpos($sContentType, 'multipart/') &&
- 'text/html' !== $sContentType && 'text/plain' !== $sContentType;
- }
+ return 'attachment' === $this->sDisposition
+ || (
+ !\str_starts_with($this->sContentType, 'multipart/')
+ && 'text/html' !== $this->sContentType
+ && 'text/plain' !== $this->sContentType
+ );
return $bResult;
}
@@ -222,7 +186,7 @@ class BodyStructure
$bResult = !empty($this->aBodyParams['format']) &&
'flowed' === \strtolower(\trim($this->aBodyParams['format']));
- if ($bResult && \in_array(\strtolower($this->MailEncodingName()), array('base64', 'quoted-printable')))
+ if ($bResult && \in_array($this->sMailEncodingName, array('base64', 'quoted-printable')))
{
$bResult = false;
}
@@ -230,43 +194,13 @@ class BodyStructure
return $bResult;
}
- public function SearchPlainParts() : array
- {
- $aReturn = array();
- $aParts = $this->SearchByContentType('text/plain');
- foreach ($aParts as $oPart)
- {
- if (!$oPart->IsAttachBodyPart())
- {
- $aReturn[] = $oPart;
- }
- }
- return $aReturn;
- }
-
- public function SearchHtmlParts() : array
- {
- $aReturn = array();
- $aParts = $this->SearchByContentType('text/html');
-
- foreach ($aParts as $oPart)
- {
- if (!$oPart->IsAttachBodyPart())
- {
- $aReturn[] = $oPart;
- }
- }
-
- return $aReturn;
- }
-
public function SearchInlineEncryptedPart() : ?self
{
- if ('multipart/encrypted' === \strtolower($this->ContentType()))
+ if ('multipart/encrypted' === \strtolower($this->sContentType))
{
- $aSearchParts = $this->SearchByCallback(function ($oItem) {
+ $aSearchParts = \iterator_to_array($this->SearchByCallback(function ($oItem) {
return $oItem->IsInline();
- });
+ }));
if (1 === \count($aSearchParts) && isset($aSearchParts[0]))
{
@@ -277,82 +211,68 @@ class BodyStructure
return null;
}
- public function SearchHtmlOrPlainParts() : array
+ public function GetHtmlAndPlainParts() : array
{
- $mResult = $this->SearchHtmlParts() ?: $this->SearchPlainParts();
- if (!$mResult)
- {
- $oPart = $this->SearchInlineEncryptedPart();
- if ($oPart instanceof self)
- {
- $mResult = array($oPart);
- }
+ $aParts = $this->SearchByCallback(function ($oItem) {
+ return ('text/html' === $oItem->sContentType || 'text/plain' === $oItem->sContentType)
+ && !$oItem->IsAttachBodyPart();
+ });
+
+ if ($aParts->valid()) {
+ return \iterator_to_array($aParts);
}
- return $mResult;
+ $oPart = $this->SearchInlineEncryptedPart();
+ if ($oPart instanceof self) {
+ return array($oPart);
+ }
+
+ return [];
}
public function SearchCharset() : string
{
- $sResult = '';
- $mParts = \array_merge($this->SearchHtmlParts(), $this->SearchPlainParts());
+ $gParts = $this->SearchByCallback(function ($oPart) {
+ return $oPart->Charset()
+ && ('text/html' === $oPart->sContentType || 'text/plain' === $oPart->sContentType)
+ && !$oPart->IsAttachBodyPart();
+ });
- foreach ($mParts as $oPart)
- {
- $sResult = $oPart ? $oPart->Charset() : '';
- if ($sResult)
- {
- break;
- }
+ if (!$gParts->valid()) {
+ $gParts = $this->SearchByCallback(function ($oPart) {
+ return $oPart->Charset() && $oPart->IsAttachBodyPart();
+ });
}
- if (!$sResult)
- {
- $aParts = $this->SearchAttachmentsParts();
- foreach ($aParts as $oPart)
- {
- $sResult = $oPart ? $oPart->Charset() : '';
- if ($sResult)
- {
- break;
- }
- }
- }
-
- return $sResult ?: '';
+ return $gParts->valid() ? $gParts->current()->Charset() : '';
}
/**
* @param mixed $fCallback
*/
- public function SearchByCallback($fCallback) : array
+// public function SearchByCallback($fCallback) : \Generator
+ public function SearchByCallback($fCallback) : iterable
{
- $aReturn = array();
- if ($fCallback($this))
- {
- $aReturn[] = $this;
+ if ($fCallback($this)) {
+ yield $this;
}
-
- foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ $oSubPart)
- {
- $aReturn = \array_merge($aReturn, $oSubPart->SearchByCallback($fCallback));
+ foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ $oSubPart) {
+ yield from $oSubPart->SearchByCallback($fCallback);
}
-
- return $aReturn;
}
- public function SearchAttachmentsParts() : array
+ public function SearchAttachmentsParts() : iterable
{
return $this->SearchByCallback(function ($oItem) {
return $oItem->IsAttachBodyPart();
});
}
- public function SearchByContentType(string $sContentType) : array
+ public function SearchByContentType(string $sContentType) : iterable
{
$sContentType = \strtolower($sContentType);
return $this->SearchByCallback(function ($oItem) use ($sContentType) {
- return $sContentType === $oItem->ContentType();
+ return $sContentType === $oItem->sContentType;
});
}
@@ -382,7 +302,7 @@ class BodyStructure
return $oPart;
}
- private static function decodeAttrParameter(array $aParams, string $sParamName, string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8) : string
+ private static function decodeAttrParameter(array $aParams, string $sParamName, string $sCharset) : string
{
$sResult = '';
if (isset($aParams[$sParamName]))
@@ -455,34 +375,23 @@ class BodyStructure
return null;
}
- $sBodyMainType = null;
- if (\is_string($aBodyStructure[0]))
- {
- $sBodyMainType = $aBodyStructure[0];
- }
-
- $sBodySubType = null;
- $sContentType = '';
+ $sContentTypeMain = '';
+ $sContentTypeSub = '';
$aSubParts = array();
$aBodyParams = array();
- $sName = null;
- $sCharset = null;
- $sContentID = null;
- $sDescription = null;
- $sMailEncodingName = null;
+ $sName = '';
+ $sCharset = ''; // \MailSo\Base\Enumerations\Charset::UTF_8 ?
+ $sContentID = '';
+ $sDescription = '';
+ $sMailEncodingName = '';
$iSize = 0;
- $iTextLineCount = 0; // valid for rfc822/message and text parts
$iExtraItemPos = 0; // list index of items which have no well-established position (such as 0, 1, 5, etc).
- if (null === $sBodyMainType)
+ if (\is_array($aBodyStructure[0]))
{
// Process multipart body structure
- if (!\is_array($aBodyStructure[0]))
- {
- return null;
- }
-
- $sBodyMainType = 'multipart';
+ $sContentTypeMain = 'multipart';
+ $sContentTypeSub = 'mixed'; // primary default
$sSubPartIDPrefix = '';
if (!\strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1])
{
@@ -498,17 +407,22 @@ class BodyStructure
$iIndex = 1;
+ /**
+ * First process the subparts, like:
+ ("text" "plain" ("charset" "utf-8") …)
+ ("text" "html" …)
+ */
while ($iExtraItemPos < \count($aBodyStructure) && \is_array($aBodyStructure[$iExtraItemPos]))
{
$oPart = self::NewInstance($aBodyStructure[$iExtraItemPos], $sSubPartIDPrefix.$iIndex);
- if (null === $oPart)
+ if (!$oPart)
{
return null;
}
// For multipart, we have no charset info in the part itself. Thus,
// obtain charset from nested parts.
- if ($sCharset == null)
+ if (!$sCharset)
{
$sCharset = $oPart->Charset();
}
@@ -518,43 +432,35 @@ class BodyStructure
++$iIndex;
}
+ /**
+ * Now process the subparts containter like:
+ "alternative" ("boundary" "--boundary_id") …
+ */
if ($iExtraItemPos < \count($aBodyStructure))
{
if (!\is_string($aBodyStructure[$iExtraItemPos]))
{
return null;
}
+ $sContentTypeSub = \strtolower($aBodyStructure[$iExtraItemPos]);
- $sBodySubType = \strtolower($aBodyStructure[$iExtraItemPos]);
++$iExtraItemPos;
- }
-
- if ($iExtraItemPos < \count($aBodyStructure))
- {
- $sBodyParamList = $aBodyStructure[$iExtraItemPos];
- if (\is_array($sBodyParamList))
+ if ($iExtraItemPos < \count($aBodyStructure) && \is_array($aBodyStructure[$iExtraItemPos]))
{
- $aBodyParams = self::getKeyValueListFromArrayList($sBodyParamList);
+ $aBodyParams = self::getKeyValueListFromArrayList($aBodyStructure[$iExtraItemPos]);
}
}
-
- ++$iExtraItemPos;
}
- else
+ else if (\is_string($aBodyStructure[0]))
{
// Process simple (singlepart) body structure
- if (7 > \count($aBodyStructure))
+ if (7 > \count($aBodyStructure) || !\is_string($aBodyStructure[1]))
{
return null;
}
- $sBodyMainType = \strtolower($sBodyMainType);
- if (!\is_string($aBodyStructure[1]))
- {
- return null;
- }
-
- $sBodySubType = \strtolower($aBodyStructure[1]);
+ $sContentTypeMain = \strtolower($aBodyStructure[0]);
+ $sContentTypeSub = \strtolower($aBodyStructure[1]);
$aBodyParamList = $aBodyStructure[2];
if (\is_array($aBodyParamList))
@@ -565,7 +471,7 @@ class BodyStructure
$sCharset = $aBodyParams['charset'];
}
- $sName = self::decodeAttrParameter($aBodyParams, 'name', $sContentType);
+ $sName = self::decodeAttrParameter($aBodyParams, 'name', $sCharset);
}
if (null !== $aBodyStructure[3])
@@ -574,7 +480,6 @@ class BodyStructure
{
return null;
}
-
$sContentID = $aBodyStructure[3];
}
@@ -584,7 +489,6 @@ class BodyStructure
{
return null;
}
-
$sDescription = $aBodyStructure[4];
}
@@ -597,14 +501,7 @@ class BodyStructure
$sMailEncodingName = $aBodyStructure[5];
}
- if (\is_numeric($aBodyStructure[6]))
- {
- $iSize = (int) $aBodyStructure[6];
- }
- else
- {
- $iSize = -1;
- }
+ $iSize = \is_numeric($aBodyStructure[6]) ? (int) $aBodyStructure[6] : -1;
if (!\strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1])
{
@@ -614,161 +511,85 @@ class BodyStructure
}
$iExtraItemPos = 7;
- if ('text' === $sBodyMainType)
+ if ('text' === $sContentTypeMain)
{
- if ($iExtraItemPos < \count($aBodyStructure))
- {
- if (\is_numeric($aBodyStructure[$iExtraItemPos]))
- {
- $iTextLineCount = (int) $aBodyStructure[$iExtraItemPos];
- }
- else
- {
- $iTextLineCount = -1;
- }
- }
- else
- {
- $iTextLineCount = -1;
- }
-
+ /**
+ * A body type of type TEXT contains, immediately after the basic
+ * fields, the size of the body in text lines.
+ */
++$iExtraItemPos;
}
- else if ('message' === $sBodyMainType && 'rfc822' === $sBodySubType)
+ else if ('message' === $sContentTypeMain && 'rfc822' === $sContentTypeSub)
{
- if ($iExtraItemPos + 2 < \count($aBodyStructure))
- {
- if (\is_numeric($aBodyStructure[$iExtraItemPos + 2]))
- {
- $iTextLineCount = (int) $aBodyStructure[$iExtraItemPos + 2];
- }
- else
- {
- $iTextLineCount = -1;
- }
- }
- else
- {
- $iTextLineCount = -1;
- }
-
+ /**
+ * A body type of type MESSAGE and subtype RFC822 contains,
+ * immediately after the basic fields, the envelope structure,
+ * body structure, and size in text lines of the encapsulated message.
+ */
$iExtraItemPos += 3;
}
-
- ++$iExtraItemPos; // skip MD5 digest of the body because most mail servers leave it NIL anyway
+ }
+ else
+ {
+ return null;
}
- $sContentType = $sBodyMainType.'/'.$sBodySubType;
+ // Skip body MD5 because most mail servers leave it NIL anyway
+ ++$iExtraItemPos;
- $sDisposition = null;
- $aDispositionParams = null;
- $sFileName = null;
+ $sDisposition = '';
+ $sFileName = '';
if ($iExtraItemPos < \count($aBodyStructure))
{
$aDispList = $aBodyStructure[$iExtraItemPos];
if (\is_array($aDispList) && 1 < \count($aDispList))
{
- if (null !== $aDispList[0])
+ if (!\is_string($aDispList[0]))
{
- if (\is_string($aDispList[0]))
- {
- $sDisposition = $aDispList[0];
- }
- else
- {
- return null;
- }
+ return null;
}
-
- $aDispParamList = $aDispList[1];
- if (\is_array($aDispParamList))
+ $sDisposition = $aDispList[0];
+ if (\is_array($aDispList[1]))
{
- $aDispositionParams = self::getKeyValueListFromArrayList($aDispParamList);
- $sFileName = self::decodeAttrParameter($aDispositionParams, 'filename', $sCharset ?: '');
+ $aDispositionParams = self::getKeyValueListFromArrayList($aDispList[1]);
+ $sFileName = self::decodeAttrParameter($aDispositionParams, 'filename', $sCharset);
}
}
}
- ++$iExtraItemPos;
+ $oStructure = new self;
+ $oStructure->sContentType = \strtolower($sContentTypeMain.'/'.$sContentTypeSub);
+ $oStructure->sCharset = $sCharset;
+ $oStructure->aBodyParams = $aBodyParams;
+ $oStructure->sContentID = $sContentID;
+ $oStructure->sDescription = $sDescription;
+ $oStructure->sMailEncodingName = \strtolower($sMailEncodingName);
+ $oStructure->sDisposition = \strtolower($sDisposition);
+ $oStructure->sFileName = \MailSo\Base\Utils::Utf8Clear($sFileName ?: $sName);
+ $oStructure->iSize = $iSize;
+ $oStructure->sPartID = $sPartID;
+ $oStructure->aSubParts = $aSubParts;
- $sLanguage = null;
if ($iExtraItemPos < \count($aBodyStructure))
{
- if (null !== $aBodyStructure[$iExtraItemPos])
+ if (\is_array($aBodyStructure[$iExtraItemPos]))
{
- if (\is_array($aBodyStructure[$iExtraItemPos]))
- {
- $sLanguage = \implode(',', $aBodyStructure[$iExtraItemPos]);
- }
- else if (\is_string($aBodyStructure[$iExtraItemPos]))
- {
- $sLanguage = $aBodyStructure[$iExtraItemPos];
- }
+ $oStructure->sLanguage = \implode(',', $aBodyStructure[$iExtraItemPos]);
+ }
+ else if (\is_string($aBodyStructure[$iExtraItemPos]))
+ {
+ $oStructure->sLanguage = $aBodyStructure[$iExtraItemPos];
}
++$iExtraItemPos;
}
- $sLocation = null;
- if ($iExtraItemPos < \count($aBodyStructure))
+ if ($iExtraItemPos < \count($aBodyStructure) && \is_string($aBodyStructure[$iExtraItemPos]))
{
- if (null !== $aBodyStructure[$iExtraItemPos])
- {
- if (\is_string($aBodyStructure[$iExtraItemPos]))
- {
- $sLocation = $aBodyStructure[$iExtraItemPos];
- }
- }
- ++$iExtraItemPos;
+ $oStructure->sLocation = $aBodyStructure[$iExtraItemPos];
}
- return new self(
- $sContentType,
- $sCharset,
- $aBodyParams,
- $sContentID,
- $sDescription,
- $sMailEncodingName,
- $sDisposition,
- $aDispositionParams,
- \MailSo\Base\Utils::Utf8Clear($sFileName ?: $sName),
- $sLanguage,
- $sLocation,
- $iSize,
- $iTextLineCount,
- $sPartID,
- $aSubParts
- );
- }
-
- public static function NewInstanceFromRfc822SubPart(array $aBodyStructure, string $sSubPartID) : ?self
- {
- $aBodySubStructure = self::findPartByIndexInArray($aBodyStructure, $sSubPartID);
- if ($aBodySubStructure && \is_array($aBodySubStructure) && isset($aBodySubStructure[8]))
- {
- return self::NewInstance($aBodySubStructure[8], $sSubPartID);
- }
-
- return null;
- }
-
- private static function findPartByIndexInArray(array $aList, string $sPartID) : ?array
- {
- $bFind = false;
- $aPath = \explode('.', ''.$sPartID);
- $aCurrentPart = $aList;
-
- foreach ($aPath as $iPos => $iNum)
- {
- $iIndex = \intval($iNum) - 1;
- if (0 <= $iIndex && 0 < $iPos ? isset($aCurrentPart[8][$iIndex]) : isset($aCurrentPart[$iIndex]))
- {
- $aCurrentPart = 0 < $iPos ? $aCurrentPart[8][$iIndex] : $aCurrentPart[$iIndex];
- $bFind = true;
- }
- }
-
- return $bFind ? $aCurrentPart : null;
+ return $oStructure;
}
/**
@@ -783,7 +604,7 @@ class BodyStructure
{
for ($iIndex = 0; $iIndex < $iLen; $iIndex += 2)
{
- if (\is_string($aList[$iIndex]) && isset($aList[$iIndex + 1]) && \is_string($aList[$iIndex + 1]))
+ if (\is_string($aList[$iIndex]) && \is_string($aList[$iIndex + 1]))
{
$aDict[\strtolower($aList[$iIndex])] = $aList[$iIndex + 1];
}
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php
index 9735bbaff..56c560d29 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php
@@ -83,20 +83,13 @@ class FetchResponse
return $oResult;
}
- public function GetFetchBodyStructure(string $sRfc822SubMimeIndex = '') : ?BodyStructure
+ public function GetFetchBodyStructure() : ?BodyStructure
{
$aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE);
- if (\is_array($aBodyStructureArray))
- {
- if (\strlen($sRfc822SubMimeIndex))
- {
- return BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex);
- }
- return BodyStructure::NewInstance($aBodyStructureArray);
- }
-
- return null;
+ return \is_array($aBodyStructureArray)
+ ? BodyStructure::NewInstance($aBodyStructureArray)
+ : null;
}
/**
@@ -125,12 +118,10 @@ class FetchResponse
* Like: BODY[HEADER.FIELDS (RETURN-PATH RECEIVED MIME-VERSION MESSAGE-ID CONTENT-TYPE FROM TO CC BCC SENDER REPLY-TO DELIVERED-TO IN-REPLY-TO REFERENCES DATE SUBJECT SENSITIVITY X-MSMAIL-PRIORITY IMPORTANCE X-PRIORITY X-DRAFT-INFO RETURN-RECEIPT-TO DISPOSITION-NOTIFICATION-TO X-CONFIRM-READING-TO AUTHENTICATION-RESULTS X-DKIM-AUTHENTICATION-RESULTS LIST-UNSUBSCRIBE X-SPAM-STATUS X-SPAMD-RESULT X-BOGOSITY X-VIRUS X-VIRUS-SCANNED X-VIRUS-STATUS)]
* @return mixed
*/
- public function GetHeaderFieldsValue(string $sRfc822SubMimeIndex = '') : string
+ public function GetHeaderFieldsValue() : string
{
$bNextIsValue = false;
- $sRfc822SubMimeIndex = \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : '';
-
if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
{
foreach ($this->oImapResponse->ResponseList[3] as $mItem)
@@ -141,9 +132,9 @@ class FetchResponse
}
if (\is_string($mItem) && (
- $mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' ||
- 0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') ||
- $mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]'))
+ $mItem === 'BODY[HEADER]' ||
+ 0 === \strpos($mItem, 'BODY[HEADER.FIELDS') ||
+ $mItem === 'BODY[MIME]'))
{
$bNextIsValue = true;
}
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Attachment.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Attachment.php
index 741bfd4e4..93ccb71ae 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Attachment.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Attachment.php
@@ -100,11 +100,6 @@ class Attachment implements \JsonSerializable
return $this->oBodyStructure ? $this->oBodyStructure->ContentType() : '';
}
- public function ContentTransferEncoding() : string
- {
- return $this->oBodyStructure ? $this->oBodyStructure->MailEncodingName() : '';
- }
-
public function EncodedSize() : int
{
return $this->oBodyStructure ? $this->oBodyStructure->Size() : 0;
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
index cf39ea9ae..1dd08dcb6 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
@@ -170,7 +170,7 @@ class MailClient
$oBodyStructure = $aFetchResponse[0]->GetFetchBodyStructure();
if ($oBodyStructure)
{
- foreach ($oBodyStructure->SearchHtmlOrPlainParts() as $oPart)
+ foreach ($oBodyStructure->GetHtmlAndPlainParts() as $oPart)
{
$sLine = FetchType::BODY_PEEK.'['.$oPart->PartID().']';
if (0 < $iBodyTextLimit && $iBodyTextLimit < $oPart->Size())
@@ -181,13 +181,10 @@ class MailClient
$aFetchItems[] = $sLine;
}
- $aSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature');
- if (\is_array($aSignatureParts) && \count($aSignatureParts))
+ $gSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature');
+ foreach ($gSignatureParts as $oPart)
{
- foreach ($aSignatureParts as $oPart)
- {
- $aFetchItems[] = FetchType::BODY_PEEK.'['.$oPart->PartID().']';
- }
+ $aFetchItems[] = FetchType::BODY_PEEK.'['.$oPart->PartID().']';
}
}
}
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php
index 7bd95be6a..8c3c1aeb4 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php
@@ -11,6 +11,9 @@
namespace MailSo\Mail;
+use \MailSo\Base\Utils;
+use \MailSo\Imap\Enumerations\FetchType;
+
/**
* @category MailSo
* @package Mail
@@ -116,11 +119,6 @@ class Message implements \JsonSerializable
return $this->bPgpEncrypted;
}
- public function SetHtml(string $sHtml) : void
- {
- $this->sHtml = $sHtml;
- }
-
public function Folder() : string
{
return $this->sFolder;
@@ -298,19 +296,18 @@ class Message implements \JsonSerializable
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
}
- $sInternalDate = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INTERNALDATE);
- $aFlags = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::FLAGS);
+ $sInternalDate = $oFetchResponse->GetFetchValue(FetchType::INTERNALDATE);
+ $aFlags = $oFetchResponse->GetFetchValue(FetchType::FLAGS);
$this->sFolder = $sFolder;
- $this->iUid = (int) $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID);
- $this->iSize = (int) $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE);
+ $this->iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
+ $this->iSize = (int) $oFetchResponse->GetFetchValue(FetchType::RFC822_SIZE);
$this->aFlagsLowerCase = \array_map('strtolower', $aFlags ?: []);
$this->iInternalTimeStampInUTC =
\MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate);
- $sCharset = $oBodyStructure ? $oBodyStructure->SearchCharset() : '';
- $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
+ $sCharset = $oBodyStructure ? Utils::NormalizeCharset($oBodyStructure->SearchCharset()) : '';
$sHeaders = $oFetchResponse->GetHeaderFieldsValue();
if (\strlen($sHeaders))
@@ -324,8 +321,7 @@ class Message implements \JsonSerializable
if (\strlen($sContentTypeCharset))
{
- $sCharset = $sContentTypeCharset;
- $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
+ $sCharset = Utils::NormalizeCharset($sContentTypeCharset);
}
if (\strlen($sCharset))
@@ -353,7 +349,7 @@ class Message implements \JsonSerializable
$this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
$this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
- $this->sReferences = \MailSo\Base\Utils::StripSpaces(
+ $this->sReferences = Utils::StripSpaces(
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
$sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
@@ -491,20 +487,11 @@ class Message implements \JsonSerializable
}
else if ($oFetchResponse->GetEnvelope())
{
- if (!\strlen($sCharset) && $oBodyStructure)
- {
- $sCharset = $oBodyStructure->SearchCharset();
- $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
- }
-
- if (!\strlen($sCharset))
- {
- $sCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
- }
+ $sCharset = $sCharset ?: \MailSo\Base\Enumerations\Charset::ISO_8859_1;
// date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, message-id
$this->sMessageId = $oFetchResponse->GetFetchEnvelopeValue(9, '');
- $this->sSubject = \MailSo\Base\Utils::DecodeHeaderValue($oFetchResponse->GetFetchEnvelopeValue(1, ''), $sCharset);
+ $this->sSubject = Utils::DecodeHeaderValue($oFetchResponse->GetFetchEnvelopeValue(1, ''), $sCharset);
$this->oFrom = $oFetchResponse->GetFetchEnvelopeEmailCollection(2, $sCharset);
$this->oSender = $oFetchResponse->GetFetchEnvelopeEmailCollection(3, $sCharset);
@@ -519,9 +506,10 @@ class Message implements \JsonSerializable
if ('multipart/signed' === \strtolower($this->sContentType)
&& 'application/pgp-signature' === \strtolower($oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, \MailSo\Mime\Enumerations\Parameter::PROTOCOL)))
{
- $aPgpSignatureParts = $oBodyStructure ? $oBodyStructure->SearchByContentType('application/pgp-signature') : null;
- if ($this->bPgpSigned = !empty($aPgpSignatureParts)) {
- $sPgpSignatureText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$aPgpSignatureParts[0]->PartID().']');
+ $gPgpSignatureParts = $oBodyStructure ? $oBodyStructure->SearchByContentType('application/pgp-signature') : null;
+ $this->bPgpSigned = $gPgpSignatureParts && $gPgpSignatureParts->valid();
+ if ($this->bPgpSigned) {
+ $sPgpSignatureText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$gPgpSignatureParts->current()->PartID().']');
if (\is_string($sPgpSignatureText) && \strlen($sPgpSignatureText) && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE')) {
$this->sPgpSignature = \trim($sPgpSignatureText);
$this->sPgpSignatureMicAlg = (string) $oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, 'micalg');
@@ -533,23 +521,21 @@ class Message implements \JsonSerializable
$this->bPgpEncrypted = ('multipart/encrypted' === \strtolower($this->sContentType)
&& 'application/pgp-encrypted' === \strtolower($oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, \MailSo\Mime\Enumerations\Parameter::PROTOCOL)));
- $aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : null;
+ $aTextParts = $oBodyStructure ? $oBodyStructure->GetHtmlAndPlainParts() : null;
+
if ($aTextParts)
{
- if (!\strlen($sCharset))
- {
- $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
- }
+ $sCharset = $sCharset ?: \MailSo\Base\Enumerations\Charset::UTF_8;
$aHtmlParts = array();
$aPlainParts = array();
foreach ($aTextParts as $oPart)
{
- $sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$oPart->PartID().']');
+ $sText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oPart->PartID().']');
if (null === $sText)
{
- $sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$oPart->PartID().']<0>');
+ $sText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oPart->PartID().']<0>');
if (\is_string($sText) && \strlen($sText))
{
$this->bTextPartIsTrimmed = true;
@@ -564,11 +550,11 @@ class Message implements \JsonSerializable
$sTextCharset = $sCharset;
}
- $sTextCharset = \MailSo\Base\Utils::NormalizeCharset($sTextCharset, true);
+ $sTextCharset = Utils::NormalizeCharset($sTextCharset, true);
- $sText = \MailSo\Base\Utils::DecodeEncodingValue($sText, $oPart->MailEncodingName());
- $sText = \MailSo\Base\Utils::ConvertEncoding($sText, $sTextCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
- $sText = \MailSo\Base\Utils::Utf8Clear($sText);
+ $sText = Utils::DecodeEncodingValue($sText, $oPart->MailEncodingName());
+ $sText = Utils::ConvertEncoding($sText, $sTextCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
+ $sText = Utils::Utf8Clear($sText);
if ('text/html' === $oPart->ContentType())
{
@@ -578,7 +564,7 @@ class Message implements \JsonSerializable
{
if ($oPart->IsFlowedFormat())
{
- $sText = \MailSo\Base\Utils::DecodeFlowedFormat($sText);
+ $sText = Utils::DecodeFlowedFormat($sText);
}
$aPlainParts[] = $sText;
@@ -586,14 +572,8 @@ class Message implements \JsonSerializable
}
}
- if (\count($aHtmlParts))
- {
- $this->sHtml = \implode('
', $aHtmlParts);
- }
- else
- {
- $this->sPlain = \trim(\implode("\n", $aPlainParts));
- }
+ $this->sHtml = \implode('
', $aHtmlParts);
+ $this->sPlain = \trim(\implode("\n", $aPlainParts));
$aMatch = array();
if (!$this->bPgpSigned && \preg_match('/-----BEGIN PGP SIGNATURE-----(.+)-----END PGP SIGNATURE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0]))
@@ -609,11 +589,11 @@ class Message implements \JsonSerializable
if ($oBodyStructure)
{
- $aAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
- if ($aAttachmentsParts && \count($aAttachmentsParts))
+ $gAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
+ if ($gAttachmentsParts->valid())
{
$this->oAttachments = new AttachmentCollection;
- foreach ($aAttachmentsParts as /* @var $oAttachmentItem \MailSo\Imap\BodyStructure */ $oAttachmentItem)
+ foreach ($gAttachmentsParts as /* @var $oAttachmentItem \MailSo\Imap\BodyStructure */ $oAttachmentItem)
{
$this->oAttachments->append(
Attachment::NewBodyStructureInstance($this->sFolder, $this->iUid, $oAttachmentItem)
@@ -631,7 +611,7 @@ class Message implements \JsonSerializable
'@Object' => 'Object/Message',
'Folder' => $this->sFolder,
'Uid' => $this->iUid,
- 'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->sSubject)),
+ 'Subject' => \trim(Utils::Utf8Clear($this->sSubject)),
'MessageId' => $this->sMessageId,
'Size' => $this->iSize,
'SpamScore' => $this->iSpamScore,
diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php
index e19544a31..9c3133eef 100644
--- a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php
+++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php
@@ -141,13 +141,6 @@ class Part
Enumerations\Header::CONTENT_TYPE))) : '';
}
- public function ContentTransferEncoding() : string
- {
- return ($this->Headers) ?
- \trim(\strtolower($this->Headers->ValueByName(
- Enumerations\Header::CONTENT_TRANSFER_ENCODING))) : '';
- }
-
public function ContentID() : string
{
return ($this->Headers) ? \trim($this->Headers->ValueByName(
@@ -169,7 +162,7 @@ class Part
Enumerations\Header::CONTENT_TYPE,
Enumerations\Parameter::FORMAT)));
- if ($bResult && \in_array(\strtolower($this->MailEncodingName()), array('base64', 'quoted-printable')))
+ if ($bResult && \in_array($this->MailEncodingName(), array('base64', 'quoted-printable')))
{
$bResult = false;
}
diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php
index 00e16e9fe..707400ac2 100644
--- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php
+++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php
@@ -223,14 +223,6 @@ trait Response
}
}
- $sPlain = '';
- $sHtml = \trim($mResponse->Html());
-
- if (!\strlen($sHtml))
- {
- $sPlain = \trim($mResponse->Plain());
- }
-
$mResult['DraftInfo'] = $mResponse->DraftInfo();
$mResult['InReplyTo'] = $mResponse->InReplyTo();
$mResult['UnsubsribeLinks'] = $mResponse->UnsubsribeLinks();
@@ -248,27 +240,25 @@ trait Response
};
}
+ $sHtml = $mResponse->Html();
$sHtml = \preg_replace_callback('/(
]*>)([\s\S\r\n\t]*?)(<\/pre>)/mi', function ($aMatches) {
return \preg_replace('/[\r\n]+/', '
', $aMatches[1].\trim($aMatches[2]).$aMatches[3]);
}, $sHtml);
-
$mResult['Html'] = \strlen($sHtml) ? \MailSo\Base\HtmlUtils::ClearHtml(
$sHtml, $bHasExternals, $aFoundCIDs, $aContentLocationUrls, $aFoundContentLocationUrls,
$fAdditionalExternalFilter, !!$this->Config()->Get('labs', 'try_to_detect_hidden_images', false)
) : '';
+ unset($sHtml);
$mResult['ExternalProxy'] = null !== $fAdditionalExternalFilter;
- $mResult['Plain'] = $sPlain;
-// $mResult['Plain'] = \strlen($sPlain) ? \MailSo\Base\HtmlUtils::ConvertPlainToHtml($sPlain) : '';
+ $mResult['Plain'] = $mResponse->Plain();
$mResult['isPgpSigned'] = $mResponse->isPgpSigned();
$mResult['isPgpEncrypted'] = $mResponse->isPgpEncrypted();
// $mResult['PgpSignature'] = $mResponse->PgpSignature();
// $mResult['PgpSignatureMicAlg'] = $mResponse->PgpSignatureMicAlg();
- unset($sHtml, $sPlain);
-
$mResult['HasExternals'] = $bHasExternals;
$mResult['HasInternals'] = \count($aFoundCIDs) || \count($aFoundContentLocationUrls);