Skip to content

Commit

Permalink
Enabling psalm on php >= 7.1, fixing #125, #168, #169, partially fixing
Browse files Browse the repository at this point in the history
#177 (#190)

* experimenting with psalm

* loading in symfony polyfill, partially resolves #177, but SpoofChecker does not seem to be polyfilled in symfony/polyfill-intl-*

* removing unused imports, fixes #168 and #169

* not actually used for object storage

* Egulias\Tests\EmailValidator\Validation\SpoofCheckValidationTest::testEmailWithSpoofsIsInvalid fails if extension is not installed

* satisfying psalm

* amending indentation

* disabling psalm on 5.6

* attempting to resolve psalm issue on 7.0 & 7.1

* dropping psalm from 7.0 matrix

* ext-intl removed as per #231

* updating baseline with psalm 3.8.3

* suppressing issue with Spoofchecker not being present, pending resolution of #231

* enable psalm on travis config for php 7.3
  • Loading branch information
SignpostMarv authored and egulias committed Jan 20, 2020
1 parent c4b8d12 commit e834eea
Show file tree
Hide file tree
Showing 22 changed files with 272 additions and 31 deletions.
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,37 @@ matrix:
- php: 5.5
dist: trusty
- php: 5.6
env:
dist: xenial
- php: 7.0
dist: xenial
- php: 7.1
env:
- psalm=yes
dist: bionic
- php: 7.2
env:
- psalm=yes
dist: bionic
- php: 7.3
dist: bionic
env:
- psalm=yes
- php: 7.4
env:
- psalm=yes
dist: bionic

install:
- if [ "$deps" = "low" ]; then composer update --prefer-lowest; else composer install; fi
- if [ "$psalm" = "yes" ]; then composer require --dev vimeo/psalm; fi

before_script:
- mkdir -p build/logs

script:
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- if [ "$psalm" = "yes" ]; then vendor/bin/psalm; fi

after_script:
- php vendor/bin/coveralls
44 changes: 41 additions & 3 deletions EmailValidator/EmailLexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,37 @@ class EmailLexer extends AbstractLexer
'\0' => self::C_NUL,
);

/**
* @var bool
*/
protected $hasInvalidTokens = false;

protected $previous;
/**
* @var array
*
* @psalm-var array{value:string, type:null|int, position:int}|array<empty, empty>
*/
protected $previous = [];

/**
* The last matched/seen token.
*
* @var array
*
* @psalm-var array{value:string, type:null|int, position:int}
*/
public $token;

/**
* The next token in the input.
*
* @var array|null
*/
public $lookahead;

/**
* @psalm-var array{value:'', type:null, position:0}
*/
private static $nullToken = [
'value' => '',
'type' => null,
Expand All @@ -86,6 +113,7 @@ class EmailLexer extends AbstractLexer
public function __construct()
{
$this->previous = $this->token = self::$nullToken;
$this->lookahead = null;
}

/**
Expand All @@ -98,15 +126,20 @@ public function reset()
$this->previous = $this->token = self::$nullToken;
}

/**
* @return bool
*/
public function hasInvalidTokens()
{
return $this->hasInvalidTokens;
}

/**
* @param string $type
* @param int $type
* @throws \UnexpectedValueException
* @return boolean
*
* @psalm-suppress InvalidScalarArgument
*/
public function find($type)
{
Expand All @@ -122,7 +155,7 @@ public function find($type)
/**
* getPrevious
*
* @return array token
* @return array
*/
public function getPrevious()
{
Expand Down Expand Up @@ -196,6 +229,11 @@ protected function getType(&$value)
return self::GENERIC;
}

/**
* @param string $value
*
* @return bool
*/
protected function isValid($value)
{
if (isset($this->charValue[$value])) {
Expand Down
37 changes: 35 additions & 2 deletions EmailValidator/EmailParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,40 @@ class EmailParser
{
const EMAIL_MAX_LENGTH = 254;

protected $warnings;
/**
* @var array
*/
protected $warnings = [];

/**
* @var string
*/
protected $domainPart = '';

/**
* @var string
*/
protected $localPart = '';
/**
* @var EmailLexer
*/
protected $lexer;

/**
* @var LocalPart
*/
protected $localPartParser;

/**
* @var DomainPart
*/
protected $domainPartParser;

public function __construct(EmailLexer $lexer)
{
$this->lexer = $lexer;
$this->localPartParser = new LocalPart($this->lexer);
$this->domainPartParser = new DomainPart($this->lexer);
$this->warnings = new \SplObjectStorage();
}

/**
Expand Down Expand Up @@ -57,6 +78,9 @@ public function parse($str)
return array('local' => $this->localPart, 'domain' => $this->domainPart);
}

/**
* @return Warning\Warning[]
*/
public function getWarnings()
{
$localPartWarnings = $this->localPartParser->getWarnings();
Expand All @@ -68,18 +92,27 @@ public function getWarnings()
return $this->warnings;
}

/**
* @return string
*/
public function getParsedDomainPart()
{
return $this->domainPart;
}

/**
* @param string $email
*/
protected function setParts($email)
{
$parts = explode('@', $email);
$this->domainPart = $this->domainPartParser->getDomainPart();
$this->localPart = $parts[0];
}

/**
* @return bool
*/
protected function hasAtToken()
{
$this->lexer->moveNext();
Expand Down
8 changes: 4 additions & 4 deletions EmailValidator/EmailValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class EmailValidator
private $lexer;

/**
* @var array
* @var Warning\Warning[]
*/
protected $warnings;
protected $warnings = [];

/**
* @var InvalidEmail
* @var InvalidEmail|null
*/
protected $error;

Expand Down Expand Up @@ -58,7 +58,7 @@ public function getWarnings()
}

/**
* @return InvalidEmail
* @return InvalidEmail|null
*/
public function getError()
{
Expand Down
36 changes: 32 additions & 4 deletions EmailValidator/Parser/DomainPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
class DomainPart extends Parser
{
const DOMAIN_MAX_LENGTH = 254;

/**
* @var string
*/
protected $domainPart = '';

public function parse($domainPart)
Expand Down Expand Up @@ -95,11 +99,18 @@ private function checkInvalidTokensAfterAT()
}
}

/**
* @return string
*/
public function getDomainPart()
{
return $this->domainPart;
}

/**
* @param string $addressLiteral
* @param int $maxGroups
*/
public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
{
$prev = $this->lexer->getPrevious();
Expand Down Expand Up @@ -143,6 +154,9 @@ public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
}
}

/**
* @return string
*/
protected function doParseDomainPart()
{
$domain = '';
Expand Down Expand Up @@ -189,14 +203,17 @@ protected function doParseDomainPart()
return $domain;
}

private function checkNotAllowedChars($token)
private function checkNotAllowedChars(array $token)
{
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
if (isset($notAllowed[$token['type']])) {
throw new CharNotAllowed();
}
}

/**
* @return string|false
*/
protected function parseDomainLiteral()
{
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
Expand All @@ -213,6 +230,9 @@ protected function parseDomainLiteral()
return $this->doParseDomainLiteral();
}

/**
* @return string|false
*/
protected function doParseDomainLiteral()
{
$IPv6TAG = false;
Expand Down Expand Up @@ -280,6 +300,11 @@ protected function doParseDomainLiteral()
return $addressLiteral;
}

/**
* @param string $addressLiteral
*
* @return string|false
*/
protected function checkIPV4Tag($addressLiteral)
{
$matchesIP = array();
Expand All @@ -297,13 +322,13 @@ protected function checkIPV4Tag($addressLiteral)
return false;
}
// Convert IPv4 part to IPv6 format for further testing
$addressLiteral = substr($addressLiteral, 0, $index) . '0:0';
$addressLiteral = substr($addressLiteral, 0, (int) $index) . '0:0';
}

return $addressLiteral;
}

protected function checkDomainPartExceptions($prev)
protected function checkDomainPartExceptions(array $prev)
{
$invalidDomainTokens = array(
EmailLexer::S_DQUOTE => true,
Expand Down Expand Up @@ -338,6 +363,9 @@ protected function checkDomainPartExceptions($prev)
}
}

/**
* @return bool
*/
protected function hasBrackets()
{
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
Expand All @@ -353,7 +381,7 @@ protected function hasBrackets()
return true;
}

protected function checkLabelLength($prev)
protected function checkLabelLength(array $prev)
{
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
$prev['type'] === EmailLexer::GENERIC &&
Expand Down
9 changes: 7 additions & 2 deletions EmailValidator/Parser/LocalPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Egulias\EmailValidator\Exception\DotAtEnd;
use Egulias\EmailValidator\Exception\DotAtStart;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\ExpectingAT;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
Expand Down Expand Up @@ -67,6 +66,9 @@ public function parse($localPart)
}
}

/**
* @return bool
*/
protected function parseDoubleQuote()
{
$parseAgain = true;
Expand Down Expand Up @@ -118,7 +120,10 @@ protected function parseDoubleQuote()
return $parseAgain;
}

protected function isInvalidToken($token, $closingQuote)
/**
* @param bool $closingQuote
*/
protected function isInvalidToken(array $token, $closingQuote)
{
$forbidden = array(
EmailLexer::S_COMMA,
Expand Down
Loading

0 comments on commit e834eea

Please sign in to comment.