Chris@18: lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) { Chris@18: if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) { Chris@18: throw new DotAtStart(); Chris@18: } Chris@18: Chris@18: $closingQuote = $this->checkDQUOTE($closingQuote); Chris@18: if ($closingQuote && $parseDQuote) { Chris@18: $parseDQuote = $this->parseDoubleQuote(); Chris@18: } Chris@18: Chris@18: if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { Chris@18: $this->parseComments(); Chris@18: $openedParenthesis += $this->getOpenedParenthesis(); Chris@18: } Chris@18: if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { Chris@18: if ($openedParenthesis === 0) { Chris@18: throw new UnopenedComment(); Chris@18: } else { Chris@18: $openedParenthesis--; Chris@18: } Chris@18: } Chris@18: Chris@18: $this->checkConsecutiveDots(); Chris@18: Chris@18: if ($this->lexer->token['type'] === EmailLexer::S_DOT && Chris@18: $this->lexer->isNextToken(EmailLexer::S_AT) Chris@18: ) { Chris@18: throw new DotAtEnd(); Chris@18: } Chris@18: Chris@18: $this->warnEscaping(); Chris@18: $this->isInvalidToken($this->lexer->token, $closingQuote); Chris@18: Chris@18: if ($this->isFWS()) { Chris@18: $this->parseFWS(); Chris@18: } Chris@18: Chris@18: $this->lexer->moveNext(); Chris@18: } Chris@18: Chris@18: $prev = $this->lexer->getPrevious(); Chris@18: if (strlen($prev['value']) > LocalTooLong::LOCAL_PART_LENGTH) { Chris@18: $this->warnings[LocalTooLong::CODE] = new LocalTooLong(); Chris@18: } Chris@18: } Chris@18: Chris@18: protected function parseDoubleQuote() Chris@18: { Chris@18: $parseAgain = true; Chris@18: $special = array( Chris@18: EmailLexer::S_CR => true, Chris@18: EmailLexer::S_HTAB => true, Chris@18: EmailLexer::S_LF => true Chris@18: ); Chris@18: Chris@18: $invalid = array( Chris@18: EmailLexer::C_NUL => true, Chris@18: EmailLexer::S_HTAB => true, Chris@18: EmailLexer::S_CR => true, Chris@18: EmailLexer::S_LF => true Chris@18: ); Chris@18: $setSpecialsWarning = true; Chris@18: Chris@18: $this->lexer->moveNext(); Chris@18: Chris@18: while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) { Chris@18: $parseAgain = false; Chris@18: if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) { Chris@18: $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); Chris@18: $setSpecialsWarning = false; Chris@18: } Chris@18: if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) { Chris@18: $this->lexer->moveNext(); Chris@18: } Chris@18: Chris@18: $this->lexer->moveNext(); Chris@18: Chris@18: if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) { Chris@18: throw new ExpectingATEXT(); Chris@18: } Chris@18: } Chris@18: Chris@18: $prev = $this->lexer->getPrevious(); Chris@18: Chris@18: if ($prev['type'] === EmailLexer::S_BACKSLASH) { Chris@18: if (!$this->checkDQUOTE(false)) { Chris@18: throw new UnclosedQuotedString(); Chris@18: } Chris@18: } Chris@18: Chris@18: if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) { Chris@18: throw new ExpectingAT(); Chris@18: } Chris@18: Chris@18: return $parseAgain; Chris@18: } Chris@18: Chris@18: protected function isInvalidToken($token, $closingQuote) Chris@18: { Chris@18: $forbidden = array( Chris@18: EmailLexer::S_COMMA, Chris@18: EmailLexer::S_CLOSEBRACKET, Chris@18: EmailLexer::S_OPENBRACKET, Chris@18: EmailLexer::S_GREATERTHAN, Chris@18: EmailLexer::S_LOWERTHAN, Chris@18: EmailLexer::S_COLON, Chris@18: EmailLexer::S_SEMICOLON, Chris@18: EmailLexer::INVALID Chris@18: ); Chris@18: Chris@18: if (in_array($token['type'], $forbidden) && !$closingQuote) { Chris@18: throw new ExpectingATEXT(); Chris@18: } Chris@18: } Chris@18: }