vendor/egulias/email-validator/src/EmailLexer.php line 275

Open in your IDE?
  1. <?php
  2. namespace Egulias\EmailValidator;
  3. use Doctrine\Common\Lexer\AbstractLexer;
  4. class EmailLexer extends AbstractLexer
  5. {
  6.     //ASCII values
  7.     const S_EMPTY            null;
  8.     const C_NUL              0;
  9.     const S_HTAB             9;
  10.     const S_LF               10;
  11.     const S_CR               13;
  12.     const S_SP               32;
  13.     const EXCLAMATION        33;
  14.     const S_DQUOTE           34;
  15.     const NUMBER_SIGN        35;
  16.     const DOLLAR             36;
  17.     const PERCENTAGE         37;
  18.     const AMPERSAND          38;
  19.     const S_SQUOTE           39;
  20.     const S_OPENPARENTHESIS  40;
  21.     const S_CLOSEPARENTHESIS 41;
  22.     const ASTERISK           42;
  23.     const S_PLUS             43;
  24.     const S_COMMA            44;
  25.     const S_HYPHEN           45;
  26.     const S_DOT              46;
  27.     const S_SLASH            47;
  28.     const S_COLON            58;
  29.     const S_SEMICOLON        59;
  30.     const S_LOWERTHAN        60;
  31.     const S_EQUAL            61;
  32.     const S_GREATERTHAN      62;
  33.     const QUESTIONMARK       63;
  34.     const S_AT               64;
  35.     const S_OPENBRACKET      91;
  36.     const S_BACKSLASH        92;
  37.     const S_CLOSEBRACKET     93;
  38.     const CARET              94;
  39.     const S_UNDERSCORE       95;
  40.     const S_BACKTICK         96;
  41.     const S_OPENCURLYBRACES  123;
  42.     const S_PIPE             124;
  43.     const S_CLOSECURLYBRACES 125;
  44.     const S_TILDE            126;
  45.     const C_DEL              127;
  46.     const INVERT_QUESTIONMARK168;
  47.     const INVERT_EXCLAMATION 173;
  48.     const GENERIC            300;
  49.     const S_IPV6TAG          301;
  50.     const INVALID            302;
  51.     const CRLF               1310;
  52.     const S_DOUBLECOLON      5858;
  53.     const ASCII_INVALID_FROM 127;
  54.     const ASCII_INVALID_TO   199;
  55.     /**
  56.      * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
  57.      *
  58.      * @var array
  59.      */
  60.     protected $charValue = array(
  61.         '{'    => self::S_OPENCURLYBRACES,
  62.         '}'    => self::S_CLOSECURLYBRACES,
  63.         '('    => self::S_OPENPARENTHESIS,
  64.         ')'    => self::S_CLOSEPARENTHESIS,
  65.         '<'    => self::S_LOWERTHAN,
  66.         '>'    => self::S_GREATERTHAN,
  67.         '['    => self::S_OPENBRACKET,
  68.         ']'    => self::S_CLOSEBRACKET,
  69.         ':'    => self::S_COLON,
  70.         ';'    => self::S_SEMICOLON,
  71.         '@'    => self::S_AT,
  72.         '\\'   => self::S_BACKSLASH,
  73.         '/'    => self::S_SLASH,
  74.         ','    => self::S_COMMA,
  75.         '.'    => self::S_DOT,
  76.         "'"    => self::S_SQUOTE,
  77.         "`"    => self::S_BACKTICK,
  78.         '"'    => self::S_DQUOTE,
  79.         '-'    => self::S_HYPHEN,
  80.         '::'   => self::S_DOUBLECOLON,
  81.         ' '    => self::S_SP,
  82.         "\t"   => self::S_HTAB,
  83.         "\r"   => self::S_CR,
  84.         "\n"   => self::S_LF,
  85.         "\r\n" => self::CRLF,
  86.         'IPv6' => self::S_IPV6TAG,
  87.         ''     => self::S_EMPTY,
  88.         '\0'   => self::C_NUL,
  89.         '*'    => self::ASTERISK,
  90.         '!'    => self::EXCLAMATION,
  91.         '&'    => self::AMPERSAND,
  92.         '^'    => self::CARET,
  93.         '$'    => self::DOLLAR,
  94.         '%'    => self::PERCENTAGE,
  95.         '~'    => self::S_TILDE,
  96.         '|'    => self::S_PIPE,
  97.         '_'    => self::S_UNDERSCORE,
  98.         '='    => self::S_EQUAL,
  99.         '+'    => self::S_PLUS,
  100.         '¿'    => self::INVERT_QUESTIONMARK,
  101.         '?'    => self::QUESTIONMARK,
  102.         '#'    => self::NUMBER_SIGN,
  103.         '¡'    => self::INVERT_EXCLAMATION,
  104.     );
  105.     /**
  106.      * @var bool
  107.      */
  108.     protected $hasInvalidTokens false;
  109.     /**
  110.      * @var array
  111.      *
  112.      * @psalm-var array{value:string, type:null|int, position:int}|array<empty, empty>
  113.      */
  114.     protected $previous = [];
  115.     /**
  116.      * The last matched/seen token.
  117.      *
  118.      * @var array
  119.      *
  120.      * @psalm-suppress NonInvariantDocblockPropertyType
  121.      * @psalm-var array{value:string, type:null|int, position:int}
  122.      * @psalm-suppress NonInvariantDocblockPropertyType
  123.      */
  124.     public $token;
  125.     /**
  126.      * The next token in the input.
  127.      *
  128.      * @var array|null
  129.      */
  130.     public $lookahead;
  131.     /**
  132.      * @psalm-var array{value:'', type:null, position:0}
  133.      */
  134.     private static $nullToken = [
  135.         'value' => '',
  136.         'type' => null,
  137.         'position' => 0,
  138.     ];
  139.     /**
  140.      * @var string
  141.      */
  142.     private $accumulator '';
  143.     /**
  144.      * @var bool
  145.      */
  146.     private $hasToRecord false;
  147.     public function __construct()
  148.     {
  149.         $this->previous $this->token self::$nullToken;
  150.         $this->lookahead null;
  151.     }
  152.     /**
  153.      * @return void
  154.      */
  155.     public function reset()
  156.     {
  157.         $this->hasInvalidTokens false;
  158.         parent::reset();
  159.         $this->previous $this->token self::$nullToken;
  160.     }
  161.     /**
  162.      * @return bool
  163.      */
  164.     public function hasInvalidTokens()
  165.     {
  166.         return $this->hasInvalidTokens;
  167.     }
  168.     /**
  169.      * @param int $type
  170.      * @throws \UnexpectedValueException
  171.      * @return boolean
  172.      *
  173.      * @psalm-suppress InvalidScalarArgument
  174.      */
  175.     public function find($type)
  176.     {
  177.         $search = clone $this;
  178.         $search->skipUntil($type);
  179.         if (!$search->lookahead) {
  180.             throw new \UnexpectedValueException($type ' not found');
  181.         }
  182.         return true;
  183.     }
  184.     /**
  185.      * getPrevious
  186.      *
  187.      * @return array
  188.      */
  189.     public function getPrevious()
  190.     {
  191.         return $this->previous;
  192.     }
  193.     /**
  194.      * moveNext
  195.      *
  196.      * @return boolean
  197.      */
  198.     public function moveNext()
  199.     {
  200.         if ($this->hasToRecord && $this->previous === self::$nullToken) {
  201.             $this->accumulator .= $this->token['value'];
  202.         }
  203.         $this->previous $this->token;
  204.         $hasNext parent::moveNext();
  205.         $this->token $this->token ?: self::$nullToken;
  206.         if ($this->hasToRecord) {
  207.             $this->accumulator .= $this->token['value'];
  208.         }
  209.         return $hasNext;
  210.     }
  211.     /**
  212.      * Lexical catchable patterns.
  213.      *
  214.      * @return string[]
  215.      */
  216.     protected function getCatchablePatterns()
  217.     {
  218.         return array(
  219.             '[a-zA-Z]+[46]?'//ASCII and domain literal
  220.             '[^\x00-\x7F]',  //UTF-8
  221.             '[0-9]+',
  222.             '\r\n',
  223.             '::',
  224.             '\s+?',
  225.             '.',
  226.             );
  227.     }
  228.     /**
  229.      * Lexical non-catchable patterns.
  230.      *
  231.      * @return string[]
  232.      */
  233.     protected function getNonCatchablePatterns()
  234.     {
  235.         return [
  236.             '[\xA0-\xff]+',
  237.         ];
  238.     }
  239.     /**
  240.      * Retrieve token type. Also processes the token value if necessary.
  241.      *
  242.      * @param string $value
  243.      * @throws \InvalidArgumentException
  244.      * @return integer
  245.      */
  246.     protected function getType(&$value)
  247.     {
  248.         $encoded $value;
  249.         if (mb_detect_encoding($value'auto'true) !== 'UTF-8') {
  250.             $encoded utf8_encode($value);
  251.         }
  252.         if ($this->isValid($encoded)) {
  253.             return $this->charValue[$encoded];
  254.         }
  255.         if ($this->isNullType($encoded)) {
  256.             return self::C_NUL;
  257.         }
  258.         if ($this->isInvalidChar($encoded)) {
  259.             $this->hasInvalidTokens true;
  260.             return self::INVALID;
  261.         }
  262.         return  self::GENERIC;
  263.     }
  264.     protected function isInvalidChar(string $value) : bool
  265.     {
  266.         if(preg_match("/[^\p{S}\p{C}\p{Cc}]+/iu"$value) ) {
  267.             return false;
  268.         }
  269.         return true;
  270.     }
  271.     protected function isValid(string $value) : bool
  272.     {
  273.         if (isset($this->charValue[$value])) {
  274.             return true;
  275.         }
  276.         return false;
  277.     }
  278.     /**
  279.      * @param string $value
  280.      * @return bool
  281.      */
  282.     protected function isNullType($value)
  283.     {
  284.         if ($value === "\0") {
  285.             return true;
  286.         }
  287.         return false;
  288.     }
  289.     protected function isUTF8Invalid(string $value) : bool
  290.     {
  291.         if (preg_match('/\p{Cc}+/u'$value)) {
  292.             return true;
  293.         }
  294.         return false;
  295.     }
  296.     /**
  297.      * @return string
  298.      */
  299.     protected function getModifiers()
  300.     {
  301.         return 'iu';
  302.     }
  303.     public function getAccumulatedValues() : string
  304.     {
  305.         return $this->accumulator;
  306.     }
  307.     public function startRecording() : void
  308.     {
  309.         $this->hasToRecord true;
  310.     }
  311.     public function stopRecording() : void
  312.     {
  313.         $this->hasToRecord false;
  314.     }
  315.     public function clearRecorded() : void
  316.     {
  317.         $this->accumulator '';
  318.     }
  319. }