mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-08-24 12:38:16 +00:00
@@ -84,6 +84,7 @@ class EmailLexer extends AbstractLexer
|
||||
if (!$search->lookahead) {
|
||||
throw new \UnexpectedValueException($type . ' not found');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Egulias\EmailValidator\Parser;
|
||||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\Parser\Parser;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
|
||||
|
||||
@@ -11,7 +10,9 @@ class LocalPart extends Parser
|
||||
{
|
||||
public function parse($localPart)
|
||||
{
|
||||
$parseDQuote = true;
|
||||
$closingQuote = false;
|
||||
|
||||
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
|
||||
@@ -19,6 +20,10 @@ class LocalPart extends Parser
|
||||
}
|
||||
|
||||
$closingQuote = $this->checkDQUOTE($closingQuote);
|
||||
if ($closingQuote && $parseDQuote) {
|
||||
$this->parseDoubleQuote();
|
||||
$parseDQuote = false;
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||
$this->parseComments();
|
||||
@@ -26,20 +31,15 @@ class LocalPart extends Parser
|
||||
|
||||
$this->checkConsecutiveDots();
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_AT)) {
|
||||
if (
|
||||
$this->lexer->token['type'] === EmailLexer::S_DOT &&
|
||||
$this->lexer->isNextToken(EmailLexer::S_AT)
|
||||
) {
|
||||
throw new \InvalidArgumentException('ERR_DOT_END');
|
||||
}
|
||||
|
||||
$this->warnEscaping();
|
||||
|
||||
if ($this->lexer->isNextTokenAny(
|
||||
array(
|
||||
EmailLexer::INVALID, EmailLexer::S_LOWERTHAN, EmailLexer::S_GREATERTHAN
|
||||
)
|
||||
)
|
||||
) {
|
||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||
}
|
||||
$this->isInvalidToken($this->lexer->token, $closingQuote);
|
||||
|
||||
if ($this->isFWS()) {
|
||||
$this->parseFWS();
|
||||
@@ -53,4 +53,42 @@ class LocalPart extends Parser
|
||||
$this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG;
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseDoubleQuote()
|
||||
{
|
||||
$special = array (
|
||||
EmailLexer::S_CR => true,
|
||||
EmailLexer::S_HTAB => true,
|
||||
EmailLexer::S_LF => true
|
||||
);
|
||||
$setSpecialsWarning = true;
|
||||
|
||||
$this->lexer->moveNext();
|
||||
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
|
||||
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
|
||||
$this->warnings[] = EmailValidator::CFWS_FWS;
|
||||
$setSpecialsWarning = false;
|
||||
}
|
||||
$this->lexer->moveNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function isInvalidToken($token, $closingQuote)
|
||||
{
|
||||
$forbidden = array(
|
||||
EmailLexer::S_COMMA,
|
||||
EmailLexer::S_CLOSEBRACKET,
|
||||
EmailLexer::S_OPENBRACKET,
|
||||
EmailLexer::S_GREATERTHAN,
|
||||
EmailLexer::S_LOWERTHAN,
|
||||
EmailLexer::S_COLON,
|
||||
EmailLexer::S_SEMICOLON,
|
||||
EmailLexer::INVALID
|
||||
);
|
||||
|
||||
if (in_array($token['type'], $forbidden) && !$closingQuote) {
|
||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,10 @@ abstract class Parser
|
||||
|
||||
protected function isFWS()
|
||||
{
|
||||
if ($this->escaped()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->lexer->token['type'] === EmailLexer::S_SP ||
|
||||
$this->lexer->token['type'] === EmailLexer::S_HTAB ||
|
||||
$this->lexer->token['type'] === EmailLexer::S_CR ||
|
||||
@@ -114,6 +118,21 @@ abstract class Parser
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function escaped()
|
||||
{
|
||||
$previous = $this->lexer->getPrevious();
|
||||
|
||||
if ($previous['type'] === EmailLexer::S_BACKSLASH
|
||||
&&
|
||||
($this->lexer->token['type'] === EmailLexer::S_SP ||
|
||||
$this->lexer->token['type'] === EmailLexer::S_HTAB)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function warnEscaping()
|
||||
{
|
||||
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
|
||||
|
||||
@@ -36,6 +36,14 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(EmailLexer::S_HTAB, $lexer->token['type']);
|
||||
}
|
||||
|
||||
public function testLexerSearchToken()
|
||||
{
|
||||
$lexer = new EmailLexer();
|
||||
$lexer->setInput("foo\tbar");
|
||||
$lexer->moveNext();
|
||||
$this->assertTrue($lexer->find(EmailLexer::S_HTAB));
|
||||
}
|
||||
|
||||
public function getTokens()
|
||||
{
|
||||
return array(
|
||||
|
||||
@@ -34,11 +34,15 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
array('fabien_potencier@example.fr'),
|
||||
array('example@localhost'),
|
||||
array('fab\'ien@symfony.com'),
|
||||
array('fab\ ien@symfony.com'),
|
||||
array('example((example))@fakedfake.co.uk'),
|
||||
array('example@faked(fake).co.uk'),
|
||||
array('fabien+@symfony.com'),
|
||||
array('инфо@письмо.рф'),
|
||||
|
||||
array('"username"@example.com'),
|
||||
array('"user,name"@example.com'),
|
||||
array('"user name"@example.com'),
|
||||
array('"user@name"@example.com'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,6 +70,8 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
array('example@(fake).com'),
|
||||
array('example@(fake.com'),
|
||||
array('username@example,com'),
|
||||
array('usern,ame@example.com'),
|
||||
array('user[na]me@example.com'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -105,14 +111,13 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
array(EmailValidator::ERR_CR_NO_LF, "example@exa\rmple.co.uk"),
|
||||
array(EmailValidator::ERR_CR_NO_LF, "example@[\r]"),
|
||||
array(EmailValidator::ERR_CR_NO_LF, "exam\rple@example.co.uk"),
|
||||
array(EmailValidator::ERR_CR_NO_LF, "\"\r\"@localhost"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidEmailsWithWarnings
|
||||
*/
|
||||
public function testInvalidEmailsWithWarningsCheck($warnings, $email)
|
||||
public function testValidEmailsWithWarningsCheck($warnings, $email)
|
||||
{
|
||||
$this->assertTrue($this->validator->isValid($email, true));
|
||||
|
||||
@@ -139,6 +144,13 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
),
|
||||
"\"\t\"@example.co.uk"
|
||||
),
|
||||
array(
|
||||
array(
|
||||
EmailValidator::RFC5321_QUOTEDSTRING,
|
||||
EmailValidator::CFWS_FWS,
|
||||
),
|
||||
"\"\r\"@example.co.uk"
|
||||
),
|
||||
array(
|
||||
array(
|
||||
EmailValidator::RFC5321_ADDRESSLITERAL,
|
||||
|
||||
Reference in New Issue
Block a user