annotate vendor/egulias/email-validator/EmailValidator/Parser/LocalPart.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@18 1 <?php
Chris@18 2
Chris@18 3 namespace Egulias\EmailValidator\Parser;
Chris@18 4
Chris@18 5 use Egulias\EmailValidator\Exception\DotAtEnd;
Chris@18 6 use Egulias\EmailValidator\Exception\DotAtStart;
Chris@18 7 use Egulias\EmailValidator\EmailLexer;
Chris@18 8 use Egulias\EmailValidator\EmailValidator;
Chris@18 9 use Egulias\EmailValidator\Exception\ExpectingAT;
Chris@18 10 use Egulias\EmailValidator\Exception\ExpectingATEXT;
Chris@18 11 use Egulias\EmailValidator\Exception\UnclosedQuotedString;
Chris@18 12 use Egulias\EmailValidator\Exception\UnopenedComment;
Chris@18 13 use Egulias\EmailValidator\Warning\CFWSWithFWS;
Chris@18 14 use Egulias\EmailValidator\Warning\LocalTooLong;
Chris@18 15
Chris@18 16 class LocalPart extends Parser
Chris@18 17 {
Chris@18 18 public function parse($localPart)
Chris@18 19 {
Chris@18 20 $parseDQuote = true;
Chris@18 21 $closingQuote = false;
Chris@18 22 $openedParenthesis = 0;
Chris@18 23
Chris@18 24 while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
Chris@18 25 if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
Chris@18 26 throw new DotAtStart();
Chris@18 27 }
Chris@18 28
Chris@18 29 $closingQuote = $this->checkDQUOTE($closingQuote);
Chris@18 30 if ($closingQuote && $parseDQuote) {
Chris@18 31 $parseDQuote = $this->parseDoubleQuote();
Chris@18 32 }
Chris@18 33
Chris@18 34 if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
Chris@18 35 $this->parseComments();
Chris@18 36 $openedParenthesis += $this->getOpenedParenthesis();
Chris@18 37 }
Chris@18 38 if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
Chris@18 39 if ($openedParenthesis === 0) {
Chris@18 40 throw new UnopenedComment();
Chris@18 41 } else {
Chris@18 42 $openedParenthesis--;
Chris@18 43 }
Chris@18 44 }
Chris@18 45
Chris@18 46 $this->checkConsecutiveDots();
Chris@18 47
Chris@18 48 if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
Chris@18 49 $this->lexer->isNextToken(EmailLexer::S_AT)
Chris@18 50 ) {
Chris@18 51 throw new DotAtEnd();
Chris@18 52 }
Chris@18 53
Chris@18 54 $this->warnEscaping();
Chris@18 55 $this->isInvalidToken($this->lexer->token, $closingQuote);
Chris@18 56
Chris@18 57 if ($this->isFWS()) {
Chris@18 58 $this->parseFWS();
Chris@18 59 }
Chris@18 60
Chris@18 61 $this->lexer->moveNext();
Chris@18 62 }
Chris@18 63
Chris@18 64 $prev = $this->lexer->getPrevious();
Chris@18 65 if (strlen($prev['value']) > LocalTooLong::LOCAL_PART_LENGTH) {
Chris@18 66 $this->warnings[LocalTooLong::CODE] = new LocalTooLong();
Chris@18 67 }
Chris@18 68 }
Chris@18 69
Chris@18 70 protected function parseDoubleQuote()
Chris@18 71 {
Chris@18 72 $parseAgain = true;
Chris@18 73 $special = array(
Chris@18 74 EmailLexer::S_CR => true,
Chris@18 75 EmailLexer::S_HTAB => true,
Chris@18 76 EmailLexer::S_LF => true
Chris@18 77 );
Chris@18 78
Chris@18 79 $invalid = array(
Chris@18 80 EmailLexer::C_NUL => true,
Chris@18 81 EmailLexer::S_HTAB => true,
Chris@18 82 EmailLexer::S_CR => true,
Chris@18 83 EmailLexer::S_LF => true
Chris@18 84 );
Chris@18 85 $setSpecialsWarning = true;
Chris@18 86
Chris@18 87 $this->lexer->moveNext();
Chris@18 88
Chris@18 89 while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
Chris@18 90 $parseAgain = false;
Chris@18 91 if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
Chris@18 92 $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
Chris@18 93 $setSpecialsWarning = false;
Chris@18 94 }
Chris@18 95 if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) {
Chris@18 96 $this->lexer->moveNext();
Chris@18 97 }
Chris@18 98
Chris@18 99 $this->lexer->moveNext();
Chris@18 100
Chris@18 101 if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
Chris@18 102 throw new ExpectingATEXT();
Chris@18 103 }
Chris@18 104 }
Chris@18 105
Chris@18 106 $prev = $this->lexer->getPrevious();
Chris@18 107
Chris@18 108 if ($prev['type'] === EmailLexer::S_BACKSLASH) {
Chris@18 109 if (!$this->checkDQUOTE(false)) {
Chris@18 110 throw new UnclosedQuotedString();
Chris@18 111 }
Chris@18 112 }
Chris@18 113
Chris@18 114 if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
Chris@18 115 throw new ExpectingAT();
Chris@18 116 }
Chris@18 117
Chris@18 118 return $parseAgain;
Chris@18 119 }
Chris@18 120
Chris@18 121 protected function isInvalidToken($token, $closingQuote)
Chris@18 122 {
Chris@18 123 $forbidden = array(
Chris@18 124 EmailLexer::S_COMMA,
Chris@18 125 EmailLexer::S_CLOSEBRACKET,
Chris@18 126 EmailLexer::S_OPENBRACKET,
Chris@18 127 EmailLexer::S_GREATERTHAN,
Chris@18 128 EmailLexer::S_LOWERTHAN,
Chris@18 129 EmailLexer::S_COLON,
Chris@18 130 EmailLexer::S_SEMICOLON,
Chris@18 131 EmailLexer::INVALID
Chris@18 132 );
Chris@18 133
Chris@18 134 if (in_array($token['type'], $forbidden) && !$closingQuote) {
Chris@18 135 throw new ExpectingATEXT();
Chris@18 136 }
Chris@18 137 }
Chris@18 138 }