mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-08-29 19:49:34 +00:00
Quoted string parsing returns only Results and avoids exceptions
This commit is contained in:
@@ -3,21 +3,22 @@ namespace Egulias\EmailValidator\Parser;
|
||||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\Parser\Parser;
|
||||
use Egulias\EmailValidator\Result\ValidEmail;
|
||||
use Egulias\EmailValidator\Result\InvalidEmail;
|
||||
use Egulias\EmailValidator\Warning\CFWSWithFWS;
|
||||
use Egulias\EmailValidator\Warning\QuotedString;
|
||||
use Egulias\EmailValidator\Exception\ExpectingAT;
|
||||
use Egulias\EmailValidator\Exception\ExpectingATEXT;
|
||||
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
|
||||
use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;
|
||||
use Egulias\EmailValidator\Result\Reason\UnclosedQuotedString;
|
||||
use Egulias\EmailValidator\Result\Result;
|
||||
|
||||
class DoubleQuote extends Parser
|
||||
{
|
||||
public function parse($qouted)
|
||||
{
|
||||
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
|
||||
return true;
|
||||
}
|
||||
if(!$this->checkDQUOTE(false)) return false;
|
||||
$parseAgain = true;
|
||||
|
||||
$validQuotedString = $this->checkDQUOTE();
|
||||
if(!$validQuotedString->isValid()) return $validQuotedString;
|
||||
|
||||
$special = array(
|
||||
EmailLexer::S_CR => true,
|
||||
EmailLexer::S_HTAB => true,
|
||||
@@ -35,7 +36,6 @@ class DoubleQuote extends Parser
|
||||
$this->lexer->moveNext();
|
||||
|
||||
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) {
|
||||
$parseAgain = false;
|
||||
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
|
||||
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
|
||||
$setSpecialsWarning = false;
|
||||
@@ -47,54 +47,41 @@ class DoubleQuote extends Parser
|
||||
$this->lexer->moveNext();
|
||||
|
||||
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
|
||||
throw new ExpectingATEXT();
|
||||
return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->token['value']);
|
||||
}
|
||||
}
|
||||
|
||||
$prev = $this->lexer->getPrevious();
|
||||
|
||||
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
|
||||
if (!$this->checkDQUOTE(false)) {
|
||||
throw new UnclosedQuotedString();
|
||||
}
|
||||
$validQuotedString = $this->checkDQUOTE();
|
||||
if(!$validQuotedString->isValid()) return $validQuotedString;
|
||||
}
|
||||
|
||||
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
|
||||
throw new ExpectingAT();
|
||||
return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->token['value']);
|
||||
}
|
||||
|
||||
return $parseAgain;
|
||||
return new ValidEmail();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasClosingQuote
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkDQUOTE($hasClosingQuote) : bool
|
||||
protected function checkDQUOTE() : Result
|
||||
{
|
||||
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
|
||||
return $hasClosingQuote;
|
||||
}
|
||||
if ($hasClosingQuote) {
|
||||
return $hasClosingQuote;
|
||||
}
|
||||
$previous = $this->lexer->getPrevious();
|
||||
|
||||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
|
||||
//https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit
|
||||
//return new InvalidEmail(new ReasonExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->token['value']);
|
||||
throw new ExpectingATEXT();
|
||||
$description = 'https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit';
|
||||
return new InvalidEmail(new ExpectingATEXT($description), $this->lexer->token['value']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->lexer->find(EmailLexer::S_DQUOTE);
|
||||
$hasClosingQuote = true;
|
||||
} catch (\Exception $e) {
|
||||
throw new UnclosedQuotedString();
|
||||
return new InvalidEmail(new UnclosedQuotedString(), $this->lexer->token['value']);
|
||||
}
|
||||
$this->warnings[QuotedString::CODE] = new QuotedString($previous['value'], $this->lexer->token['value']);
|
||||
|
||||
return $hasClosingQuote;
|
||||
return new ValidEmail();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,8 +26,15 @@ class LocalPart extends Parser
|
||||
return new InvalidEmail(new DotAtStart(), $this->lexer->token['value']);
|
||||
}
|
||||
|
||||
if ($parseDQuote) {
|
||||
$parseDQuote = $this->parseDoubleQuote();
|
||||
//if ($parseDQuote) {
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_DQUOTE) {
|
||||
$dquoteParsingResult = $this->parseDoubleQuote();
|
||||
$parseDQuote = !$dquoteParsingResult->isValid();
|
||||
|
||||
//Invalid double quote parsing
|
||||
if($parseDQuote) {
|
||||
return $dquoteParsingResult;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
@@ -74,7 +81,7 @@ class LocalPart extends Parser
|
||||
return $this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type'];
|
||||
}
|
||||
|
||||
protected function parseDoubleQuote() : bool
|
||||
protected function parseDoubleQuote() : Result
|
||||
{
|
||||
$dquoteParser = new DoubleQuote($this->lexer);
|
||||
$parseAgain = $dquoteParser->parse("remove useless arg");
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Egulias\EmailValidator\Result\Reason;
|
||||
|
||||
class UnclosedQuotedString implements Reason
|
||||
{
|
||||
public function code() : int
|
||||
{
|
||||
return 145;
|
||||
}
|
||||
|
||||
public function description() : string
|
||||
{
|
||||
return "Unclosed quoted string";
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ use Egulias\EmailValidator\Exception\UnopenedComment;
|
||||
use Egulias\EmailValidator\Result\Reason\NoLocalPart;
|
||||
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
|
||||
use Egulias\EmailValidator\Result\Reason\DotAtStart as ReasonDotAtStart;
|
||||
use Egulias\EmailValidator\Result\Reason\ExpectingATEXT as ReasonExpectingATEXT;
|
||||
use Egulias\EmailValidator\Result\Reason\UnclosedQuotedString as ReasonUnclosedQuotedString;
|
||||
|
||||
class RFCValidationTest extends TestCase
|
||||
{
|
||||
@@ -198,8 +200,13 @@ class RFCValidationTest extends TestCase
|
||||
[new DotAtEnd(), 'example@localhost.'],
|
||||
[new DotAtEnd(), 'example.@example.co.uk'],
|
||||
[new UnclosedComment(), '(example@localhost'],
|
||||
[new UnclosedQuotedString(), '"example@localhost'],
|
||||
[new ExpectingATEXT(), 'exa"mple@localhost'],
|
||||
[new InvalidEmail(new ReasonUnclosedQuotedString(), '"'), '"example@localhost'],
|
||||
[
|
||||
new InvalidEmail(
|
||||
new ReasonExpectingATEXT('https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit'),
|
||||
'"'),
|
||||
'exa"mple@localhost'
|
||||
],
|
||||
[new UnclosedComment(), '(example@localhost'],
|
||||
[new UnopenedComment(), 'comment)example@localhost'],
|
||||
[new UnopenedComment(), 'example(comment))@localhost'],
|
||||
|
||||
Reference in New Issue
Block a user