From 3184f22d6cff732a34d1655d13e6b85a8e88d6aa Mon Sep 17 00:00:00 2001 From: djmaze Date: Fri, 29 Oct 2021 11:51:56 +0200 Subject: [PATCH] Prevent double foreach in \MailSo\Imap\ResponseCollection::getFoldersResult() --- .../app/libraries/MailSo/Imap/Folder.php | 46 ++++++--------- .../app/libraries/MailSo/Imap/ImapClient.php | 6 +- .../MailSo/Imap/ResponseCollection.php | 56 +++++++++---------- 3 files changed, 47 insertions(+), 61 deletions(-) diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php index 1748ca58a..229dbc719 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php @@ -48,41 +48,31 @@ class Folder /** * @throws \MailSo\Base\Exceptions\InvalidArgumentException */ - function __construct(string $sFullNameRaw, string $sDelimiter = '.', array $aFlags = array()) + function __construct(string $sFullNameRaw, string $sDelimiter = null, array $aFlags = array()) { - $sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? '' : $sDelimiter; - if (empty($sDelimiter)) - { - $sDelimiter = '.'; // default delimiter - } - - if (1 < \strlen($sDelimiter) || 0 === \strlen($sFullNameRaw)) - { + if (!\strlen($sFullNameRaw)) { throw new \MailSo\Base\Exceptions\InvalidArgumentException; } - $this->sFullNameRaw = $sFullNameRaw; - $this->sDelimiter = $sDelimiter; + + $this->setDelimiter($sDelimiter); + $this->setFlags($aFlags); + } + + public function setFlags(array $aFlags) : void + { $this->aFlagsLowerCase = \array_map('strtolower', $aFlags); + } - $this->sFullNameRaw = 'INBOX'.$this->sDelimiter === \substr(\strtoupper($this->sFullNameRaw), 0, 5 + \strlen($this->sDelimiter)) ? - 'INBOX'.\substr($this->sFullNameRaw, 5) : $this->sFullNameRaw; - - if ($this->IsInbox()) - { - $this->sFullNameRaw = 'INBOX'; - } - - $this->sNameRaw = $this->sFullNameRaw; - if (0 < \strlen($this->sDelimiter)) - { + public function setDelimiter(?string $sDelimiter) : void + { + $sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? null : $sDelimiter; + $this->sDelimiter = $sDelimiter; + if ($sDelimiter) { $aNames = \explode($this->sDelimiter, $this->sFullNameRaw); - if (false !== \array_search('', $aNames)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException; - } - $this->sNameRaw = \end($aNames); + } else { + $this->sNameRaw = $this->sFullNameRaw; } } @@ -96,7 +86,7 @@ class Folder return $this->sFullNameRaw; } - public function Delimiter() : string + public function Delimiter() : ?string { return $this->sDelimiter; } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php index ed2667a08..253f0aeee 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php @@ -469,17 +469,13 @@ class ImapClient extends \MailSo\Net\NetClient $aReturnParams[] = 'STATUS'; $aReturnParams[] = $aL; } - else - { - $bUseListStatus = false; - } if ($aReturnParams) { $aParameters[] = 'RETURN'; $aParameters[] = $aReturnParams; } - $aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd, $bUseListStatus); + $aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd); // RFC 5464 if (!$bIsSubscribeList && $this->IsSupported('METADATA')) { diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php index 3b5788b8e..4ec7fc9e1 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php @@ -119,7 +119,7 @@ class ResponseCollection extends \MailSo\Base\Collection { $aReturn = array(); foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && 4 === \count($oResponse->ResponseList) && 'METADATA' === $oResponse->ResponseList[1] && \is_array($oResponse->ResponseList[3])) @@ -136,17 +136,24 @@ class ResponseCollection extends \MailSo\Base\Collection return $aReturn; } - public function getFoldersResult(string $sStatus, bool $bUseListStatus = false) : array + public function getFoldersResult(string $sStatus) : array { $aReturn = array(); $sDelimiter = ''; $bInbox = false; - foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && - $sStatus === $oResponse->StatusOrIndex && 5 <= count($oResponse->ResponseList)) - { + if (Enumerations\ResponseType::UNTAGGED !== $oResponse->ResponseType) { + continue; + } + if ('STATUS' === $oResponse->StatusOrIndex && isset($oResponse->ResponseList[2])) { + $sFullNameRaw = $oResponse->ResponseList[2]; + if (!isset($aReturn[$sFullNameRaw])) { + $aReturn[$sFullNameRaw] = new Folder($sFullNameRaw); + } + $aReturn[$sFullNameRaw]->setStatusFromResponse($oResponse); + } + else if ($sStatus === $oResponse->StatusOrIndex && 5 <= count($oResponse->ResponseList)) { try { /** @@ -169,14 +176,21 @@ class ResponseCollection extends \MailSo\Base\Collection * $oResponse->ResponseList[3] = Delimiter * $oResponse->ResponseList[4] = FullNameRaw */ - $oFolder = new Folder($sFullNameRaw, - $oResponse->ResponseList[3], $oResponse->ResponseList[2]); + if (!isset($aReturn[$sFullNameRaw])) { + $oFolder = new Folder($sFullNameRaw, + $oResponse->ResponseList[3], $oResponse->ResponseList[2]); + $aReturn[$sFullNameRaw] = $oFolder; + } else { + $oFolder = $aReturn[$sFullNameRaw]; + $oFolder->setDelimiter($oResponse->ResponseList[3]); + $oFolder->setFlags($oResponse->ResponseList[2]); + } if ($oFolder->IsInbox()) { $bInbox = true; } - if (empty($sDelimiter)) { + if (!$sDelimiter) { $sDelimiter = $oFolder->Delimiter(); } @@ -197,24 +211,10 @@ class ResponseCollection extends \MailSo\Base\Collection } } - if (!$bInbox && !empty($sDelimiter) && !isset($aReturn['INBOX'])) { + if (!$bInbox && !isset($aReturn['INBOX'])) { $aReturn['INBOX'] = new Folder('INBOX', $sDelimiter); } - if ($bUseListStatus) { - foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && - 'STATUS' === $oResponse->StatusOrIndex && - isset($oResponse->ResponseList[2])) - { - $sFolderNameRaw = $oResponse->ResponseList[2]; - if (isset($aReturn[$sFolderNameRaw])) { - $aReturn[$sFolderNameRaw]->setStatusFromResponse($oResponse); - } - } - } - } - return $aReturn; } @@ -223,7 +223,7 @@ class ResponseCollection extends \MailSo\Base\Collection $aReturn = array(); foreach ($this as $oResponse) { $iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0; - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && ($sStatus === $oResponse->StatusOrIndex || $iOffset) && \is_array($oResponse->ResponseList) && 2 < count($oResponse->ResponseList)) @@ -261,7 +261,7 @@ class ResponseCollection extends \MailSo\Base\Collection $aReturn = array(); foreach ($this as $oResponse) { $iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0; - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && ($sStatus === $oResponse->StatusOrIndex || $iOffset) && \is_array($oResponse->ResponseList) && 2 < \count($oResponse->ResponseList)) @@ -285,7 +285,7 @@ class ResponseCollection extends \MailSo\Base\Collection { $oResult = new FolderInformation($sFolderName, $bIsWritable); foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { if (!$oResult->setStatusFromResponse($oResponse)) { // OK untagged responses if (\is_array($oResponse->OptionalResponse)) { @@ -372,7 +372,7 @@ class ResponseCollection extends \MailSo\Base\Collection { $aResult = array(); foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && ('ESEARCH' === $oResponse->StatusOrIndex || 'ESORT' === $oResponse->StatusOrIndex) && \is_array($oResponse->ResponseList) && isset($oResponse->ResponseList[2], $oResponse->ResponseList[2][0], $oResponse->ResponseList[2][1])