Compare commits

..

10 Commits

Author SHA1 Message Date
Alexander M. Turek 5f35e41eba Allow doctrine/lexer 2 (#345) 2022-12-30 15:09:25 +01:00
Alexis Lefebvre 0170967656 CHANGELOG: Fix typo “Breacking” (#333) 2022-09-03 11:54:08 +02:00
Eduardo Gulias Davis 4c72190f32 Update LICENSE 2022-08-14 20:36:33 +02:00
Mathias Reker ⚡️ 413b263617 Nullable type declaration for default null value (#328)
Adds ? before type declarations for parameters with a default null value
2022-07-13 16:53:11 +02:00
Mathias Reker ⚡️ 18b9e5b572 Visibility required (#329)
Visibility MUST be declared on all properties and methods; abstract and final MUST be declared before the visibility; static MUST be declared after the visibility.
2022-07-13 16:52:42 +02:00
Mathias Reker ⚡️ 1ca313dfcd Single blank line at eof (#330)
A PHP file without end tag must always end with a single empty line feed.
2022-07-13 16:51:51 +02:00
Mathias Reker ⚡️ cf5908bb1a No superfluous elseif (#331)
Replaces superfluous elseif with if.
2022-07-13 16:51:22 +02:00
Mathias Reker ⚡️ b241b54919 No unused imports (#332)
Unused use statements must be removed.
2022-07-13 16:50:27 +02:00
dependabot[bot] 74d2f16d9d Bump guzzlehttp/guzzle from 7.4.3 to 7.4.5 (#326)
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 7.4.3 to 7.4.5.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/master/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.4.3...7.4.5)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-24 20:51:04 +02:00
Nicolas Grekas f88dcf4b14 Don't use utf8_en/decode() functions, they're deprecated on PHP 8.2 (#325) 2022-06-18 22:57:19 +02:00
65 changed files with 264 additions and 217 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
* Access to local part and domain part from EmailParser
* Validations outside of the scope of the RFC will be considered "extra" validations, thus opening the door for adding new; will live in their own folder "extra" (as requested in #248, #195, #183).
## Breacking changes
## Breaking changes
* PHP version upgraded to match Symfony's (as of 12/2020).
* DNSCheckValidation now fails for missing MX records. While the RFC argues that the existence of only A records to be valid, starting in v3 they will be considered invalid.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2013-2021 Eduardo Gulias Davis
Copyright (c) 2013-2022 Eduardo Gulias Davis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1 -1
View File
@@ -14,7 +14,7 @@
},
"require": {
"php": ">=7.2",
"doctrine/lexer": "^1.2",
"doctrine/lexer": "^1.2|^2",
"symfony/polyfill-intl-idn": "^1.15"
},
"require-dev": {
Generated
+103 -58
View File
@@ -4,35 +4,80 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a77d36b64bc1213fecf4d4f92d759c3b",
"content-hash": "9b420b2279da45fe448cd428cf568d87",
"packages": [
{
"name": "doctrine/lexer",
"version": "1.2.3",
"name": "doctrine/deprecations",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229"
"url": "https://github.com/doctrine/deprecations.git",
"reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229",
"reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
"php": "^7.1|^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^9.0",
"phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"vimeo/psalm": "^4.11"
"doctrine/coding-standard": "^9",
"phpunit/phpunit": "^7.5|^8.5|^9.5",
"psr/log": "^1|^2|^3"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
},
"time": "2022-05-02T15:47:09+00:00"
},
{
"name": "doctrine/lexer",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1.0",
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^9 || ^10",
"phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"psalm/plugin-phpunit": "^0.18.3",
"vimeo/psalm": "^4.11 || ^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -64,7 +109,7 @@
],
"support": {
"issues": "https://github.com/doctrine/lexer/issues",
"source": "https://github.com/doctrine/lexer/tree/1.2.3"
"source": "https://github.com/doctrine/lexer/tree/2.1.0"
},
"funding": [
{
@@ -80,20 +125,20 @@
"type": "tidelift"
}
],
"time": "2022-02-28T11:07:21+00:00"
"time": "2022-12-14T08:49:07+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.25.0",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "749045c69efb97c70d25d7463abba812e91f3a44"
"reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44",
"reference": "749045c69efb97c70d25d7463abba812e91f3a44",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
"reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
"shasum": ""
},
"require": {
@@ -107,7 +152,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -151,7 +196,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0"
},
"funding": [
{
@@ -167,20 +212,20 @@
"type": "tidelift"
}
],
"time": "2021-09-14T14:02:44+00:00"
"time": "2022-05-24T11:49:31+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.25.0",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
"reference": "219aa369ceff116e673852dce47c3a41794c14bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
"reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
"reference": "219aa369ceff116e673852dce47c3a41794c14bd",
"shasum": ""
},
"require": {
@@ -192,7 +237,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -235,7 +280,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
},
"funding": [
{
@@ -251,20 +296,20 @@
"type": "tidelift"
}
],
"time": "2021-02-19T12:13:01+00:00"
"time": "2022-05-24T11:49:31+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.25.0",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
"reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
"shasum": ""
},
"require": {
@@ -273,7 +318,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -311,7 +356,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0"
"source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
},
"funding": [
{
@@ -327,7 +372,7 @@
"type": "tidelift"
}
],
"time": "2021-05-27T09:17:38+00:00"
"time": "2022-05-24T11:49:31+00:00"
}
],
"packages-dev": [
@@ -998,22 +1043,22 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.4.3",
"version": "7.4.5",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "74a8602c6faec9ef74b7a9391ac82c5e65b1cdab"
"reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/74a8602c6faec9ef74b7a9391ac82c5e65b1cdab",
"reference": "74a8602c6faec9ef74b7a9391ac82c5e65b1cdab",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82",
"reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5",
"guzzlehttp/psr7": "^1.8.3 || ^2.1",
"guzzlehttp/psr7": "^1.9 || ^2.4",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
@@ -1102,7 +1147,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.4.3"
"source": "https://github.com/guzzle/guzzle/tree/7.4.5"
},
"funding": [
{
@@ -1118,7 +1163,7 @@
"type": "tidelift"
}
],
"time": "2022-05-25T13:24:33+00:00"
"time": "2022-06-20T22:16:13+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -1206,16 +1251,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "2.2.1",
"version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
"reference": "13388f00956b1503577598873fffb5ae994b5737"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737",
"reference": "13388f00956b1503577598873fffb5ae994b5737",
"shasum": ""
},
"require": {
@@ -1239,7 +1284,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
"dev-master": "2.4-dev"
}
},
"autoload": {
@@ -1301,7 +1346,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.2.1"
"source": "https://github.com/guzzle/psr7/tree/2.4.0"
},
"funding": [
{
@@ -1317,7 +1362,7 @@
"type": "tidelift"
}
],
"time": "2022-03-20T21:55:58+00:00"
"time": "2022-06-20T21:43:11+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -4120,16 +4165,16 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.25.0",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"shasum": ""
},
"require": {
@@ -4144,7 +4189,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -4183,7 +4228,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
},
"funding": [
{
@@ -4199,7 +4244,7 @@
"type": "tidelift"
}
],
"time": "2021-11-30T18:21:41+00:00"
"time": "2022-05-24T11:49:31+00:00"
},
{
"name": "symfony/polyfill-php73",
@@ -5024,5 +5069,5 @@
"php": ">=7.2"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.3.0"
}
+5 -16
View File
@@ -1,19 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.8.3@389af1bfc739bfdff3f9e3dc7bd6499aee51a831">
<file src="src/EmailLexer.php">
<DocblockTypeContradiction occurrences="1">
<code>self::$nullToken</code>
</DocblockTypeContradiction>
</file>
<file src="src/Parser/Parser.php">
<MissingReturnType occurrences="1">
<code>parse</code>
</MissingReturnType>
</file>
<file src="src/Validation/SpoofCheckValidation.php">
<UndefinedClass occurrences="2">
<code>Spoofchecker</code>
<code>Spoofchecker</code>
</UndefinedClass>
<files psalm-version="5.4.0@62db5d4f6a7ae0a20f7cc5a4952d730272fc0863">
<file src="src/Parser/DomainPart.php">
<RedundantConditionGivenDocblockType occurrences="1">
<code>null !== $this-&gt;lexer-&gt;token['type']</code>
</RedundantConditionGivenDocblockType>
</file>
</files>
+7 -1
View File
@@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
errorBaseline="./psalm.baseline.xml"
errorBaseline="psalm.baseline.xml"
>
<projectFiles>
<directory name="src" />
@@ -13,5 +13,11 @@
</projectFiles>
<issueHandlers>
<DeprecatedMethod>
<errorLevel type="suppress">
<!-- This issue needs to be resolved before upgrading to Lexer 3 -->
<referencedMethod name="Doctrine\Common\Lexer\Token::offsetGet"/>
</errorLevel>
</DeprecatedMethod>
</issueHandlers>
</psalm>
+67 -59
View File
@@ -3,58 +3,62 @@
namespace Egulias\EmailValidator;
use Doctrine\Common\Lexer\AbstractLexer;
use Doctrine\Common\Lexer\Token;
/**
* @extends AbstractLexer<int, string>
*/
class EmailLexer extends AbstractLexer
{
//ASCII values
const S_EMPTY = null;
const C_NUL = 0;
const S_HTAB = 9;
const S_LF = 10;
const S_CR = 13;
const S_SP = 32;
const EXCLAMATION = 33;
const S_DQUOTE = 34;
const NUMBER_SIGN = 35;
const DOLLAR = 36;
const PERCENTAGE = 37;
const AMPERSAND = 38;
const S_SQUOTE = 39;
const S_OPENPARENTHESIS = 40;
const S_CLOSEPARENTHESIS = 41;
const ASTERISK = 42;
const S_PLUS = 43;
const S_COMMA = 44;
const S_HYPHEN = 45;
const S_DOT = 46;
const S_SLASH = 47;
const S_COLON = 58;
const S_SEMICOLON = 59;
const S_LOWERTHAN = 60;
const S_EQUAL = 61;
const S_GREATERTHAN = 62;
const QUESTIONMARK = 63;
const S_AT = 64;
const S_OPENBRACKET = 91;
const S_BACKSLASH = 92;
const S_CLOSEBRACKET = 93;
const CARET = 94;
const S_UNDERSCORE = 95;
const S_BACKTICK = 96;
const S_OPENCURLYBRACES = 123;
const S_PIPE = 124;
const S_CLOSECURLYBRACES = 125;
const S_TILDE = 126;
const C_DEL = 127;
const INVERT_QUESTIONMARK= 168;
const INVERT_EXCLAMATION = 173;
const GENERIC = 300;
const S_IPV6TAG = 301;
const INVALID = 302;
const CRLF = 1310;
const S_DOUBLECOLON = 5858;
const ASCII_INVALID_FROM = 127;
const ASCII_INVALID_TO = 199;
public const S_EMPTY = null;
public const C_NUL = 0;
public const S_HTAB = 9;
public const S_LF = 10;
public const S_CR = 13;
public const S_SP = 32;
public const EXCLAMATION = 33;
public const S_DQUOTE = 34;
public const NUMBER_SIGN = 35;
public const DOLLAR = 36;
public const PERCENTAGE = 37;
public const AMPERSAND = 38;
public const S_SQUOTE = 39;
public const S_OPENPARENTHESIS = 40;
public const S_CLOSEPARENTHESIS = 41;
public const ASTERISK = 42;
public const S_PLUS = 43;
public const S_COMMA = 44;
public const S_HYPHEN = 45;
public const S_DOT = 46;
public const S_SLASH = 47;
public const S_COLON = 58;
public const S_SEMICOLON = 59;
public const S_LOWERTHAN = 60;
public const S_EQUAL = 61;
public const S_GREATERTHAN = 62;
public const QUESTIONMARK = 63;
public const S_AT = 64;
public const S_OPENBRACKET = 91;
public const S_BACKSLASH = 92;
public const S_CLOSEBRACKET = 93;
public const CARET = 94;
public const S_UNDERSCORE = 95;
public const S_BACKTICK = 96;
public const S_OPENCURLYBRACES = 123;
public const S_PIPE = 124;
public const S_CLOSECURLYBRACES = 125;
public const S_TILDE = 126;
public const C_DEL = 127;
public const INVERT_QUESTIONMARK= 168;
public const INVERT_EXCLAMATION = 173;
public const GENERIC = 300;
public const S_IPV6TAG = 301;
public const INVALID = 302;
public const CRLF = 1310;
public const S_DOUBLECOLON = 5858;
public const ASCII_INVALID_FROM = 127;
public const ASCII_INVALID_TO = 199;
/**
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
@@ -107,11 +111,11 @@ class EmailLexer extends AbstractLexer
'¡' => self::INVERT_EXCLAMATION,
];
const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu";
public const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu";
const VALID_UTF8_REGEX = '/\p{Cc}+/u';
public const VALID_UTF8_REGEX = '/\p{Cc}+/u';
const CATCHABLE_PATTERNS = [
public const CATCHABLE_PATTERNS = [
'[a-zA-Z]+[46]?', //ASCII and domain literal
'[^\x00-\x7F]', //UTF-8
'[0-9]+',
@@ -121,11 +125,11 @@ class EmailLexer extends AbstractLexer
'.',
];
const NON_CATCHABLE_PATTERNS = [
public const NON_CATCHABLE_PATTERNS = [
'[\xA0-\xff]+',
];
const MODIFIERS = 'iu';
public const MODIFIERS = 'iu';
/** @var bool */
protected $hasInvalidTokens = false;
@@ -140,18 +144,20 @@ class EmailLexer extends AbstractLexer
/**
* The last matched/seen token.
*
* @var array
* @var array|Token
*
* @psalm-suppress NonInvariantDocblockPropertyType
* @psalm-var array{value:string, type:null|int, position:int}
* @psalm-suppress NonInvariantDocblockPropertyType
* @psalm-var array{value:string, type:null|int, position:int}|Token<int, string>
*/
public $token;
/**
* The next token in the input.
*
* @var array{position: int, type: int|null|string, value: int|string}|null
* @var array|Token|null
*
* @psalm-suppress NonInvariantDocblockPropertyType
* @psalm-var array{position: int, type: int|null|string, value: int|string}|Token<int, string>|null
*/
public $lookahead;
@@ -210,7 +216,9 @@ class EmailLexer extends AbstractLexer
$this->accumulator .= $this->token['value'];
}
$this->previous = $this->token;
$this->previous = $this->token instanceof Token
? ['value' => $this->token->value, 'type' => $this->token->type, 'position' => $this->token->position]
: $this->token;
if($this->lookahead === null) {
$this->lookahead = self::$nullToken;
@@ -237,7 +245,7 @@ class EmailLexer extends AbstractLexer
$encoded = $value;
if (mb_detect_encoding($value, 'auto', true) !== 'UTF-8') {
$encoded = utf8_encode($value);
$encoded = mb_convert_encoding($value, 'UTF-8', 'Windows-1252');
}
if ($this->isValid($encoded)) {
+1 -2
View File
@@ -2,7 +2,6 @@
namespace Egulias\EmailValidator;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Parser\DomainPart;
@@ -13,7 +12,7 @@ use Egulias\EmailValidator\Result\Reason\NoLocalPart;
class EmailParser extends Parser
{
const EMAIL_MAX_LENGTH = 254;
public const EMAIL_MAX_LENGTH = 254;
/**
* @var string
+2 -3
View File
@@ -2,7 +2,6 @@
namespace Egulias\EmailValidator;
use Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\IDLeftPart;
use Egulias\EmailValidator\Parser\IDRightPart;
@@ -14,7 +13,7 @@ use Egulias\EmailValidator\Result\Reason\NoLocalPart;
class MessageIDParser extends Parser
{
const EMAILID_MAX_LENGTH = 254;
public const EMAILID_MAX_LENGTH = 254;
/**
* @var string
@@ -89,4 +88,4 @@ class MessageIDParser extends Parser
$this->warnings[EmailTooLong::CODE] = new EmailTooLong();
}
}
}
}
+3 -2
View File
@@ -59,7 +59,8 @@ class Comment extends PartParser
if($this->openedParenthesis >= 1) {
return new InvalidEmail(new UnclosedComment(), $this->lexer->token['value']);
} else if ($this->openedParenthesis < 0) {
}
if ($this->openedParenthesis < 0) {
return new InvalidEmail(new UnOpenedComment(), $this->lexer->token['value']);
}
@@ -100,4 +101,4 @@ class Comment extends PartParser
return true;
}
}
}
}
@@ -15,4 +15,4 @@ interface CommentStrategy
public function endOfLoopValidations(EmailLexer $lexer) : Result;
public function getWarnings() : array;
}
}
+1 -1
View File
@@ -34,4 +34,4 @@ class DomainComment implements CommentStrategy
{
return [];
}
}
}
+1 -1
View File
@@ -34,4 +34,4 @@ class LocalComment implements CommentStrategy
{
return $this->warnings;
}
}
}
+3 -3
View File
@@ -22,9 +22,9 @@ use Egulias\EmailValidator\Warning\DomainLiteral as WarningDomainLiteral;
class DomainLiteral extends PartParser
{
const IPV4_REGEX = '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
public const IPV4_REGEX = '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
const OBSOLETE_WARNINGS = [
public const OBSOLETE_WARNINGS = [
EmailLexer::INVALID,
EmailLexer::C_DEL,
EmailLexer::S_LF,
@@ -208,4 +208,4 @@ class DomainLiteral extends PartParser
}
}
}
}
+9 -5
View File
@@ -2,6 +2,7 @@
namespace Egulias\EmailValidator\Parser;
use Doctrine\Common\Lexer\Token;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Warning\TLD;
use Egulias\EmailValidator\Result\Result;
@@ -24,8 +25,8 @@ use Egulias\EmailValidator\Parser\DomainLiteral as DomainLiteralParser;
class DomainPart extends PartParser
{
const DOMAIN_MAX_LENGTH = 253;
const LABEL_MAX_LENGTH = 63;
public const DOMAIN_MAX_LENGTH = 253;
public const LABEL_MAX_LENGTH = 63;
/**
* @var string
@@ -212,7 +213,10 @@ class DomainPart extends PartParser
return new ValidEmail();
}
private function checkNotAllowedChars(array $token) : Result
/**
* @psalm-param array|Token<int, string> $token
*/
private function checkNotAllowedChars($token) : Result
{
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
if (isset($notAllowed[$token['type']])) {
@@ -292,7 +296,7 @@ class DomainPart extends PartParser
private function isLabelTooLong(string $label) : bool
{
if (preg_match('/[^\x00-\x7F]/', $label)) {
idn_to_ascii(utf8_decode($label), IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG);
}
return strlen($label) > self::LABEL_MAX_LENGTH;
@@ -309,4 +313,4 @@ class DomainPart extends PartParser
{
return $this->domainPart;
}
}
}
+1 -2
View File
@@ -2,7 +2,6 @@
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Parser\Parser;
use Egulias\EmailValidator\Result\ValidEmail;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
@@ -85,4 +84,4 @@ class DoubleQuote extends PartParser
return new ValidEmail();
}
}
}
+2 -2
View File
@@ -15,7 +15,7 @@ use Egulias\EmailValidator\Result\ValidEmail;
class FoldingWhiteSpace extends PartParser
{
const FWS_TYPES = [
public const FWS_TYPES = [
EmailLexer::S_SP,
EmailLexer::S_HTAB,
EmailLexer::S_CR,
@@ -83,4 +83,4 @@ class FoldingWhiteSpace extends PartParser
return in_array($this->lexer->token['type'], self::FWS_TYPES);
}
}
}
+1 -2
View File
@@ -3,7 +3,6 @@
namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\CommentsInIDRight;
@@ -13,4 +12,4 @@ class IDLeftPart extends LocalPart
{
return new InvalidEmail(new CommentsInIDRight(), $this->lexer->token['value']);
}
}
}
+1 -1
View File
@@ -26,4 +26,4 @@ class IDRightPart extends DomainPart
}
return new ValidEmail();
}
}
}
+2 -2
View File
@@ -15,7 +15,7 @@ use Egulias\EmailValidator\Parser\CommentStrategy\LocalComment;
class LocalPart extends PartParser
{
const INVALID_TOKENS = [
public const INVALID_TOKENS = [
EmailLexer::S_COMMA => EmailLexer::S_COMMA,
EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET,
EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET,
@@ -162,4 +162,4 @@ class LocalPart extends PartParser
return new ValidEmail();
}
}
}
+1 -1
View File
@@ -60,4 +60,4 @@ abstract class PartParser
&&
$this->lexer->token['type'] !== EmailLexer::GENERIC;
}
}
}
+2 -2
View File
@@ -6,7 +6,7 @@ use Egulias\EmailValidator\Result\Reason\Reason;
class InvalidEmail implements Result
{
private $token;
private $token;
/**
* @var Reason
*/
@@ -43,4 +43,4 @@ class InvalidEmail implements Result
return $this->reason;
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class AtextAfterCFWS implements Reason
{
return 'ATEXT found after CFWS';
}
}
}
+2 -2
View File
@@ -4,8 +4,8 @@ namespace Egulias\EmailValidator\Result\Reason;
class CRLFAtTheEnd implements Reason
{
const CODE = 149;
const REASON = "CRLF at the end";
public const CODE = 149;
public const REASON = "CRLF at the end";
public function code() : int
{
+1 -1
View File
@@ -13,4 +13,4 @@ class CharNotAllowed implements Reason
{
return "Character not allowed";
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class CommaInDomain implements Reason
{
return "Comma ',' is not allowed in domain part";
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class CommentsInIDRight implements Reason
{
return 'Comments are not allowed in IDRight for message-id';
}
}
}
+1 -1
View File
@@ -10,4 +10,4 @@ abstract class DetailedReason implements Reason
{
$this->detailedDescription = $details;
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class DomainAcceptsNoMail implements Reason
{
return 'Domain accepts no mail (Null MX, RFC7505)';
}
}
}
+1 -1
View File
@@ -23,4 +23,4 @@ class ExceptionFound implements Reason
{
return $this->exception->getMessage();
}
}
}
@@ -13,4 +13,4 @@ class ExpectingDomainLiteralClose implements Reason
{
return "Closing bracket ']' for domain literal not found";
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class LocalOrReservedDomain implements Reason
{
return 'Local, mDNS or reserved domain (RFC2606, RFC6762)';
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class NoDNSRecord implements Reason
{
return 'No MX or A DSN record was found for this email';
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ interface Reason
* Short description of the result, human readable.
*/
public function description() : string;
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ class UnOpenedComment implements Reason
{
return 'Missing opening comment parentheses - https://tools.ietf.org/html/rfc5322#section-3.2.2';
}
}
}
+1 -1
View File
@@ -23,4 +23,4 @@ class UnusualElements implements Reason
{
return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element;
}
}
}
+1 -1
View File
@@ -24,4 +24,4 @@ interface Result
* Code for user land to act upon.
*/
public function code() : int;
}
}
+1 -2
View File
@@ -1,7 +1,6 @@
<?php
namespace Egulias\EmailValidator\Result;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\SpoofEmail as ReasonSpoofEmail;
class SpoofEmail extends InvalidEmail
@@ -11,4 +10,4 @@ class SpoofEmail extends InvalidEmail
$this->reason = new ReasonSpoofEmail();
parent::__construct($this->reason, '');
}
}
}
+1 -1
View File
@@ -24,4 +24,4 @@ class ValidEmail implements Result
return 0;
}
}
}
+3 -4
View File
@@ -2,7 +2,6 @@
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail;
@@ -22,7 +21,7 @@ class DNSCheckValidation implements EmailValidation
* Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2),
* mDNS and private DNS Namespaces (https://tools.ietf.org/html/rfc6762#appendix-G)
*/
const RESERVED_DNS_TOP_LEVEL_NAMES = [
public const RESERVED_DNS_TOP_LEVEL_NAMES = [
// Reserved Top Level DNS Names
'test',
'example',
@@ -61,7 +60,7 @@ class DNSCheckValidation implements EmailValidation
*/
private $dnsGetRecord;
public function __construct(DNSGetRecordWrapper $dnsGetRecord = null)
public function __construct(?DNSGetRecordWrapper $dnsGetRecord = null)
{
if (!function_exists('idn_to_ascii')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
@@ -189,4 +188,4 @@ class DNSCheckValidation implements EmailValidation
return true;
}
}
}
+1 -1
View File
@@ -25,4 +25,4 @@ class DNSGetRecordWrapper
restore_error_handler();
}
}
}
}
+1 -1
View File
@@ -32,4 +32,4 @@ class DNSRecords
}
}
}
@@ -9,7 +9,7 @@ class EmptyValidationList extends \InvalidArgumentException
/**
* @param int $code
*/
public function __construct($code = 0, Exception $previous = null)
public function __construct($code = 0, ?Exception $previous = null)
{
parent::__construct("Empty validation list is not allowed", $code, $previous);
}
+2 -2
View File
@@ -13,13 +13,13 @@ class MultipleValidationWithAnd implements EmailValidation
* If one of validations fails, the remaining validations will be skipped.
* This means MultipleErrors will only contain a single error, the first found.
*/
const STOP_ON_ERROR = 0;
public const STOP_ON_ERROR = 0;
/**
* All of validations will be invoked even if one of them got failure.
* So MultipleErrors will contain all causes.
*/
const ALLOW_ALL_ERRORS = 1;
public const ALLOW_ALL_ERRORS = 1;
/**
* @var EmailValidation[]
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class AddressLiteral extends Warning
{
const CODE = 12;
public const CODE = 12;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class CFWSNearAt extends Warning
{
const CODE = 49;
public const CODE = 49;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class CFWSWithFWS extends Warning
{
const CODE = 18;
public const CODE = 18;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class Comment extends Warning
{
const CODE = 17;
public const CODE = 17;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class DeprecatedComment extends Warning
{
const CODE = 37;
public const CODE = 37;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class DomainLiteral extends Warning
{
const CODE = 70;
public const CODE = 70;
public function __construct()
{
+1 -1
View File
@@ -6,7 +6,7 @@ use Egulias\EmailValidator\EmailParser;
class EmailTooLong extends Warning
{
const CODE = 66;
public const CODE = 66;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6BadChar extends Warning
{
const CODE = 74;
public const CODE = 74;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6ColonEnd extends Warning
{
const CODE = 77;
public const CODE = 77;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6ColonStart extends Warning
{
const CODE = 76;
public const CODE = 76;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6Deprecated extends Warning
{
const CODE = 13;
public const CODE = 13;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6DoubleColon extends Warning
{
const CODE = 73;
public const CODE = 73;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6GroupCount extends Warning
{
const CODE = 72;
public const CODE = 72;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6MaxGroups extends Warning
{
const CODE = 75;
public const CODE = 75;
public function __construct()
{
+2 -2
View File
@@ -4,8 +4,8 @@ namespace Egulias\EmailValidator\Warning;
class LocalTooLong extends Warning
{
const CODE = 64;
const LOCAL_PART_LENGTH = 64;
public const CODE = 64;
public const LOCAL_PART_LENGTH = 64;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class NoDNSMXRecord extends Warning
{
const CODE = 6;
public const CODE = 6;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class ObsoleteDTEXT extends Warning
{
const CODE = 71;
public const CODE = 71;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class QuotedPart extends Warning
{
const CODE = 36;
public const CODE = 36;
/**
* @param scalar $prevToken
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class QuotedString extends Warning
{
const CODE = 11;
public const CODE = 11;
/**
* @param scalar $prevToken
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class TLD extends Warning
{
const CODE = 9;
public const CODE = 9;
public function __construct()
{
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
abstract class Warning
{
const CODE = 0;
public const CODE = 0;
/**
* @var string