Bugfix: SieveClient quoted string parsing

Redesign NetClient::getNextBuffer() to return string
This commit is contained in:
the-djmaze 2022-12-19 10:39:50 +01:00
parent 2a86ab5753
commit 8b65b6ee7c
4 changed files with 94 additions and 152 deletions

View file

@ -87,39 +87,31 @@ trait ResponseParser
$sAtomBuilder = $bTreatAsAtom ? '' : null; $sAtomBuilder = $bTreatAsAtom ? '' : null;
$aList = array(); $aList = array();
if ($bRoot) if ($bRoot) {
{
$aList =& $oImapResponse->ResponseList; $aList =& $oImapResponse->ResponseList;
} }
while (true) $sResponseBuffer = '';
{
if ($this->bNeedNext) while (true) {
{ if ($this->bNeedNext) {
/**
* $this->sResponseBuffer is a single fgets() that ends with \r\n
*/
$iPos = 0; $iPos = 0;
$this->getNextBuffer(); $sResponseBuffer = $this->getNextBuffer();
$this->iResponseBufParsedPos = $iPos; $this->iResponseBufParsedPos = $iPos;
$this->bNeedNext = false; $this->bNeedNext = false;
} }
$sChar = null; $sChar = null;
if ($bIsGotoDefault) if ($bIsGotoDefault) {
{
$bIsGotoDefault = false; $bIsGotoDefault = false;
} } else {
else $iBufferEndIndex = \strlen($sResponseBuffer) - 3;
{
$iBufferEndIndex = \strlen($this->sResponseBuffer) - 3;
if ($iPos > $iBufferEndIndex) if ($iPos > $iBufferEndIndex) {
{
break; break;
} }
$sChar = $this->sResponseBuffer[$iPos]; $sChar = $sResponseBuffer[$iPos];
} }
switch ($sChar) switch ($sChar)
@ -167,13 +159,13 @@ trait ResponseParser
continue 2; continue 2;
case '~': // literal8 case '~': // literal8
if ('{' !== $this->sResponseBuffer[++$iPos]) { if ('{' !== $sResponseBuffer[++$iPos]) {
break; break;
} }
case '{': case '{':
$iLength = \strspn($this->sResponseBuffer, '0123456789', $iPos + 1); $iLength = \strspn($sResponseBuffer, '0123456789', $iPos + 1);
if ($iLength && "}\r\n" === \substr($this->sResponseBuffer, $iPos + 1 + $iLength, 3)) { if ($iLength && "}\r\n" === \substr($sResponseBuffer, $iPos + 1 + $iLength, 3)) {
$iLiteralLen = (int) \substr($this->sResponseBuffer, $iPos + 1, $iLength); $iLiteralLen = (int) \substr($sResponseBuffer, $iPos + 1, $iLength);
$iPos += 4 + $iLength; $iPos += 4 + $iLength;
if ($this->partialResponseLiteralCallbacks($sParentToken, $sPreviousAtomUpperCase, $iLiteralLen)) { if ($this->partialResponseLiteralCallbacks($sParentToken, $sPreviousAtomUpperCase, $iLiteralLen)) {
@ -217,13 +209,13 @@ trait ResponseParser
$iPos = $iBufferEndIndex; $iPos = $iBufferEndIndex;
break; break;
} }
$iLength = \strcspn($this->sResponseBuffer, "\r\n\\\"", $iOffset); $iLength = \strcspn($sResponseBuffer, "\r\n\\\"", $iOffset);
$sSpecial = $this->sResponseBuffer[$iOffset + $iLength]; $sSpecial = $sResponseBuffer[$iOffset + $iLength];
switch ($sSpecial) switch ($sSpecial)
{ {
case '\\': case '\\':
// Is escaped character \ or "? // Is escaped character \ or "?
if (!\in_array($this->sResponseBuffer[$iOffset + $iLength + 1], ['\\','"'])) { if (!\in_array($sResponseBuffer[$iOffset + $iLength + 1], ['\\','"'])) {
// No, not allowed in quoted string // No, not allowed in quoted string
break 2; break 2;
} }
@ -232,9 +224,9 @@ trait ResponseParser
case '"': case '"':
if ($bTreatAsAtom) { if ($bTreatAsAtom) {
$sAtomBuilder .= \stripslashes(\substr($this->sResponseBuffer, $iPos, $iOffset + $iLength - $iPos + 1)); $sAtomBuilder .= \stripslashes(\substr($sResponseBuffer, $iPos, $iOffset + $iLength - $iPos + 1));
} else { } else {
$aList[] = \stripslashes(\substr($this->sResponseBuffer, $iPos + 1, $iOffset + $iLength - $iPos - 1)); $aList[] = \stripslashes(\substr($sResponseBuffer, $iPos + 1, $iOffset + $iLength - $iPos - 1));
} }
$iPos = $iOffset + $iLength + 1; $iPos = $iOffset + $iLength + 1;
break 2; break 2;
@ -242,7 +234,7 @@ trait ResponseParser
default: default:
case "\r": case "\r":
case "\n": case "\n":
\SnappyMail\Log::notice('IMAP', 'Invalid char in quoted string: "' . \substr($this->sResponseBuffer, $iPos, $iOffset + $iLength - $iPos) . '"'); \SnappyMail\Log::notice('IMAP', 'Invalid char in quoted string: "' . \substr($sResponseBuffer, $iPos, $iOffset + $iLength - $iPos) . '"');
// Not allowed in quoted string // Not allowed in quoted string
break 2; break 2;
} }
@ -253,29 +245,26 @@ trait ResponseParser
default: default:
$iCharBlockStartPos = $iPos; $iCharBlockStartPos = $iPos;
if ($bRoot && $oImapResponse->IsStatusResponse) if ($bRoot && $oImapResponse->IsStatusResponse) {
{
$iPos = $iBufferEndIndex; $iPos = $iBufferEndIndex;
if ($iPos > $iCharBlockStartPos) { if ($iPos > $iCharBlockStartPos) {
$iCharBlockStartPos += \strspn($this->sResponseBuffer, ' ', $iCharBlockStartPos, $iPos - $iCharBlockStartPos); $iCharBlockStartPos += \strspn($sResponseBuffer, ' ', $iCharBlockStartPos, $iPos - $iCharBlockStartPos);
} }
} }
while ($iPos <= $iBufferEndIndex) while ($iPos <= $iBufferEndIndex) {
{ $sCharDef = $sResponseBuffer[$iPos];
$sCharDef = $this->sResponseBuffer[$iPos];
switch (true) switch (true)
{ {
case $bRoot && ('[' === $sCharDef || ']' === $sCharDef) && static::skipSquareBracketParse($oImapResponse): case $bRoot && ('[' === $sCharDef || ']' === $sCharDef) && static::skipSquareBracketParse($oImapResponse):
++$iPos; ++$iPos;
break; break;
case '[' === $sCharDef: case '[' === $sCharDef:
if (null === $sAtomBuilder) if (null === $sAtomBuilder) {
{
$sAtomBuilder = ''; $sAtomBuilder = '';
} }
$sAtomBuilder .= \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos + 1); $sAtomBuilder .= \substr($sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos + 1);
$this->iResponseBufParsedPos = ++$iPos; $this->iResponseBufParsedPos = ++$iPos;
@ -301,33 +290,25 @@ trait ResponseParser
} }
} }
if ($iPos > $iCharBlockStartPos || null !== $sAtomBuilder) if ($iPos > $iCharBlockStartPos || null !== $sAtomBuilder) {
{ $sLastCharBlock = \substr($sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos);
$sLastCharBlock = \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos); if (null === $sAtomBuilder) {
if (null === $sAtomBuilder)
{
$aList[] = 'NIL' === $sLastCharBlock ? null : $sLastCharBlock; $aList[] = 'NIL' === $sLastCharBlock ? null : $sLastCharBlock;
$sPreviousAtomUpperCase = \strtoupper($sLastCharBlock); $sPreviousAtomUpperCase = \strtoupper($sLastCharBlock);
} } else {
else
{
$sAtomBuilder .= $sLastCharBlock; $sAtomBuilder .= $sLastCharBlock;
if (!$bTreatAsAtom) if (!$bTreatAsAtom) {
{
$aList[] = $sAtomBuilder; $aList[] = $sAtomBuilder;
$sPreviousAtomUpperCase = \strtoupper($sAtomBuilder); $sPreviousAtomUpperCase = \strtoupper($sAtomBuilder);
$sAtomBuilder = null; $sAtomBuilder = null;
} }
} }
if ($bRoot) if ($bRoot) {
{ if (!isset($oImapResponse->Tag) && 1 === \count($aList)) {
if (!isset($oImapResponse->Tag) && 1 === \count($aList))
{
$oImapResponse->setTag($aList[0]); $oImapResponse->setTag($aList[0]);
if ($this->getCurrentTag() === $oImapResponse->Tag) if ($this->getCurrentTag() === $oImapResponse->Tag) {
{
$oImapResponse->ResponseType = ResponseType::TAGGED; $oImapResponse->ResponseType = ResponseType::TAGGED;
} }
} }
@ -372,8 +353,7 @@ trait ResponseParser
$iLiteralSize = \strlen($sLiteral); $iLiteralSize = \strlen($sLiteral);
if ($iLiteralLen !== $iLiteralSize) { if ($iLiteralLen !== $iLiteralSize) {
$this->writeLog('Literal stream read warning "read '.$iLiteralSize.' of '. $this->writeLog('Literal stream read warning "read '.$iLiteralSize.' of '.$iLiteralLen.'" bytes', \LOG_WARNING);
$iLiteralLen.'" bytes', \LOG_WARNING);
} }
return $sLiteral; return $sLiteral;
} }

View file

@ -28,8 +28,6 @@ abstract class NetClient
private string $sConnectedHost = ''; private string $sConnectedHost = '';
protected string $sResponseBuffer = '';
private bool $ssl = false; private bool $ssl = false;
private int $iConnectTimeOut = 10; private int $iConnectTimeOut = 10;
@ -260,25 +258,25 @@ abstract class NetClient
* @throws \MailSo\Net\Exceptions\SocketConnectionDoesNotAvailableException * @throws \MailSo\Net\Exceptions\SocketConnectionDoesNotAvailableException
* @throws \MailSo\Net\Exceptions\SocketReadException * @throws \MailSo\Net\Exceptions\SocketReadException
*/ */
protected function getNextBuffer(?int $iReadLen = null) : void protected function getNextBuffer(?int $iReadLen = null) : ?string
{ {
if (null === $iReadLen) { if (null === $iReadLen) {
$this->sResponseBuffer = \fgets($this->rConnect); $sResponseBuffer = \fgets($this->rConnect);
} else { } else {
$this->sResponseBuffer = ''; $sResponseBuffer = '';
$iRead = $iReadLen; $iRead = $iReadLen;
while (0 < $iRead) { while (0 < $iRead) {
$sAddRead = \fread($this->rConnect, $iRead); $sAddRead = \fread($this->rConnect, $iRead);
if (false === $sAddRead) { if (false === $sAddRead) {
$this->sResponseBuffer = false; $sResponseBuffer = false;
break; break;
} }
$this->sResponseBuffer .= $sAddRead; $sResponseBuffer .= $sAddRead;
$iRead -= \strlen($sAddRead); $iRead -= \strlen($sAddRead);
} }
} }
if (false === $this->sResponseBuffer) { if (false === $sResponseBuffer) {
$this->IsConnected(true); $this->IsConnected(true);
$this->bUnreadBuffer = true; $this->bUnreadBuffer = true;
$aSocketStatus = \stream_get_meta_data($this->rConnect); $aSocketStatus = \stream_get_meta_data($this->rConnect);
@ -288,16 +286,19 @@ abstract class NetClient
$this->writeLog('Stream Meta: '.\print_r($aSocketStatus, true), \LOG_ERR); $this->writeLog('Stream Meta: '.\print_r($aSocketStatus, true), \LOG_ERR);
$this->writeLogException(new Exceptions\SocketReadException, \LOG_ERR); $this->writeLogException(new Exceptions\SocketReadException, \LOG_ERR);
} }
} else { return null;
$iReadBytes = \strlen($this->sResponseBuffer);
// $iReadLen && $this->writeLog('Received '.$iReadBytes.'/'.$iReadLen.' bytes.');
$iLimit = 5000; // 5KB
if ($iLimit < $iReadBytes) {
$this->writeLogWithCrlf('[cutted:'.$iReadBytes.'] < '.\substr($this->sResponseBuffer, 0, $iLimit).'...');
} else {
$this->writeLogWithCrlf('< '.$this->sResponseBuffer);
}
} }
$iReadBytes = \strlen($sResponseBuffer);
// $iReadLen && $this->writeLog('Received '.$iReadBytes.'/'.$iReadLen.' bytes.');
$iLimit = 5000; // 5KB
if ($iLimit < $iReadBytes) {
$this->writeLogWithCrlf('[cutted:'.$iReadBytes.'] < '.\substr($sResponseBuffer, 0, $iLimit).'...');
} else {
$this->writeLogWithCrlf('< '.$sResponseBuffer);
}
return $sResponseBuffer;
} }
abstract function getLogName() : string; abstract function getLogName() : string;

View file

@ -32,21 +32,11 @@ class SieveClient extends \MailSo\Net\NetClient
return isset($this->aCapa[\strtoupper($sCapa)]); return isset($this->aCapa[\strtoupper($sCapa)]);
} }
public function IsModuleSupported(string $sModule) : bool
{
return $this->hasCapability('SIEVE') && \in_array(\strtolower(\trim($sModule)), $this->aModules);
}
public function Modules() : array public function Modules() : array
{ {
return $this->aModules; return $this->aModules;
} }
public function IsAuthSupported(string $sAuth) : bool
{
return $this->hasCapability('SASL') && \in_array(\strtoupper($sAuth), $this->aAuth);
}
/** /**
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \MailSo\RuntimeException * @throws \MailSo\RuntimeException
@ -58,7 +48,6 @@ class SieveClient extends \MailSo\Net\NetClient
parent::Connect($oSettings); parent::Connect($oSettings);
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$this->parseStartupResponse($aResponse); $this->parseStartupResponse($aResponse);
if (ConnectionSecurityType::STARTTLS === $this->Settings->type if (ConnectionSecurityType::STARTTLS === $this->Settings->type
@ -73,7 +62,6 @@ class SieveClient extends \MailSo\Net\NetClient
$this->sendRequestWithCheck('STARTTLS'); $this->sendRequestWithCheck('STARTTLS');
$this->EnableCrypto(); $this->EnableCrypto();
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$this->parseStartupResponse($aResponse); $this->parseStartupResponse($aResponse);
} else { } else {
$this->writeLogException( $this->writeLogException(
@ -98,10 +86,12 @@ class SieveClient extends \MailSo\Net\NetClient
} }
$type = ''; $type = '';
foreach ($oSettings->SASLMechanisms as $sasl_type) { if ($this->hasCapability('SASL')) {
if ($this->IsAuthSupported($sasl_type) && \SnappyMail\SASL::isSupported($sasl_type)) { foreach ($oSettings->SASLMechanisms as $sasl_type) {
$type = $sasl_type; if (\in_array(\strtoupper($sasl_type), $this->aAuth) && \SnappyMail\SASL::isSupported($sasl_type)) {
break; $type = $sasl_type;
break;
}
} }
} }
if (!$type) { if (!$type) {
@ -143,7 +133,6 @@ class SieveClient extends \MailSo\Net\NetClient
} }
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$this->parseStartupResponse($aResponse); $this->parseStartupResponse($aResponse);
$bAuth = true; $bAuth = true;
} }
@ -160,7 +149,6 @@ class SieveClient extends \MailSo\Net\NetClient
$this->sendRaw($sPassword); $this->sendRaw($sPassword);
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$this->parseStartupResponse($aResponse); $this->parseStartupResponse($aResponse);
$bAuth = true; $bAuth = true;
} }
@ -201,12 +189,11 @@ class SieveClient extends \MailSo\Net\NetClient
{ {
$this->sendRequest('LISTSCRIPTS'); $this->sendRequest('LISTSCRIPTS');
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$aResult = array(); $aResult = array();
foreach ($aResponse as $sLine) { foreach ($aResponse as $sLine) {
$aTokens = $this->parseLine($sLine); $aTokens = $this->parseLine($sLine);
if ($aTokens) { if ($aTokens) {
$aResult[$aTokens[0]] = 'ACTIVE' === substr($sLine, -6); $aResult[$aTokens[0]] = 'ACTIVE' === \substr($sLine, -6);
} }
} }
@ -222,7 +209,6 @@ class SieveClient extends \MailSo\Net\NetClient
{ {
$this->sendRequest('CAPABILITY'); $this->sendRequest('CAPABILITY');
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$this->parseStartupResponse($aResponse); $this->parseStartupResponse($aResponse);
return $this->aCapa; return $this->aCapa;
@ -247,9 +233,9 @@ class SieveClient extends \MailSo\Net\NetClient
*/ */
public function GetScript(string $sScriptName) : string public function GetScript(string $sScriptName) : string
{ {
$sScriptName = \addcslashes($sScriptName, '"\\');
$this->sendRequest('GETSCRIPT "'.$sScriptName.'"'); $this->sendRequest('GETSCRIPT "'.$sScriptName.'"');
$aResponse = $this->parseResponse(); $aResponse = $this->parseResponse();
$this->validateResponse($aResponse);
$sScript = ''; $sScript = '';
if (\count($aResponse)) { if (\count($aResponse)) {
@ -274,6 +260,7 @@ class SieveClient extends \MailSo\Net\NetClient
*/ */
public function PutScript(string $sScriptName, string $sScriptSource) : self public function PutScript(string $sScriptName, string $sScriptSource) : self
{ {
$sScriptName = \addcslashes($sScriptName, '"\\');
$sScriptSource = \preg_replace('/\r?\n/', "\r\n", $sScriptSource); $sScriptSource = \preg_replace('/\r?\n/', "\r\n", $sScriptSource);
$this->sendRequest('PUTSCRIPT "'.$sScriptName.'" {'.\strlen($sScriptSource).'+}'); $this->sendRequest('PUTSCRIPT "'.$sScriptName.'" {'.\strlen($sScriptSource).'+}');
$this->sendRequestWithCheck($sScriptSource); $this->sendRequestWithCheck($sScriptSource);
@ -302,6 +289,7 @@ class SieveClient extends \MailSo\Net\NetClient
*/ */
public function SetActiveScript(string $sScriptName) : self public function SetActiveScript(string $sScriptName) : self
{ {
$sScriptName = \addcslashes($sScriptName, '"\\');
$this->sendRequestWithCheck('SETACTIVE "'.$sScriptName.'"'); $this->sendRequestWithCheck('SETACTIVE "'.$sScriptName.'"');
return $this; return $this;
@ -314,6 +302,7 @@ class SieveClient extends \MailSo\Net\NetClient
*/ */
public function DeleteScript(string $sScriptName) : self public function DeleteScript(string $sScriptName) : self
{ {
$sScriptName = \addcslashes($sScriptName, '"\\');
$this->sendRequestWithCheck('DELETESCRIPT "'.$sScriptName.'"'); $this->sendRequestWithCheck('DELETESCRIPT "'.$sScriptName.'"');
return $this; return $this;
@ -326,6 +315,8 @@ class SieveClient extends \MailSo\Net\NetClient
*/ */
public function RenameScript(string $sOldName, string $sNewName) : self public function RenameScript(string $sOldName, string $sNewName) : self
{ {
$sOldName = \addcslashes($sOldName, '"\\');
$sNewName = \addcslashes($sNewName, '"\\');
$this->sendRequestWithCheck('RENAMESCRIPT "'.$sOldName.'" "'.$sNewName.'"'); $this->sendRequestWithCheck('RENAMESCRIPT "'.$sOldName.'" "'.$sNewName.'"');
return $this; return $this;
@ -333,26 +324,13 @@ class SieveClient extends \MailSo\Net\NetClient
private function parseLine(string $sLine) : ?array private function parseLine(string $sLine) : ?array
{ {
if (false === $sLine || null === $sLine || \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) { if (!\in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) {
return null; $aResult = array();
} if (\preg_match_all('/(?:(?:"((?:\\\\"|[^"])*)"))/', $sLine, $aResult)) {
return \array_map('stripcslashes', $aResult[1]);
$iStart = -1;
$iIndex = 0;
$aResult = array();
for ($iPos = 0; $iPos < \strlen($sLine); ++$iPos) {
if ('"' === $sLine[$iPos] && '\\' !== $sLine[$iPos]) {
if (-1 === $iStart) {
$iStart = $iPos;
} else {
$aResult[$iIndex++] = \substr($sLine, $iStart + 1, $iPos - $iStart - 1);
$iStart = -1;
}
} }
} }
return null;
return isset($aResult[0]) ? $aResult : null;
} }
/** /**
@ -364,10 +342,7 @@ class SieveClient extends \MailSo\Net\NetClient
{ {
foreach ($aResponse as $sLine) { foreach ($aResponse as $sLine) {
$aTokens = $this->parseLine($sLine); $aTokens = $this->parseLine($sLine);
if (empty($aTokens[0]) || \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) {
if (false === $aTokens || !isset($aTokens[0]) ||
\in_array(\substr($sLine, 0, 2), array('OK', 'NO')))
{
continue; continue;
} }
@ -411,7 +386,7 @@ class SieveClient extends \MailSo\Net\NetClient
private function sendRequestWithCheck(string $sRequest) : void private function sendRequestWithCheck(string $sRequest) : void
{ {
$this->sendRequest($sRequest); $this->sendRequest($sRequest);
$this->validateResponse($this->parseResponse()); $this->parseResponse();
} }
private function parseResponse() : array private function parseResponse() : array
@ -419,22 +394,21 @@ class SieveClient extends \MailSo\Net\NetClient
$aResult = array(); $aResult = array();
do do
{ {
$this->getNextBuffer(); $sResponseBuffer = $this->getNextBuffer();
$sLine = $this->sResponseBuffer; if (null === $sResponseBuffer) {
if (false === $sLine) {
break; break;
} }
$bEnd = \in_array(\substr($sLine, 0, 2), array('OK', 'NO')); $bEnd = \in_array(\substr($sResponseBuffer, 0, 2), array('OK', 'NO'));
// convertEndOfLine // convertEndOfLine
$sLine = \trim($sLine); $sLine = \trim($sResponseBuffer);
if ('}' === \substr($sLine, -1)) { if ('}' === \substr($sLine, -1)) {
$iPos = \strrpos($sLine, '{'); $iPos = \strrpos($sLine, '{');
if (false !== $iPos) { if (false !== $iPos) {
$iLen = \intval(\substr($sLine, $iPos + 1, -1)); $iLen = \intval(\substr($sLine, $iPos + 1, -1));
if (0 < $iLen) { if (0 < $iLen) {
$this->getNextBuffer($iLen); $sResponseBuffer = $this->getNextBuffer($iLen);
if (\strlen($this->sResponseBuffer) === $iLen) { if (\strlen($sResponseBuffer) === $iLen) {
$sLine = \trim(\substr_replace($sLine, $this->sResponseBuffer, $iPos)); $sLine = \trim(\substr_replace($sLine, $sResponseBuffer, $iPos));
} }
} }
} }
@ -446,17 +420,11 @@ class SieveClient extends \MailSo\Net\NetClient
} }
while (true); while (true);
return $aResult; if (!$aResult || 'OK' !== \substr($aResult[\array_key_last($aResult)], 0, 2)) {
} $this->writeLogException(new \MailSo\Sieve\Exceptions\NegativeResponseException($aResult), \LOG_WARNING);
/**
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
*/
private function validateResponse(array $aResponse)
{
if (!$aResponse || 'OK' !== \substr($aResponse[\count($aResponse) - 1], 0, 2)) {
$this->writeLogException(new \MailSo\Sieve\Exceptions\NegativeResponseException($aResponse), \LOG_WARNING);
} }
return $aResult;
} }
public function getLogName() : string public function getLogName() : string

View file

@ -41,11 +41,6 @@ class SmtpClient extends \MailSo\Net\NetClient
return \in_array(\strtoupper($sCapa), $this->aCapa); return \in_array(\strtoupper($sCapa), $this->aCapa);
} }
public function IsAuthSupported(string $sAuth) : bool
{
return \in_array(\strtoupper($sAuth), $this->aAuthTypes);
}
public function maxSize() : int public function maxSize() : int
{ {
return $this->iSizeCapaValue; return $this->iSizeCapaValue;
@ -118,7 +113,7 @@ class SmtpClient extends \MailSo\Net\NetClient
$type = ''; $type = '';
foreach ($oSettings->SASLMechanisms as $sasl_type) { foreach ($oSettings->SASLMechanisms as $sasl_type) {
if ($this->IsAuthSupported($sasl_type) && \SnappyMail\SASL::isSupported($sasl_type)) { if (\in_array(\strtoupper($sasl_type), $this->aAuthTypes) && \SnappyMail\SASL::isSupported($sasl_type)) {
$type = $sasl_type; $type = $sasl_type;
break; break;
} }
@ -486,18 +481,16 @@ class SmtpClient extends \MailSo\Net\NetClient
*/ */
private function validateResponse($mExpectCode, string $sErrorPrefix = '') : void private function validateResponse($mExpectCode, string $sErrorPrefix = '') : void
{ {
if (!\is_array($mExpectCode)) { $mExpectCode = \is_array($mExpectCode)
$mExpectCode = array((int) $mExpectCode); ? \array_map('intval', $mExpectCode)
} else { : array((int) $mExpectCode);
$mExpectCode = \array_map('intval', $mExpectCode);
}
$aParts = array('', '', ''); $aParts = array('', '', '');
$this->aResults = array(); $this->aResults = array();
do do
{ {
$this->getNextBuffer(); $sResponse = $this->getNextBuffer();
$aParts = \preg_split('/([\s\-]+)/', $this->sResponseBuffer, 2, PREG_SPLIT_DELIM_CAPTURE); $aParts = \preg_split('/([\s\-]+)/', $sResponse, 2, PREG_SPLIT_DELIM_CAPTURE);
if (3 === \count($aParts) && \is_numeric($aParts[0])) { if (3 === \count($aParts) && \is_numeric($aParts[0])) {
if ('-' !== \substr($aParts[1], 0, 1) && !\in_array((int) $aParts[0], $mExpectCode)) { if ('-' !== \substr($aParts[1], 0, 1) && !\in_array((int) $aParts[0], $mExpectCode)) {
@ -505,17 +498,17 @@ class SmtpClient extends \MailSo\Net\NetClient
new Exceptions\NegativeResponseException($this->aResults, new Exceptions\NegativeResponseException($this->aResults,
('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim(
(\count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). (\count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : '').
$this->sResponseBuffer)), \LOG_ERR); $sResponse)), \LOG_ERR);
} }
} else { } else {
$this->writeLogException( $this->writeLogException(
new Exceptions\ResponseException($this->aResults, new Exceptions\ResponseException($this->aResults,
('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim(
(\count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). (\count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : '').
$this->sResponseBuffer)), \LOG_ERR); $sResponse)), \LOG_ERR);
} }
$this->aResults[] = $this->sResponseBuffer; $this->aResults[] = $sResponse;
} }
while ('-' === \substr($aParts[1], 0, 1)); while ('-' === \substr($aParts[1], 0, 1));
} }