[ Index ]

MailPress 7.2

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-includes/composer/vendor/egulias/email-validator/EmailValidator/Parser/ -> DomainPart.php (source)

   1  <?php
   2  
   3  namespace Egulias\EmailValidator\Parser;
   4  
   5  use Egulias\EmailValidator\EmailLexer;
   6  use Egulias\EmailValidator\Exception\CharNotAllowed;
   7  use Egulias\EmailValidator\Exception\CommaInDomain;
   8  use Egulias\EmailValidator\Exception\ConsecutiveAt;
   9  use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
  10  use Egulias\EmailValidator\Exception\CRNoLF;
  11  use Egulias\EmailValidator\Exception\DomainHyphened;
  12  use Egulias\EmailValidator\Exception\DotAtEnd;
  13  use Egulias\EmailValidator\Exception\DotAtStart;
  14  use Egulias\EmailValidator\Exception\ExpectingATEXT;
  15  use Egulias\EmailValidator\Exception\ExpectingDomainLiteralClose;
  16  use Egulias\EmailValidator\Exception\ExpectingDTEXT;
  17  use Egulias\EmailValidator\Exception\NoDomainPart;
  18  use Egulias\EmailValidator\Exception\UnopenedComment;
  19  use Egulias\EmailValidator\Warning\AddressLiteral;
  20  use Egulias\EmailValidator\Warning\CFWSWithFWS;
  21  use Egulias\EmailValidator\Warning\DeprecatedComment;
  22  use Egulias\EmailValidator\Warning\DomainLiteral;
  23  use Egulias\EmailValidator\Warning\DomainTooLong;
  24  use Egulias\EmailValidator\Warning\IPV6BadChar;
  25  use Egulias\EmailValidator\Warning\IPV6ColonEnd;
  26  use Egulias\EmailValidator\Warning\IPV6ColonStart;
  27  use Egulias\EmailValidator\Warning\IPV6Deprecated;
  28  use Egulias\EmailValidator\Warning\IPV6DoubleColon;
  29  use Egulias\EmailValidator\Warning\IPV6GroupCount;
  30  use Egulias\EmailValidator\Warning\IPV6MaxGroups;
  31  use Egulias\EmailValidator\Warning\LabelTooLong;
  32  use Egulias\EmailValidator\Warning\ObsoleteDTEXT;
  33  use Egulias\EmailValidator\Warning\TLD;
  34  
  35  class DomainPart extends Parser
  36  {
  37      const DOMAIN_MAX_LENGTH = 254;
  38      protected $domainPart = '';
  39  
  40      public function parse($domainPart)
  41      {
  42          $this->lexer->moveNext();
  43  
  44          if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
  45              throw new DotAtStart();
  46          }
  47  
  48          if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) {
  49              throw new NoDomainPart();
  50          }
  51          if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
  52              throw new DomainHyphened();
  53          }
  54  
  55          if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
  56              $this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
  57              $this->parseDomainComments();
  58          }
  59  
  60          $domain = $this->doParseDomainPart();
  61  
  62          $prev = $this->lexer->getPrevious();
  63          $length = strlen($domain);
  64  
  65          if ($prev['type'] === EmailLexer::S_DOT) {
  66              throw new DotAtEnd();
  67          }
  68          if ($prev['type'] === EmailLexer::S_HYPHEN) {
  69              throw new DomainHyphened();
  70          }
  71          if ($length > self::DOMAIN_MAX_LENGTH) {
  72              $this->warnings[DomainTooLong::CODE] = new DomainTooLong();
  73          }
  74          if ($prev['type'] === EmailLexer::S_CR) {
  75              throw new CRLFAtTheEnd();
  76          }
  77          $this->domainPart = $domain;
  78      }
  79  
  80      public function getDomainPart()
  81      {
  82          return $this->domainPart;
  83      }
  84  
  85      public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
  86      {
  87          $prev = $this->lexer->getPrevious();
  88          if ($prev['type'] === EmailLexer::S_COLON) {
  89              $this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd();
  90          }
  91  
  92          $IPv6       = substr($addressLiteral, 5);
  93          //Daniel Marschall's new IPv6 testing strategy
  94          $matchesIP  = explode(':', $IPv6);
  95          $groupCount = count($matchesIP);
  96          $colons     = strpos($IPv6, '::');
  97  
  98          if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) {
  99              $this->warnings[IPV6BadChar::CODE] = new IPV6BadChar();
 100          }
 101  
 102          if ($colons === false) {
 103              // We need exactly the right number of groups
 104              if ($groupCount !== $maxGroups) {
 105                  $this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount();
 106              }
 107              return;
 108          }
 109  
 110          if ($colons !== strrpos($IPv6, '::')) {
 111              $this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon();
 112              return;
 113          }
 114  
 115          if ($colons === 0 || $colons === (strlen($IPv6) - 2)) {
 116              // RFC 4291 allows :: at the start or end of an address
 117              //with 7 other groups in addition
 118              ++$maxGroups;
 119          }
 120  
 121          if ($groupCount > $maxGroups) {
 122              $this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups();
 123          } elseif ($groupCount === $maxGroups) {
 124              $this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated();
 125          }
 126      }
 127  
 128      protected function doParseDomainPart()
 129      {
 130          $domain = '';
 131          $openedParenthesis = 0;
 132          do {
 133              $prev = $this->lexer->getPrevious();
 134  
 135              $this->checkNotAllowedChars($this->lexer->token);
 136  
 137              if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
 138                  $this->parseComments();
 139                  $openedParenthesis += $this->getOpenedParenthesis();
 140                  $this->lexer->moveNext();
 141                  $tmpPrev = $this->lexer->getPrevious();
 142                  if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
 143                      $openedParenthesis--;
 144                  }
 145              }
 146              if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
 147                  if ($openedParenthesis === 0) {
 148                      throw new UnopenedComment();
 149                  } else {
 150                      $openedParenthesis--;
 151                  }
 152              }
 153  
 154              $this->checkConsecutiveDots();
 155              $this->checkDomainPartExceptions($prev);
 156  
 157              if ($this->hasBrackets()) {
 158                  $this->parseDomainLiteral();
 159              }
 160  
 161              $this->checkLabelLength($prev);
 162  
 163              if ($this->isFWS()) {
 164                  $this->parseFWS();
 165              }
 166  
 167              $domain .= $this->lexer->token['value'];
 168              $this->lexer->moveNext();
 169          } while ($this->lexer->token);
 170  
 171          return $domain;
 172      }
 173  
 174      private function checkNotAllowedChars($token)
 175      {
 176          $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
 177          if (isset($notAllowed[$token['type']])) {
 178              throw new CharNotAllowed();
 179          }
 180      }
 181  
 182      protected function parseDomainLiteral()
 183      {
 184          if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
 185              $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
 186          }
 187          if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) {
 188              $lexer = clone $this->lexer;
 189              $lexer->moveNext();
 190              if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) {
 191                  $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
 192              }
 193          }
 194  
 195          return $this->doParseDomainLiteral();
 196      }
 197  
 198      protected function doParseDomainLiteral()
 199      {
 200          $IPv6TAG = false;
 201          $addressLiteral = '';
 202          do {
 203              if ($this->lexer->token['type'] === EmailLexer::C_NUL) {
 204                  throw new ExpectingDTEXT();
 205              }
 206  
 207              if ($this->lexer->token['type'] === EmailLexer::INVALID ||
 208                  $this->lexer->token['type'] === EmailLexer::C_DEL   ||
 209                  $this->lexer->token['type'] === EmailLexer::S_LF
 210              ) {
 211                  $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
 212              }
 213  
 214              if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) {
 215                  throw new ExpectingDTEXT();
 216              }
 217  
 218              if ($this->lexer->isNextTokenAny(
 219                  array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF)
 220              )) {
 221                  $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
 222                  $this->parseFWS();
 223              }
 224  
 225              if ($this->lexer->isNextToken(EmailLexer::S_CR)) {
 226                  throw new CRNoLF();
 227              }
 228  
 229              if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
 230                  $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
 231                  $addressLiteral .= $this->lexer->token['value'];
 232                  $this->lexer->moveNext();
 233                  $this->validateQuotedPair();
 234              }
 235              if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) {
 236                  $IPv6TAG = true;
 237              }
 238              if ($this->lexer->token['type'] === EmailLexer::S_CLOSEQBRACKET) {
 239                  break;
 240              }
 241  
 242              $addressLiteral .= $this->lexer->token['value'];
 243  
 244          } while ($this->lexer->moveNext());
 245  
 246          $addressLiteral = str_replace('[', '', $addressLiteral);
 247          $addressLiteral = $this->checkIPV4Tag($addressLiteral);
 248  
 249          if (false === $addressLiteral) {
 250              return $addressLiteral;
 251          }
 252  
 253          if (!$IPv6TAG) {
 254              $this->warnings[DomainLiteral::CODE] = new DomainLiteral();
 255              return $addressLiteral;
 256          }
 257  
 258          $this->warnings[AddressLiteral::CODE] = new AddressLiteral();
 259  
 260          $this->checkIPV6Tag($addressLiteral);
 261  
 262          return $addressLiteral;
 263      }
 264  
 265      protected function checkIPV4Tag($addressLiteral)
 266      {
 267          $matchesIP  = array();
 268  
 269          // Extract IPv4 part from the end of the address-literal (if there is one)
 270          if (preg_match(
 271              '/\\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]?)$/',
 272              $addressLiteral,
 273              $matchesIP
 274          ) > 0
 275          ) {
 276              $index = strrpos($addressLiteral, $matchesIP[0]);
 277              if ($index === 0) {
 278                  $this->warnings[AddressLiteral::CODE] = new AddressLiteral();
 279                  return false;
 280              }
 281              // Convert IPv4 part to IPv6 format for further testing
 282              $addressLiteral = substr($addressLiteral, 0, $index) . '0:0';
 283          }
 284  
 285          return $addressLiteral;
 286      }
 287  
 288      protected function checkDomainPartExceptions($prev)
 289      {
 290          $invalidDomainTokens = array(
 291              EmailLexer::S_DQUOTE => true,
 292              EmailLexer::S_SEMICOLON => true,
 293              EmailLexer::S_GREATERTHAN => true,
 294              EmailLexer::S_LOWERTHAN => true,
 295          );
 296  
 297          if (isset($invalidDomainTokens[$this->lexer->token['type']])) {
 298              throw new ExpectingATEXT();
 299          }
 300  
 301          if ($this->lexer->token['type'] === EmailLexer::S_COMMA) {
 302              throw new CommaInDomain();
 303          }
 304  
 305          if ($this->lexer->token['type'] === EmailLexer::S_AT) {
 306              throw new ConsecutiveAt();
 307          }
 308  
 309          if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) {
 310              throw new ExpectingATEXT();
 311          }
 312  
 313          if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
 314              throw new DomainHyphened();
 315          }
 316  
 317          if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH
 318              && $this->lexer->isNextToken(EmailLexer::GENERIC)) {
 319              throw new ExpectingATEXT();
 320          }
 321      }
 322  
 323      protected function hasBrackets()
 324      {
 325          if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
 326              return false;
 327          }
 328  
 329          try {
 330              $this->lexer->find(EmailLexer::S_CLOSEBRACKET);
 331          } catch (\RuntimeException $e) {
 332              throw new ExpectingDomainLiteralClose();
 333          }
 334  
 335          return true;
 336      }
 337  
 338      protected function checkLabelLength($prev)
 339      {
 340          if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
 341              $prev['type'] === EmailLexer::GENERIC &&
 342              strlen($prev['value']) > 63
 343          ) {
 344              $this->warnings[LabelTooLong::CODE] = new LabelTooLong();
 345          }
 346      }
 347  
 348      protected function parseDomainComments()
 349      {
 350          $this->isUnclosedComment();
 351          while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
 352              $this->warnEscaping();
 353              $this->lexer->moveNext();
 354          }
 355  
 356          $this->lexer->moveNext();
 357          if ($this->lexer->isNextToken(EmailLexer::S_DOT)) {
 358              throw new ExpectingATEXT();
 359          }
 360      }
 361  
 362      protected function addTLDWarnings()
 363      {
 364          if ($this->warnings[DomainLiteral::CODE]) {
 365              $this->warnings[TLD::CODE] = new TLD();
 366          }
 367      }
 368  }


Generated: Tue May 19 15:55:14 2020 Cross-referenced by PHPXref 0.7.1