mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-08-28 02:58:29 +00:00
Merge pull request #81 from whyte624/master
#80 validate number of closing parenthesis
This commit is contained in:
@@ -33,6 +33,7 @@ class EmailValidator
|
||||
const ERR_FWS_CRLF_END = 149;
|
||||
const ERR_CR_NO_LF = 150;
|
||||
const ERR_DEPREC_REACHED = 151;
|
||||
const ERR_UNOPENEDCOMMENT = 152;
|
||||
const RFC5321_TLD = 9;
|
||||
const RFC5321_TLDNUMERIC = 10;
|
||||
const RFC5321_QUOTEDSTRING = 11;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
namespace Egulias\EmailValidator\Parser;
|
||||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\Parser\Parser;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
|
||||
class DomainPart extends Parser
|
||||
@@ -103,8 +102,8 @@ class DomainPart extends Parser
|
||||
protected function doParseDomainPart()
|
||||
{
|
||||
$domain = '';
|
||||
$openedParenthesis = 0;
|
||||
do {
|
||||
|
||||
$prev = $this->lexer->getPrevious();
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_SLASH) {
|
||||
@@ -113,7 +112,19 @@ class DomainPart extends Parser
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
$this->parseComments();
|
||||
$openedParenthesis += $this->getOpenedParenthesis();
|
||||
$this->lexer->moveNext();
|
||||
$tmpPrev = $this->lexer->getPrevious();
|
||||
if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||
$openedParenthesis--;
|
||||
}
|
||||
}
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||
if ($openedParenthesis === 0) {
|
||||
throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT');
|
||||
} else {
|
||||
$openedParenthesis--;
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkConsecutiveDots();
|
||||
@@ -180,7 +191,7 @@ class DomainPart extends Parser
|
||||
}
|
||||
|
||||
if ($this->lexer->isNextToken(EmailLexer::S_CR)) {
|
||||
throw new \InvalidArgumentException("ERR_CR_NO_LF");
|
||||
throw new \InvalidArgumentException('ERR_CR_NO_LF');
|
||||
}
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
|
||||
$this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT;
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Egulias\EmailValidator\Parser;
|
||||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
use \InvalidArgumentException;
|
||||
|
||||
class LocalPart extends Parser
|
||||
{
|
||||
@@ -12,9 +11,9 @@ class LocalPart extends Parser
|
||||
{
|
||||
$parseDQuote = true;
|
||||
$closingQuote = false;
|
||||
$openedParenthesis = 0;
|
||||
|
||||
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
|
||||
throw new \InvalidArgumentException('ERR_DOT_START');
|
||||
}
|
||||
@@ -26,12 +25,19 @@ class LocalPart extends Parser
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
$this->parseComments();
|
||||
$openedParenthesis += $this->getOpenedParenthesis();
|
||||
}
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||
if ($openedParenthesis === 0) {
|
||||
throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT');
|
||||
} else {
|
||||
$openedParenthesis--;
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkConsecutiveDots();
|
||||
|
||||
if (
|
||||
$this->lexer->token['type'] === EmailLexer::S_DOT &&
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
|
||||
$this->lexer->isNextToken(EmailLexer::S_AT)
|
||||
) {
|
||||
throw new \InvalidArgumentException('ERR_DOT_END');
|
||||
@@ -82,7 +88,7 @@ class LocalPart extends Parser
|
||||
$this->lexer->moveNext();
|
||||
|
||||
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
|
||||
throw new InvalidArgumentException("ERR_EXPECTED_ATEXT");
|
||||
throw new \InvalidArgumentException('ERR_EXPECTED_ATEXT');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,12 +96,12 @@ class LocalPart extends Parser
|
||||
|
||||
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
|
||||
if (!$this->checkDQUOTE(false)) {
|
||||
throw new \InvalidArgumentException("ERR_UNCLOSED_DQUOTE");
|
||||
throw new \InvalidArgumentException('ERR_UNCLOSED_DQUOTE');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
|
||||
throw new \InvalidArgumentException("ERR_EXPECED_AT");
|
||||
throw new \InvalidArgumentException('ERR_EXPECED_AT');
|
||||
}
|
||||
|
||||
return $parseAgain;
|
||||
|
||||
@@ -9,6 +9,7 @@ abstract class Parser
|
||||
{
|
||||
protected $warnings = array();
|
||||
protected $lexer;
|
||||
protected $openedParenthesis = 0;
|
||||
|
||||
public function __construct(EmailLexer $lexer)
|
||||
{
|
||||
@@ -20,7 +21,13 @@ abstract class Parser
|
||||
return $this->warnings;
|
||||
}
|
||||
|
||||
abstract function parse($str);
|
||||
abstract public function parse($str);
|
||||
|
||||
/** @return int */
|
||||
public function getOpenedParenthesis()
|
||||
{
|
||||
return $this->openedParenthesis;
|
||||
}
|
||||
|
||||
/**
|
||||
* validateQuotedPair
|
||||
@@ -35,15 +42,15 @@ abstract class Parser
|
||||
$this->warnings[] = EmailValidator::DEPREC_QP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the the comment
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function parseComments()
|
||||
{
|
||||
$this->openedParenthesis = 1;
|
||||
$this->isUnclosedComment();
|
||||
$this->warnings[] = EmailValidator::CFWS_COMMENT;
|
||||
while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
|
||||
if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) {
|
||||
$this->openedParenthesis++;
|
||||
}
|
||||
$this->warnEscaping();
|
||||
$this->lexer->moveNext();
|
||||
}
|
||||
@@ -75,11 +82,11 @@ abstract class Parser
|
||||
$this->checkCRLFInFWS();
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_CR) {
|
||||
throw new \InvalidArgumentException("ERR_CR_NO_LF");
|
||||
throw new \InvalidArgumentException('ERR_CR_NO_LF');
|
||||
}
|
||||
|
||||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) {
|
||||
throw new \InvalidArgumentException("ERR_ATEXT_AFTER_CFWS");
|
||||
throw new \InvalidArgumentException('ERR_ATEXT_AFTER_CFWS');
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) {
|
||||
@@ -160,7 +167,7 @@ abstract class Parser
|
||||
return $hasClosingQuote;
|
||||
}
|
||||
$previous = $this->lexer->getPrevious();
|
||||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
|
||||
if ($previous['type'] === EmailLexer::GENERIC && $this->lexer->isNextToken(EmailLexer::GENERIC)) {
|
||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||
}
|
||||
|
||||
@@ -181,10 +188,10 @@ abstract class Parser
|
||||
return;
|
||||
}
|
||||
if ($this->lexer->isNextToken(EmailLexer::CRLF)) {
|
||||
throw new \InvalidArgumentException("ERR_FWS_CRLF_X2");
|
||||
throw new \InvalidArgumentException('ERR_FWS_CRLF_X2');
|
||||
}
|
||||
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
|
||||
throw new \InvalidArgumentException("ERR_FWS_CRLF_END");
|
||||
throw new \InvalidArgumentException('ERR_FWS_CRLF_END');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,11 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
array(EmailValidator::ERR_DOT_END, 'example@localhost.'),
|
||||
array(EmailValidator::ERR_DOT_END, 'example.@example.co.uk'),
|
||||
array(EmailValidator::ERR_UNCLOSEDCOMMENT, '(example@localhost'),
|
||||
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'comment)example@localhost'),
|
||||
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example(comment))@localhost'),
|
||||
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@comment)localhost'),
|
||||
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@localhost(comment))'),
|
||||
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@(comment))example.com'),
|
||||
array(EmailValidator::ERR_UNCLOSEDQUOTEDSTR, '"example@localhost'),
|
||||
array(EmailValidator::ERR_EXPECTING_ATEXT, 'exa"mple@localhost'),
|
||||
//This was the original. But atext is not allowed after \n
|
||||
|
||||
Reference in New Issue
Block a user