sonarrradarrplexorganizrnginxdashboardhtpcserverhomepagesabnzbdheimdallembycouchpotatonzbgetbookmarkapplication-dashboardmuximuxlandingpagestartpagelanding
		
		
		
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							215 lines
						
					
					
						
							6.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							215 lines
						
					
					
						
							6.3 KiB
						
					
					
				
								<?php
							 | 
						|
								
							 | 
						|
								namespace Egulias\EmailValidator\Parser;
							 | 
						|
								
							 | 
						|
								use Egulias\EmailValidator\EmailLexer;
							 | 
						|
								use Egulias\EmailValidator\Exception\AtextAfterCFWS;
							 | 
						|
								use Egulias\EmailValidator\Exception\ConsecutiveDot;
							 | 
						|
								use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
							 | 
						|
								use Egulias\EmailValidator\Exception\CRLFX2;
							 | 
						|
								use Egulias\EmailValidator\Exception\CRNoLF;
							 | 
						|
								use Egulias\EmailValidator\Exception\ExpectedQPair;
							 | 
						|
								use Egulias\EmailValidator\Exception\ExpectingATEXT;
							 | 
						|
								use Egulias\EmailValidator\Exception\ExpectingCTEXT;
							 | 
						|
								use Egulias\EmailValidator\Exception\UnclosedComment;
							 | 
						|
								use Egulias\EmailValidator\Exception\UnclosedQuotedString;
							 | 
						|
								use Egulias\EmailValidator\Warning\CFWSNearAt;
							 | 
						|
								use Egulias\EmailValidator\Warning\CFWSWithFWS;
							 | 
						|
								use Egulias\EmailValidator\Warning\Comment;
							 | 
						|
								use Egulias\EmailValidator\Warning\QuotedPart;
							 | 
						|
								use Egulias\EmailValidator\Warning\QuotedString;
							 | 
						|
								
							 | 
						|
								abstract class Parser
							 | 
						|
								{
							 | 
						|
								    protected $warnings = [];
							 | 
						|
								    protected $lexer;
							 | 
						|
								    protected $openedParenthesis = 0;
							 | 
						|
								
							 | 
						|
								    public function __construct(EmailLexer $lexer)
							 | 
						|
								    {
							 | 
						|
								        $this->lexer = $lexer;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    public function getWarnings()
							 | 
						|
								    {
							 | 
						|
								        return $this->warnings;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    abstract public function parse($str);
							 | 
						|
								
							 | 
						|
								    /** @return int */
							 | 
						|
								    public function getOpenedParenthesis()
							 | 
						|
								    {
							 | 
						|
								        return $this->openedParenthesis;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * validateQuotedPair
							 | 
						|
								     */
							 | 
						|
								    protected function validateQuotedPair()
							 | 
						|
								    {
							 | 
						|
								        if (!($this->lexer->token['type'] === EmailLexer::INVALID
							 | 
						|
								            || $this->lexer->token['type'] === EmailLexer::C_DEL)) {
							 | 
						|
								            throw new ExpectedQPair();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $this->warnings[QuotedPart::CODE] =
							 | 
						|
								            new QuotedPart($this->lexer->getPrevious()['type'], $this->lexer->token['type']);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function parseComments()
							 | 
						|
								    {
							 | 
						|
								        $this->openedParenthesis = 1;
							 | 
						|
								        $this->isUnclosedComment();
							 | 
						|
								        $this->warnings[Comment::CODE] = new Comment();
							 | 
						|
								        while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
							 | 
						|
								            if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) {
							 | 
						|
								                $this->openedParenthesis++;
							 | 
						|
								            }
							 | 
						|
								            $this->warnEscaping();
							 | 
						|
								            $this->lexer->moveNext();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $this->lexer->moveNext();
							 | 
						|
								        if ($this->lexer->isNextTokenAny(array(EmailLexer::GENERIC, EmailLexer::S_EMPTY))) {
							 | 
						|
								            throw new ExpectingATEXT();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->isNextToken(EmailLexer::S_AT)) {
							 | 
						|
								            $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt();
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function isUnclosedComment()
							 | 
						|
								    {
							 | 
						|
								        try {
							 | 
						|
								            $this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS);
							 | 
						|
								            return true;
							 | 
						|
								        } catch (\RuntimeException $e) {
							 | 
						|
								            throw new UnclosedComment();
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function parseFWS()
							 | 
						|
								    {
							 | 
						|
								        $previous = $this->lexer->getPrevious();
							 | 
						|
								
							 | 
						|
								        $this->checkCRLFInFWS();
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->token['type'] === EmailLexer::S_CR) {
							 | 
						|
								            throw new CRNoLF();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type']  !== EmailLexer::S_AT) {
							 | 
						|
								            throw new AtextAfterCFWS();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) {
							 | 
						|
								            throw new ExpectingCTEXT();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous['type']  === EmailLexer::S_AT) {
							 | 
						|
								            $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt();
							 | 
						|
								        } else {
							 | 
						|
								            $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function checkConsecutiveDots()
							 | 
						|
								    {
							 | 
						|
								        if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
							 | 
						|
								            throw new ConsecutiveDot();
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function isFWS()
							 | 
						|
								    {
							 | 
						|
								        if ($this->escaped()) {
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->token['type'] === EmailLexer::S_SP ||
							 | 
						|
								            $this->lexer->token['type'] === EmailLexer::S_HTAB ||
							 | 
						|
								            $this->lexer->token['type'] === EmailLexer::S_CR ||
							 | 
						|
								            $this->lexer->token['type'] === EmailLexer::S_LF ||
							 | 
						|
								            $this->lexer->token['type'] === EmailLexer::CRLF
							 | 
						|
								        ) {
							 | 
						|
								            return true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return false;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function escaped()
							 | 
						|
								    {
							 | 
						|
								        $previous = $this->lexer->getPrevious();
							 | 
						|
								
							 | 
						|
								        if ($previous['type'] === EmailLexer::S_BACKSLASH
							 | 
						|
								            &&
							 | 
						|
								            $this->lexer->token['type'] !== EmailLexer::GENERIC
							 | 
						|
								        ) {
							 | 
						|
								            return true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return false;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function warnEscaping()
							 | 
						|
								    {
							 | 
						|
								        if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ($this->lexer->isNextToken(EmailLexer::GENERIC)) {
							 | 
						|
								            throw new ExpectingATEXT();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {
							 | 
						|
								            return false;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $this->warnings[QuotedPart::CODE] =
							 | 
						|
								            new QuotedPart($this->lexer->getPrevious()['type'], $this->lexer->token['type']);
							 | 
						|
								        return true;
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function checkDQUOTE($hasClosingQuote)
							 | 
						|
								    {
							 | 
						|
								        if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
							 | 
						|
								            return $hasClosingQuote;
							 | 
						|
								        }
							 | 
						|
								        if ($hasClosingQuote) {
							 | 
						|
								            return $hasClosingQuote;
							 | 
						|
								        }
							 | 
						|
								        $previous = $this->lexer->getPrevious();
							 | 
						|
								        if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
							 | 
						|
								            throw new ExpectingATEXT();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        try {
							 | 
						|
								            $this->lexer->find(EmailLexer::S_DQUOTE);
							 | 
						|
								            $hasClosingQuote = true;
							 | 
						|
								        } catch (\Exception $e) {
							 | 
						|
								            throw new UnclosedQuotedString();
							 | 
						|
								        }
							 | 
						|
								        $this->warnings[QuotedString::CODE] = new QuotedString($previous['value'], $this->lexer->token['value']);
							 | 
						|
								
							 | 
						|
								        return $hasClosingQuote;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    protected function checkCRLFInFWS()
							 | 
						|
								    {
							 | 
						|
								        if ($this->lexer->token['type'] !== EmailLexer::CRLF) {
							 | 
						|
								            return;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
							 | 
						|
								            throw new CRLFX2();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
							 | 
						|
								            throw new CRLFAtTheEnd();
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 |