Compare commits

...

5 Commits

Author SHA1 Message Date
Eduardo Gulias Davis 39b451bb2b #19 and #10 - Improvement of QuotedPart parsing 2014-09-02 00:35:48 +02:00
Eduardo Gulias Davis 65afaf3f2b Change DNS validation to default to true instead of false by @brianfreytag 2014-08-22 01:08:16 +02:00
Eduardo Gulias Davis 82f8514d89 COMMA is not allowed in domain part 2014-08-22 01:05:58 +02:00
Eduardo Gulias Davis 440bc61237 Merge pull request #17 from brianfreytag/remove_dns_requirement
Change DNS validation to default to true instead of false
2014-08-21 23:47:24 +02:00
Brian Freytag a96f0822e0 Change DNS validation to default to true instead of false
There shouldn't be a dependency on the checkDNS() method in order to
validate strict = true. We should only be concerned about the DNS if the
library is specifically told to check DNS, so we default the DNS
variable to true and then set it to false if checkDNS is set to true and
checkDNS() returns false.
2014-08-20 15:05:30 -04:00
7 changed files with 105 additions and 20 deletions
+5 -4
View File
@@ -84,6 +84,7 @@ class EmailLexer extends AbstractLexer
if (!$search->lookahead) {
throw new \UnexpectedValueException($type . ' not found');
}
return true;
}
/**
@@ -116,13 +117,13 @@ class EmailLexer extends AbstractLexer
protected function getCatchablePatterns()
{
return array(
'[a-zA-Z_]+[4,6]?',
'[a-zA-Z_]+[46]?',
'[0-9]+',
'\r\n',
'::',
'\s+',
'[\x1-\x1F]+',
'.'
'[\x10-\x1F]+',
'.',
);
}
@@ -149,7 +150,7 @@ class EmailLexer extends AbstractLexer
return $this->charValue[$value];
}
if (preg_match('/[\x1-\x1F]+/', $value)) {
if (preg_match('/[\x10-\x1F]+/', $value)) {
return self::INVALID;
}
@@ -86,7 +86,7 @@ class EmailValidator
return false;
}
$dns = false;
$dns = true;
if ($checkDNS) {
$dns = $this->checkDNS();
}
@@ -235,12 +235,18 @@ class DomainPart extends Parser
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) {
throw new \InvalidArgumentException('ERR_CONSECUTIVEATS');
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) {
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND');
}
+49 -11
View File
@@ -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,18 +34,22 @@ 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'),
);
}
/**
* @dataProvider getInvalidEmails
*/
public function testAInvalidEmails($email)
public function testInvalidEmails($email)
{
$this->assertFalse($this->validator->isValid($email));
}
@@ -65,6 +69,9 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
array('username@ example . 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@[\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));
@@ -138,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,