mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-09-07 16:47:07 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39b451bb2b | |||
| 65afaf3f2b | |||
| 82f8514d89 | |||
| 440bc61237 | |||
| a96f0822e0 |
@@ -84,6 +84,7 @@ class EmailLexer extends AbstractLexer
|
|||||||
if (!$search->lookahead) {
|
if (!$search->lookahead) {
|
||||||
throw new \UnexpectedValueException($type . ' not found');
|
throw new \UnexpectedValueException($type . ' not found');
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,13 +117,13 @@ class EmailLexer extends AbstractLexer
|
|||||||
protected function getCatchablePatterns()
|
protected function getCatchablePatterns()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'[a-zA-Z_]+[4,6]?',
|
'[a-zA-Z_]+[46]?',
|
||||||
'[0-9]+',
|
'[0-9]+',
|
||||||
'\r\n',
|
'\r\n',
|
||||||
'::',
|
'::',
|
||||||
'\s+',
|
'\s+',
|
||||||
'[\x1-\x1F]+',
|
'[\x10-\x1F]+',
|
||||||
'.'
|
'.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ class EmailLexer extends AbstractLexer
|
|||||||
return $this->charValue[$value];
|
return $this->charValue[$value];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/[\x1-\x1F]+/', $value)) {
|
if (preg_match('/[\x10-\x1F]+/', $value)) {
|
||||||
return self::INVALID;
|
return self::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class EmailValidator
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dns = false;
|
$dns = true;
|
||||||
if ($checkDNS) {
|
if ($checkDNS) {
|
||||||
$dns = $this->checkDNS();
|
$dns = $this->checkDNS();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,12 +235,18 @@ class DomainPart extends Parser
|
|||||||
|
|
||||||
protected function checkDomainPartExceptions($prev)
|
protected function checkDomainPartExceptions($prev)
|
||||||
{
|
{
|
||||||
|
if ($this->lexer->token['type'] === EmailLexer::S_COMMA) {
|
||||||
|
throw new \InvalidArgumentException('ERR_COMMA_IN_DOMAIN');
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_AT) {
|
if ($this->lexer->token['type'] === EmailLexer::S_AT) {
|
||||||
throw new \InvalidArgumentException('ERR_CONSECUTIVEATS');
|
throw new \InvalidArgumentException('ERR_CONSECUTIVEATS');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) {
|
if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) {
|
||||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
|
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
|
||||||
throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND');
|
throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace Egulias\EmailValidator\Parser;
|
namespace Egulias\EmailValidator\Parser;
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\Parser\Parser;
|
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
|
||||||
|
|
||||||
@@ -11,7 +10,9 @@ class LocalPart extends Parser
|
|||||||
{
|
{
|
||||||
public function parse($localPart)
|
public function parse($localPart)
|
||||||
{
|
{
|
||||||
|
$parseDQuote = true;
|
||||||
$closingQuote = false;
|
$closingQuote = false;
|
||||||
|
|
||||||
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
|
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
|
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
|
||||||
@@ -19,6 +20,10 @@ class LocalPart extends Parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
$closingQuote = $this->checkDQUOTE($closingQuote);
|
$closingQuote = $this->checkDQUOTE($closingQuote);
|
||||||
|
if ($closingQuote && $parseDQuote) {
|
||||||
|
$this->parseDoubleQuote();
|
||||||
|
$parseDQuote = false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||||
$this->parseComments();
|
$this->parseComments();
|
||||||
@@ -26,20 +31,15 @@ class LocalPart extends Parser
|
|||||||
|
|
||||||
$this->checkConsecutiveDots();
|
$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');
|
throw new \InvalidArgumentException('ERR_DOT_END');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->warnEscaping();
|
$this->warnEscaping();
|
||||||
|
$this->isInvalidToken($this->lexer->token, $closingQuote);
|
||||||
if ($this->lexer->isNextTokenAny(
|
|
||||||
array(
|
|
||||||
EmailLexer::INVALID, EmailLexer::S_LOWERTHAN, EmailLexer::S_GREATERTHAN
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->isFWS()) {
|
if ($this->isFWS()) {
|
||||||
$this->parseFWS();
|
$this->parseFWS();
|
||||||
@@ -53,4 +53,42 @@ class LocalPart extends Parser
|
|||||||
$this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG;
|
$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()
|
protected function isFWS()
|
||||||
{
|
{
|
||||||
|
if ($this->escaped()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_SP ||
|
if ($this->lexer->token['type'] === EmailLexer::S_SP ||
|
||||||
$this->lexer->token['type'] === EmailLexer::S_HTAB ||
|
$this->lexer->token['type'] === EmailLexer::S_HTAB ||
|
||||||
$this->lexer->token['type'] === EmailLexer::S_CR ||
|
$this->lexer->token['type'] === EmailLexer::S_CR ||
|
||||||
@@ -114,6 +118,21 @@ abstract class Parser
|
|||||||
return false;
|
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()
|
protected function warnEscaping()
|
||||||
{
|
{
|
||||||
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
|
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']);
|
$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()
|
public function getTokens()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -34,18 +34,22 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('fabien_potencier@example.fr'),
|
array('fabien_potencier@example.fr'),
|
||||||
array('example@localhost'),
|
array('example@localhost'),
|
||||||
array('fab\'ien@symfony.com'),
|
array('fab\'ien@symfony.com'),
|
||||||
|
array('fab\ ien@symfony.com'),
|
||||||
array('example((example))@fakedfake.co.uk'),
|
array('example((example))@fakedfake.co.uk'),
|
||||||
array('example@faked(fake).co.uk'),
|
array('example@faked(fake).co.uk'),
|
||||||
array('fabien+@symfony.com'),
|
array('fabien+@symfony.com'),
|
||||||
array('инфо@письмо.рф'),
|
array('инфо@письмо.рф'),
|
||||||
|
array('"username"@example.com'),
|
||||||
|
array('"user,name"@example.com'),
|
||||||
|
array('"user name"@example.com'),
|
||||||
|
array('"user@name"@example.com'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getInvalidEmails
|
* @dataProvider getInvalidEmails
|
||||||
*/
|
*/
|
||||||
public function testAInvalidEmails($email)
|
public function testInvalidEmails($email)
|
||||||
{
|
{
|
||||||
$this->assertFalse($this->validator->isValid($email));
|
$this->assertFalse($this->validator->isValid($email));
|
||||||
}
|
}
|
||||||
@@ -65,6 +69,9 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('username@ example . com'),
|
array('username@ example . com'),
|
||||||
array('example@(fake).com'),
|
array('example@(fake).com'),
|
||||||
array('example@(fake.com'),
|
array('example@(fake.com'),
|
||||||
|
array('username@example,com'),
|
||||||
|
array('usern,ame@example.com'),
|
||||||
|
array('user[na]me@example.com'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,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@exa\rmple.co.uk"),
|
||||||
array(EmailValidator::ERR_CR_NO_LF, "example@[\r]"),
|
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, "exam\rple@example.co.uk"),
|
||||||
array(EmailValidator::ERR_CR_NO_LF, "\"\r\"@localhost"),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getInvalidEmailsWithWarnings
|
* @dataProvider getInvalidEmailsWithWarnings
|
||||||
*/
|
*/
|
||||||
public function testInvalidEmailsWithWarningsCheck($warnings, $email)
|
public function testValidEmailsWithWarningsCheck($warnings, $email)
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->validator->isValid($email, true));
|
$this->assertTrue($this->validator->isValid($email, true));
|
||||||
|
|
||||||
@@ -138,6 +144,13 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
),
|
),
|
||||||
"\"\t\"@example.co.uk"
|
"\"\t\"@example.co.uk"
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
EmailValidator::RFC5321_QUOTEDSTRING,
|
||||||
|
EmailValidator::CFWS_FWS,
|
||||||
|
),
|
||||||
|
"\"\r\"@example.co.uk"
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
EmailValidator::RFC5321_ADDRESSLITERAL,
|
EmailValidator::RFC5321_ADDRESSLITERAL,
|
||||||
|
|||||||
Reference in New Issue
Block a user