Viewing file: DomainPart.php (11.24 KB) -rwxrwxr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailValidator;
class DomainPart extends Parser { const DOMAIN_MAX_LENGTH = 254; protected $domainPart = '';
public function parse($domainPart) { $this->lexer->moveNext();
if ($this->lexer->token['type'] === EmailLexer::S_DOT) { throw new \InvalidArgumentException('ERR_DOT_START'); }
if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) { throw new \InvalidArgumentException('ERR_NODOMAIN'); } if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) { throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND'); }
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { $this->warnings[] = EmailValidator::DEPREC_COMMENT; $this->parseDomainComments(); }
$domain = $this->doParseDomainPart();
$prev = $this->lexer->getPrevious(); $length = strlen($domain);
if ($prev['type'] === EmailLexer::S_DOT) { throw new \InvalidArgumentException('ERR_DOT_END'); } if ($prev['type'] === EmailLexer::S_HYPHEN) { throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND'); } if ($length > self::DOMAIN_MAX_LENGTH) { $this->warnings[] = EmailValidator::RFC5322_DOMAIN_TOOLONG; } if ($prev['type'] === EmailLexer::S_CR) { throw new \InvalidArgumentException('ERR_FWS_CRLF_END'); } $this->domainPart = $domain; }
public function getDomainPart() { return $this->domainPart; }
public function checkIPV6Tag($addressLiteral, $maxGroups = 8) { $prev = $this->lexer->getPrevious(); if ($prev['type'] === EmailLexer::S_COLON) { $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONEND; }
$IPv6 = substr($addressLiteral, 5); //Daniel Marschall's new IPv6 testing strategy $matchesIP = explode(':', $IPv6); $groupCount = count($matchesIP); $colons = strpos($IPv6, '::');
if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { $this->warnings[] = EmailValidator::RFC5322_IPV6_BADCHAR; }
if ($colons === false) { // We need exactly the right number of groups if ($groupCount !== $maxGroups) { $this->warnings[] = EmailValidator::RFC5322_IPV6_GRPCOUNT; } return; }
if ($colons !== strrpos($IPv6, '::')) { $this->warnings[] = EmailValidator::RFC5322_IPV6_2X2XCOLON; return; }
if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { // RFC 4291 allows :: at the start or end of an address //with 7 other groups in addition ++$maxGroups; }
if ($groupCount > $maxGroups) { $this->warnings[] = EmailValidator::RFC5322_IPV6_MAXGRPS; } elseif ($groupCount === $maxGroups) { $this->warnings[] = EmailValidator::RFC5321_IPV6DEPRECATED; } }
protected function doParseDomainPart() { $domain = ''; $openedParenthesis = 0; $openBrackets = false; do { $prev = $this->lexer->getPrevious();
$this->checkNotAllowedChars($this->lexer->token);
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(); $this->checkDomainPartExceptions($prev);
if ($openBrackets = $this->hasBrackets($openBrackets)) { $this->parseDomainLiteral(); }
$this->checkLabelLength($prev);
if ($this->isFWS()) { $this->parseFWS(); }
$domain .= $this->lexer->token['value']; $this->lexer->moveNext(); } while ($this->lexer->token);
return $domain; }
private function checkNotAllowedChars($token) { $notAllowed = array(EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true); if (isset($notAllowed[$token['type']])) { throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED'); } }
protected function parseDomainLiteral() { if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT; } if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { $lexer = clone $this->lexer; $lexer->moveNext(); if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT; } }
return $this->doParseDomainLiteral(); }
protected function doParseDomainLiteral() { $IPv6TAG = false; $addressLiteral = ''; do { if ($this->lexer->token['type'] === EmailLexer::C_NUL) { throw new \InvalidArgumentException('ERR_EXPECTING_DTEXT'); }
if ($this->lexer->token['type'] === EmailLexer::INVALID || $this->lexer->token['type'] === EmailLexer::C_DEL || $this->lexer->token['type'] === EmailLexer::S_LF ) { $this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT; }
if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) { throw new \InvalidArgumentException('ERR_EXPECTING_DTEXT'); }
if ($this->lexer->isNextTokenAny( array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF) )) { $this->warnings[] = EmailValidator::CFWS_FWS; $this->parseFWS(); }
if ($this->lexer->isNextToken(EmailLexer::S_CR)) { throw new \InvalidArgumentException('ERR_CR_NO_LF'); } if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) { $this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT; $addressLiteral .= $this->lexer->token['value']; $this->lexer->moveNext(); $this->validateQuotedPair(); } if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) { $IPv6TAG = true; } if ($this->lexer->token['type'] === EmailLexer::S_CLOSEQBRACKET) { break; }
$addressLiteral .= $this->lexer->token['value'];
} while ($this->lexer->moveNext());
$addressLiteral = str_replace('[', '', $addressLiteral); $addressLiteral = $this->checkIPV4Tag($addressLiteral);
if (false === $addressLiteral) { return $addressLiteral; }
if (!$IPv6TAG) { $this->warnings[] = EmailValidator::RFC5322_DOMAINLITERAL; return $addressLiteral; }
$this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL;
$this->checkIPV6Tag($addressLiteral);
return $addressLiteral; }
protected function checkIPV4Tag($addressLiteral) { $matchesIP = array();
// Extract IPv4 part from the end of the address-literal (if there is one) if (preg_match( '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', $addressLiteral, $matchesIP ) > 0 ) { $index = strrpos($addressLiteral, $matchesIP[0]); if ($index === 0) { $this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL; return false; } // Convert IPv4 part to IPv6 format for further testing $addressLiteral = substr($addressLiteral, 0, $index) . '0:0'; }
return $addressLiteral; }
protected function checkDomainPartExceptions($prev) { $invalidDomainTokens = array( EmailLexer::S_DQUOTE => true, EmailLexer::S_SEMICOLON => true, EmailLexer::S_GREATERTHAN => true, EmailLexer::S_LOWERTHAN => true, );
if (isset($invalidDomainTokens[$this->lexer->token['type']])) { throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); }
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'); }
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::GENERIC)) { throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); } }
protected function hasBrackets($openBrackets) { if ($this->lexer->token['type'] === EmailLexer::S_CLOSEBRACKET && !$openBrackets) { throw new \InvalidArgumentException('ERR_EXPECTING_OPENBRACKET'); }
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) { return false; }
try { $this->lexer->find(EmailLexer::S_CLOSEBRACKET); } catch (\RuntimeException $e) { throw new \InvalidArgumentException('ERR_EXPECTING_DOMLIT_CLOSE'); }
return true; }
protected function checkLabelLength($prev) { if ($this->lexer->token['type'] === EmailLexer::S_DOT && $prev['type'] === EmailLexer::GENERIC && strlen($prev['value']) > 63 ) { $this->warnings[] = EmailValidator::RFC5322_LABEL_TOOLONG; } }
protected function parseDomainComments() { $this->isUnclosedComment(); while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { $this->warnEscaping(); $this->lexer->moveNext(); }
$this->lexer->moveNext(); if ($this->lexer->isNextToken(EmailLexer::S_DOT)) { throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); } } }
|