From 80718556f06ba819497f4eb3d8e28f58e6aa245f Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Mon, 22 Sep 2014 23:01:44 +0100 Subject: [PATCH] Issue #2313669 by dawehner, hussainweb, pfrenssen: Bring in egulias/EmailValidator for RFC compliant email address validation. --- composer.json | 3 +- composer.lock | 52 +- core/vendor/composer/autoload_namespaces.php | 1 + core/vendor/composer/installed.json | 52 ++ .../egulias/email-validator/.coveralls.yml | 3 + .../egulias/email-validator/.travis.yml | 20 + core/vendor/egulias/email-validator/LICENSE | 19 + core/vendor/egulias/email-validator/README.md | 51 ++ .../egulias/email-validator/composer.json | 28 + .../egulias/email-validator/composer.lock | 589 ++++++++++++++++++ .../email-validator/documentation/Ohter.md | 69 ++ .../documentation/RFC5321BNF.html | 89 +++ .../documentation/RFC5322BNF.html | 141 +++++ .../egulias/email-validator/phpunit.xml.dist | 26 + .../src/Egulias/EmailValidator/EmailLexer.php | 159 +++++ .../Egulias/EmailValidator/EmailParser.php | 87 +++ .../Egulias/EmailValidator/EmailValidator.php | 178 ++++++ .../EmailValidator/Parser/DomainPart.php | 299 +++++++++ .../EmailValidator/Parser/LocalPart.php | 94 +++ .../Egulias/EmailValidator/Parser/Parser.php | 190 ++++++ .../email-validator/tests/bootstrap.php | 8 + .../egulias/Performance/AgainstFilterVar.php | 33 + .../egulias/Performance/AgainstOldIsemail.php | 34 + .../Tests/EmailValidator/EmailLexerTest.php | 80 +++ .../EmailValidator/EmailValidatorTest.php | 280 +++++++++ 25 files changed, 2583 insertions(+), 2 deletions(-) create mode 100644 core/vendor/egulias/email-validator/.coveralls.yml create mode 100644 core/vendor/egulias/email-validator/.travis.yml create mode 100644 core/vendor/egulias/email-validator/LICENSE create mode 100644 core/vendor/egulias/email-validator/README.md create mode 100644 core/vendor/egulias/email-validator/composer.json create mode 100644 core/vendor/egulias/email-validator/composer.lock create mode 100644 core/vendor/egulias/email-validator/documentation/Ohter.md create mode 100644 core/vendor/egulias/email-validator/documentation/RFC5321BNF.html create mode 100644 core/vendor/egulias/email-validator/documentation/RFC5322BNF.html create mode 100644 core/vendor/egulias/email-validator/phpunit.xml.dist create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailParser.php create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php create mode 100644 core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php create mode 100644 core/vendor/egulias/email-validator/tests/bootstrap.php create mode 100644 core/vendor/egulias/email-validator/tests/egulias/Performance/AgainstFilterVar.php create mode 100644 core/vendor/egulias/email-validator/tests/egulias/Performance/AgainstOldIsemail.php create mode 100644 core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailLexerTest.php create mode 100644 core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailValidatorTest.php diff --git a/composer.json b/composer.json index 9120f56b7b6..74cff7ff4a4 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,8 @@ "phpunit/phpunit-mock-objects": "dev-master#e60bb929c50ae4237aaf680a4f6773f4ee17f0a2", "zendframework/zend-feed": "2.2.*", "mikey179/vfsStream": "1.*", - "stack/builder": "1.0.*" + "stack/builder": "1.0.*", + "egulias/email-validator": "1.2.*" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index a6bab03d9f0..a40cb492073 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7d34fdcf5f05caf22258954b560e70f6", + "hash": "9b3b0c6ca08a325572fdeb2865e85c0a", "packages": [ { "name": "doctrine/annotations", @@ -458,6 +458,56 @@ ], "time": "2013-12-30 22:31:37" }, + { + "name": "egulias/email-validator", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/39b451bb2bb0655d83d82a38a0bba7189298cfc5", + "reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "~1.0", + "php": ">= 5.3.3" + }, + "require-dev": { + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Egulias\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "validation", + "validator" + ], + "time": "2014-09-01 22:35:48" + }, { "name": "guzzlehttp/guzzle", "version": "4.1.7", diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php index 5bb8438c1b1..e506f986e14 100644 --- a/core/vendor/composer/autoload_namespaces.php +++ b/core/vendor/composer/autoload_namespaces.php @@ -29,6 +29,7 @@ return array( 'Stack' => array($vendorDir . '/stack/builder/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log'), 'Gliph' => array($vendorDir . '/sdboyer/gliph/src'), + 'Egulias\\' => array($vendorDir . '/egulias/email-validator/src'), 'EasyRdf_' => array($vendorDir . '/easyrdf/easyrdf/lib'), 'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'), 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'), diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index f146fd9ca59..168a4ae4e7e 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -2565,5 +2565,57 @@ "docblock", "parser" ] + }, + { + "name": "egulias/email-validator", + "version": "1.2.2", + "version_normalized": "1.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/39b451bb2bb0655d83d82a38a0bba7189298cfc5", + "reference": "39b451bb2bb0655d83d82a38a0bba7189298cfc5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "~1.0", + "php": ">= 5.3.3" + }, + "require-dev": { + "satooshi/php-coveralls": "dev-master" + }, + "time": "2014-09-01 22:35:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Egulias\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "validation", + "validator" + ] } ] diff --git a/core/vendor/egulias/email-validator/.coveralls.yml b/core/vendor/egulias/email-validator/.coveralls.yml new file mode 100644 index 00000000000..143c1978b49 --- /dev/null +++ b/core/vendor/egulias/email-validator/.coveralls.yml @@ -0,0 +1,3 @@ +service_name: travis-ci +src_dir: . +coverage_clover: build/logs/clover*.xml diff --git a/core/vendor/egulias/email-validator/.travis.yml b/core/vendor/egulias/email-validator/.travis.yml new file mode 100644 index 00000000000..d3583de4534 --- /dev/null +++ b/core/vendor/egulias/email-validator/.travis.yml @@ -0,0 +1,20 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - wget http://getcomposer.org/composer.phar + - php composer.phar install --dev --no-interaction + +script: + - mkdir -p build/logs + - phpunit --coverage-clover build/logs/clover.xml + +after_script: + - php vendor/bin/coveralls + diff --git a/core/vendor/egulias/email-validator/LICENSE b/core/vendor/egulias/email-validator/LICENSE new file mode 100644 index 00000000000..de4a25bfa7f --- /dev/null +++ b/core/vendor/egulias/email-validator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 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 +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/core/vendor/egulias/email-validator/README.md b/core/vendor/egulias/email-validator/README.md new file mode 100644 index 00000000000..4bfe310397e --- /dev/null +++ b/core/vendor/egulias/email-validator/README.md @@ -0,0 +1,51 @@ +EmailValidator [![Build Status](https://travis-ci.org/egulias/EmailValidator.png?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.png?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/b18d473e-bd5a-4d88-a7b2-7aeaee0ebd7b/small.png)](https://insight.sensiolabs.com/projects/b18d473e-bd5a-4d88-a7b2-7aeaee0ebd7b)[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) +============================= + +##Installation## +Install via composer. Add to your current compooser.json ```require``` key: ```"egulias/email-validator":"1.0.x-dev" ``` + +##Usage## + +Simple example: + +```php +isValid($email)) { + echo $email . ' is a valid email address'; +} +``` + +More advanced example (returns detailed diagnostic error codes): + +```php +isValid($email); + +if ($result) { + echo $email . ' is a valid email address'; +} else if ($validator->hasWarnings()) { + echo 'Warning! ' . $email . ' has unusual/deprecated features (result code ' . var_export($validator->getWarnings(), true) . ')'; +} else { + echo $email . ' is not a valid email address (result code ' . $validator->getError() . ')'; +} +``` + +##Contributors## +As this is a port from another library and work, here are other people related to the previous: + +* Ricard Clau [@ricardclau](http://github.com/ricardclau): Performance against PHP built-in filter_var +* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib +* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function + +##Licence## +Released under the MIT Licence attached with this code. + diff --git a/core/vendor/egulias/email-validator/composer.json b/core/vendor/egulias/email-validator/composer.json new file mode 100644 index 00000000000..a9961625fa3 --- /dev/null +++ b/core/vendor/egulias/email-validator/composer.json @@ -0,0 +1,28 @@ +{ + "name": "egulias/email-validator", + "description": "A library for validating emails", + "homepage": "https://github.com/egulias/EmailValidator", + "type": "Library", + "keywords": ["email", "validation", "validator"], + "license": "MIT", + "authors": [ + {"name": "Eduardo Gulias Davis"} + ], + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "require": { + "php": ">= 5.3.3", + "doctrine/lexer": "~1.0" + }, + "require-dev" : { + "satooshi/php-coveralls": "dev-master" + }, + "autoload": { + "psr-0": { + "Egulias\\": "src/" + } + } +} diff --git a/core/vendor/egulias/email-validator/composer.lock b/core/vendor/egulias/email-validator/composer.lock new file mode 100644 index 00000000000..e7c1abdf683 --- /dev/null +++ b/core/vendor/egulias/email-validator/composer.lock @@ -0,0 +1,589 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], + "hash": "cca347a6b95164b1121e034b95f824ec", + "packages": [ + { + "name": "doctrine/lexer", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "2f708a85bb3aab5d99dab8be435abd73e0b18acb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/2f708a85bb3aab5d99dab8be435abd73e0b18acb", + "reference": "2f708a85bb3aab5d99dab8be435abd73e0b18acb", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com", + "homepage": "http://www.instaclick.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "http://jmsyst.com", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2013-01-12 18:59:04" + } + ], + "packages-dev": [ + { + "name": "guzzle/guzzle", + "version": "v3.9.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "92d9934f2fca1da15178c91239576ae26e505e60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/92d9934f2fca1da15178c91239576ae26e505e60", + "reference": "92d9934f2fca1da15178c91239576ae26e505e60", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.8-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2014-05-07 17:04:22" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "satooshi/php-coveralls", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/satooshi/php-coveralls.git", + "reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/b7271847c84d160f5b0aae83e45c225e8ffc96f4", + "reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzle/guzzle": ">=3.0", + "php": ">=5.3", + "psr/log": "1.0.0", + "symfony/config": ">=2.0", + "symfony/console": ">=2.0", + "symfony/stopwatch": ">=2.2", + "symfony/yaml": ">=2.0" + }, + "require-dev": { + "apigen/apigen": "2.8.*@stable", + "pdepend/pdepend": "dev-master", + "phpmd/phpmd": "dev-master", + "phpunit/php-invoker": ">=1.1.0,<1.2.0", + "phpunit/phpunit": "3.7.*@stable", + "sebastian/finder-facade": "dev-master", + "sebastian/phpcpd": "1.4.*@stable", + "squizlabs/php_codesniffer": "1.4.*@stable", + "theseer/fdomdocument": "dev-master" + }, + "suggest": { + "symfony/http-kernel": "Allows Symfony integration" + }, + "bin": [ + "composer/bin/coveralls" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.7-dev" + } + }, + "autoload": { + "psr-0": { + "Satooshi\\Component": "src/", + "Satooshi\\Bundle": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/satooshi/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "time": "2014-05-14 13:09:37" + }, + { + "name": "symfony/config", + "version": "v2.4.5", + "target-dir": "Symfony/Component/Config", + "source": { + "type": "git", + "url": "https://github.com/symfony/Config.git", + "reference": "2effc67af6f21a0d267210b72d0b0b691d113528" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Config/zipball/2effc67af6f21a0d267210b72d0b0b691d113528", + "reference": "2effc67af6f21a0d267210b72d0b0b691d113528", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/filesystem": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "http://symfony.com", + "time": "2014-04-22 08:11:06" + }, + { + "name": "symfony/console", + "version": "v2.4.5", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "24f723436e62598c9dddee2a8573d6992504dc5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/24f723436e62598c9dddee2a8573d6992504dc5d", + "reference": "24f723436e62598c9dddee2a8573d6992504dc5d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/event-dispatcher": "~2.1" + }, + "suggest": { + "symfony/event-dispatcher": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2014-05-14 21:48:29" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.4.5", + "target-dir": "Symfony/Component/EventDispatcher", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "e539602e5455aa086c0e81e604745af7789e4d8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e539602e5455aa086c0e81e604745af7789e4d8a", + "reference": "e539602e5455aa086c0e81e604745af7789e4d8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/dependency-injection": "~2.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2014-04-16 10:34:31" + }, + { + "name": "symfony/filesystem", + "version": "v2.4.5", + "target-dir": "Symfony/Component/Filesystem", + "source": { + "type": "git", + "url": "https://github.com/symfony/Filesystem.git", + "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a3af8294bcce4a7c1b2892363b0c9d8109affad4", + "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "http://symfony.com", + "time": "2014-04-16 10:34:31" + }, + { + "name": "symfony/stopwatch", + "version": "v2.4.5", + "target-dir": "Symfony/Component/Stopwatch", + "source": { + "type": "git", + "url": "https://github.com/symfony/Stopwatch.git", + "reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/343bcc0360f2c22f371884b8f6a9fee8d1aa431a", + "reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Stopwatch\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "http://symfony.com", + "time": "2014-04-18 20:37:09" + }, + { + "name": "symfony/yaml", + "version": "v2.4.5", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/fd22bb88c3a6f73c898b39bec185a9e211b06265", + "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2014-05-12 09:27:48" + } + ], + "aliases": [ + + ], + "minimum-stability": "stable", + "stability-flags": { + "satooshi/php-coveralls": 20 + }, + "platform": { + "php": ">= 5.3.3" + }, + "platform-dev": [ + + ] +} diff --git a/core/vendor/egulias/email-validator/documentation/Ohter.md b/core/vendor/egulias/email-validator/documentation/Ohter.md new file mode 100644 index 00000000000..9ec4bd9e554 --- /dev/null +++ b/core/vendor/egulias/email-validator/documentation/Ohter.md @@ -0,0 +1,69 @@ +Email length +------------ +http://tools.ietf.org/html/rfc5321#section-4.1.2 + Forward-path = Path + + Path = "<" [ A-d-l ":" ] Mailbox ">" + +http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3 +http://tools.ietf.org/html/rfc1035#section-2.3.4 + +DNS +--- + +http://tools.ietf.org/html/rfc5321#section-2.3.5 + Names that can + be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed + in Section 5) are permitted, as are CNAME RRs whose targets can be + resolved, in turn, to MX or address RRs. + +http://tools.ietf.org/html/rfc5321#section-5.1 + The lookup first attempts to locate an MX record associated with the + name. If a CNAME record is found, the resulting name is processed as + if it were the initial name. ... If an empty list of MXs is returned, + the address is treated as if it was associated with an implicit MX + RR, with a preference of 0, pointing to that host. + +is_email() author's note: We will regard the existence of a CNAME to be +sufficient evidence of the domain's existence. For performance reasons +we will not repeat the DNS lookup for the CNAME's target, but we will +raise a warning because we didn't immediately find an MX record. + +Check for TLD addresses +----------------------- +TLD addresses are specifically allowed in RFC 5321 but they are +unusual to say the least. We will allocate a separate +status to these addresses on the basis that they are more likely +to be typos than genuine addresses (unless we've already +established that the domain does have an MX record) + +http://tools.ietf.org/html/rfc5321#section-2.3.5 + In the case + of a top-level domain used by itself in an email address, a single + string is used without any dots. This makes the requirement, + described in more detail below, that only fully-qualified domain + names appear in SMTP transactions on the public Internet, + particularly important where top-level domains are involved. + +TLD format +---------- +The format of TLDs has changed a number of times. The standards +used by IANA have been largely ignored by ICANN, leading to +confusion over the standards being followed. These are not defined +anywhere, except as a general component of a DNS host name (a label). +However, this could potentially lead to 123.123.123.123 being a +valid DNS name (rather than an IP address) and thereby creating +an ambiguity. The most authoritative statement on TLD formats that +the author can find is in a (rejected!) erratum to RFC 1123 +submitted by John Klensin, the author of RFC 5321: + +http://www.rfc-editor.org/errata_search.php?rfc=1123&eid=1353 + However, a valid host name can never have the dotted-decimal + form #.#.#.#, since this change does not permit the highest-level + component label to start with a digit even if it is not all-numeric. + +Comments +-------- +Comments at the start of the domain are deprecated in the text +Comments at the start of a subdomain are obs-domain +(http://tools.ietf.org/html/rfc5322#section-3.4.1) diff --git a/core/vendor/egulias/email-validator/documentation/RFC5321BNF.html b/core/vendor/egulias/email-validator/documentation/RFC5321BNF.html new file mode 100644 index 00000000000..2313f01eb3e --- /dev/null +++ b/core/vendor/egulias/email-validator/documentation/RFC5321BNF.html @@ -0,0 +1,89 @@ + + + + + +The BNF from RFC 5321 defining parts of a valid SMTP address + + + +
+   Mailbox        = Local-part "@" ( Domain / address-literal )
+
+   Local-part     = Dot-string / Quoted-string
+                  ; MAY be case-sensitive
+
+
+   Dot-string     = Atom *("."  Atom)
+
+   Atom           = 1*atext
+
+   Quoted-string  = DQUOTE *QcontentSMTP DQUOTE
+
+   QcontentSMTP   = qtextSMTP / quoted-pairSMTP
+
+   quoted-pairSMTP  = %d92 %d32-126
+                    ; i.e., backslash followed by any ASCII
+                    ; graphic (including itself) or SPace
+
+   qtextSMTP      = %d32-33 / %d35-91 / %d93-126
+                  ; i.e., within a quoted string, any
+                  ; ASCII graphic or space is permitted
+                  ; without blackslash-quoting except
+                  ; double-quote and the backslash itself.
+
+   Domain         = sub-domain *("." sub-domain)
+
+   sub-domain     = Let-dig [Ldh-str]
+
+   Let-dig        = ALPHA / DIGIT
+
+   Ldh-str        = *( ALPHA / DIGIT / "-" ) Let-dig
+
+   address-literal  = "[" ( IPv4-address-literal /
+                    IPv6-address-literal /
+                    General-address-literal ) "]"
+                    ; See Section 4.1.3
+
+   IPv4-address-literal  = Snum 3("."  Snum)
+
+   IPv6-address-literal  = "IPv6:" IPv6-addr
+
+   General-address-literal  = Standardized-tag ":" 1*dcontent
+
+   Standardized-tag  = Ldh-str
+                     ; Standardized-tag MUST be specified in a
+                     ; Standards-Track RFC and registered with IANA
+
+   dcontent       = %d33-90 / ; Printable US-ASCII
+                  %d94-126 ; excl. "[", "\", "]"
+
+   Snum           = 1*3DIGIT
+                  ; representing a decimal integer
+                  ; value in the range 0 through 255
+
+   IPv6-addr      = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
+
+   IPv6-hex       = 1*4HEXDIG
+
+   IPv6-full      = IPv6-hex 7(":" IPv6-hex)
+
+   IPv6-comp      = [IPv6-hex *5(":" IPv6-hex)] "::"
+                  [IPv6-hex *5(":" IPv6-hex)]
+                  ; The "::" represents at least 2 16-bit groups of
+                  ; zeros.  No more than 6 groups in addition to the
+                  ; "::" may be present.
+
+   IPv6v4-full    = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
+
+   IPv6v4-comp    = [IPv6-hex *3(":" IPv6-hex)] "::"
+                  [IPv6-hex *3(":" IPv6-hex) ":"]
+                  IPv4-address-literal
+                  ; The "::" represents at least 2 16-bit groups of
+                  ; zeros.  No more than 4 groups in addition to the
+                  ; "::" and IPv4-address-literal may be present.
+
+
+ + + diff --git a/core/vendor/egulias/email-validator/documentation/RFC5322BNF.html b/core/vendor/egulias/email-validator/documentation/RFC5322BNF.html new file mode 100644 index 00000000000..e2f8fd7331f --- /dev/null +++ b/core/vendor/egulias/email-validator/documentation/RFC5322BNF.html @@ -0,0 +1,141 @@ + + + + + +The BNF from RFC 5322 defining parts of a valid internet message address + + + +
+   addr-spec       =   local-part "@" domain
+
+   local-part      =   dot-atom / quoted-string / obs-local-part
+
+   dot-atom        =   [CFWS] dot-atom-text [CFWS]
+
+   CFWS            =   (1*([FWS] comment) [FWS]) / FWS
+
+   FWS             =   ([*WSP CRLF] 1*WSP) /  obs-FWS
+                                          ; Folding white space
+
+   WSP             =   SP / HTAB          ; white space
+
+   obs-FWS         =   1*([CRLF] WSP)     ; As amended in erratum #1908
+
+   ctext           =   %d33-39 /          ; Printable US-ASCII
+                       %d42-91 /          ;  characters not including
+                       %d93-126 /         ;  "(", ")", or "\"
+                       obs-ctext
+
+   obs-ctext       =   obs-NO-WS-CTL
+   ccontent        =   ctext / quoted-pair / comment
+
+   comment         =   "(" *([FWS] ccontent) [FWS] ")"
+
+   dot-atom-text   =   1*atext *("." 1*atext)
+
+   atext           =   ALPHA / DIGIT /    ; Printable US-ASCII
+                       "!" / "#" /        ;  characters not including
+                       "$" / "%" /        ;  specials.  Used for atoms.
+                       "&" / "'" /
+                       "*" / "+" /
+                       "-" / "/" /
+                       "=" / "?" /
+                       "^" / "_" /
+                       "`" / "{" /
+                       "|" / "}" /
+                       "~"
+
+   specials        =   "(" / ")" /        ; Special characters that do
+                       "<" / ">" /        ;  not appear in atext
+                       "[" / "]" /
+                       ":" / ";" /
+                       "@" / "\" /
+                       "," / "." /
+                       DQUOTE
+
+   quoted-string   =   [CFWS]
+                       DQUOTE *([FWS] qcontent) [FWS] DQUOTE
+                       [CFWS]
+
+   qcontent        =   qtext / quoted-pair
+
+   qtext           =   %d33 /             ; Printable US-ASCII
+                       %d35-91 /          ;  characters not including
+                       %d93-126 /         ;  "\" or the quote character
+                       obs-qtext
+
+   obs-qtext       =   obs-NO-WS-CTL
+
+   obs-NO-WS-CTL   =   %d1-8 /            ; US-ASCII control
+                       %d11 /             ;  characters that do not
+                       %d12 /             ;  include the carriage
+                       %d14-31 /          ;  return, line feed, and
+                       %d127              ;  white space characters
+
+   quoted-pair     =   ("\" (VCHAR / WSP)) / obs-qp
+
+   VCHAR           =   %x21-7E            ; visible (printing) characters
+
+   obs-qp          =   "\" (%d0 / obs-NO-WS-CTL / LF / CR)
+
+   obs-local-part  =   word *("." word)
+
+   word            =   atom / quoted-string
+
+   atom            =   [CFWS] 1*atext [CFWS]
+
+   domain          =   dot-atom / domain-literal / obs-domain
+
+   domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
+
+   dtext           =   %d33-90 /          ; Printable US-ASCII
+                       %d94-126 /         ;  characters not including
+                       obs-dtext          ;  "[", "]", or "\"
+
+   obs-dtext       =   obs-NO-WS-CTL / quoted-pair
+
+   obs-domain      =   atom *("." atom)
+
+NB For SMTP mail, the domain-literal is restricted by RFC5321 as follows:
+
+   Mailbox        = Local-part "@" ( Domain / address-literal )
+
+   address-literal  = "[" ( IPv4-address-literal /
+                    IPv6-address-literal /
+                    General-address-literal ) "]"
+
+   IPv4-address-literal  = Snum 3("."  Snum)
+
+   IPv6-address-literal  = "IPv6:" IPv6-addr
+
+   Snum           = 1*3DIGIT
+                  ; representing a decimal integer
+                  ; value in the range 0 through 255
+
+   IPv6-addr      = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
+
+   IPv6-hex       = 1*4HEXDIG
+
+   IPv6-full      = IPv6-hex 7(":" IPv6-hex)
+
+   IPv6-comp      = [IPv6-hex *5(":" IPv6-hex)] "::"
+                  [IPv6-hex *5(":" IPv6-hex)]
+                  ; The "::" represents at least 2 16-bit groups of
+                  ; zeros.  No more than 6 groups in addition to the
+                  ; "::" may be present.
+
+   IPv6v4-full    = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
+
+   IPv6v4-comp    = [IPv6-hex *3(":" IPv6-hex)] "::"
+                  [IPv6-hex *3(":" IPv6-hex) ":"]
+                  IPv4-address-literal
+                  ; The "::" represents at least 2 16-bit groups of
+                  ; zeros.  No more than 4 groups in addition to the
+                  ; "::" and IPv4-address-literal may be present.
+
+
+ + + diff --git a/core/vendor/egulias/email-validator/phpunit.xml.dist b/core/vendor/egulias/email-validator/phpunit.xml.dist new file mode 100644 index 00000000000..f335ec1d5f5 --- /dev/null +++ b/core/vendor/egulias/email-validator/phpunit.xml.dist @@ -0,0 +1,26 @@ + + + + + + ./tests/egulias/Tests/ + ./vendor/ + + + + + + ./vendor + + + diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php new file mode 100644 index 00000000000..721190fdd00 --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php @@ -0,0 +1,159 @@ + self::S_OPENPARENTHESIS, + ')' => self::S_CLOSEPARENTHESIS, + '<' => self::S_LOWERTHAN, + '>' => self::S_GREATERTHAN, + '[' => self::S_OPENBRACKET, + ']' => self::S_CLOSEBRACKET, + ':' => self::S_COLON, + ';' => self::S_SEMICOLON, + '@' => self::S_AT, + '\\' => self::S_BACKSLASH, + ',' => self::S_COMMA, + '.' => self::S_DOT, + '"' => self::S_DQUOTE, + '-' => self::S_HYPHEN, + '::' => self::S_DOUBLECOLON, + ' ' => self::S_SP, + "\t" => self::S_HTAB, + "\r" => self::S_CR, + "\n" => self::S_LF, + "\r\n" => self::CRLF, + 'IPv6' => self::S_IPV6TAG, + '<' => self::S_LOWERTHAN, + '>' => self::S_GREATERTHAN, + '{' => self::S_OPENQBRACKET, + '}' => self::S_CLOSEQBRACKET, + '' => self::S_EMPTY + ); + + protected $previous; + + /** + * @param $type + * @throws \UnexpectedValueException + */ + public function find($type) + { + $search = clone $this; + $search->skipUntil($type); + + if (!$search->lookahead) { + throw new \UnexpectedValueException($type . ' not found'); + } + return true; + } + + /** + * getPrevious + * + * @return array token + */ + public function getPrevious() + { + return $this->previous; + } + + /** + * moveNext + * + * @return mixed + */ + public function moveNext() + { + $this->previous = $this->token; + + return parent::moveNext(); + } + + /** + * Lexical catchable patterns. + * + * @return array + */ + protected function getCatchablePatterns() + { + return array( + '[a-zA-Z_]+[46]?', + '[0-9]+', + '\r\n', + '::', + '\s+', + '[\x10-\x1F]+', + '.', + ); + } + + /** + * Lexical non-catchable patterns. + * + * @return array + */ + protected function getNonCatchablePatterns() + { + return array('[\x7f-\xff]+'); + } + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @param string $value + * @throws \InvalidArgumentException + * @return integer + */ + protected function getType(&$value) + { + if (isset($this->charValue[$value])) { + return $this->charValue[$value]; + } + + if (preg_match('/[\x10-\x1F]+/', $value)) { + return self::INVALID; + } + + return self::GENERIC; + } +} diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailParser.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailParser.php new file mode 100644 index 00000000000..cfb9ce954d8 --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailParser.php @@ -0,0 +1,87 @@ + + */ +class EmailParser +{ + const EMAIL_MAX_LENGTH = 254; + + protected $warnings = array(); + protected $domainPart = ''; + protected $localPart = ''; + protected $lexer; + protected $localPartParser; + protected $domainPartParser; + + public function __construct(EmailLexer $lexer) + { + $this->lexer = $lexer; + $this->localPartParser = new LocalPart($this->lexer); + $this->domainPartParser = new DomainPart($this->lexer); + } + + public function parse($str) + { + $this->lexer->setInput($str); + + if (!$this->hasAtToken()) { + throw new \InvalidArgumentException('ERR_NOLOCALPART'); + } + + $this->localPartParser->parse($str); + $this->domainPartParser->parse($str); + + $this->setParts($str); + + return array('local' => $this->localPart, 'domain' => $this->domainPart); + } + + public function getWarnings() + { + $localPartWarnings = $this->localPartParser->getWarnings(); + $domainPartWarnings = $this->domainPartParser->getWarnings(); + + $this->warnings = array_merge($localPartWarnings, $domainPartWarnings); + $this->addLongEmailWarning($this->localPart, $this->domainPart); + + return $this->warnings; + } + + public function getParsedDomainPart() + { + return $this->domainPart; + } + + protected function setParts($email) + { + $parts = explode('@', $email); + $this->domainPart = $this->domainPartParser->getDomainPart(); + $this->localPart = $parts[0]; + } + + protected function hasAtToken() + { + $this->lexer->moveNext(); + $this->lexer->moveNext(); + if ($this->lexer->token['type'] === EmailLexer::S_AT) { + return false; + } + + return true; + } + + protected function addLongEmailWarning($localPart, $parsedDomainPart) + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { + $this->warnings[] = EmailValidator::RFC5322_TOOLONG; + } + } +} diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php new file mode 100644 index 00000000000..34da6364e0d --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php @@ -0,0 +1,178 @@ + + */ +class EmailValidator +{ + const ERR_CONSECUTIVEATS = 128; + const ERR_EXPECTING_DTEXT = 129; + const ERR_NOLOCALPART = 130; + const ERR_NODOMAIN = 131; + const ERR_CONSECUTIVEDOTS = 132; + const ERR_ATEXT_AFTER_CFWS = 133; + const ERR_ATEXT_AFTER_QS = 134; + const ERR_ATEXT_AFTER_DOMLIT = 135; + const ERR_EXPECTING_QPAIR = 136; + const ERR_EXPECTING_ATEXT = 137; + const ERR_EXPECTING_QTEXT = 138; + const ERR_EXPECTING_CTEXT = 139; + const ERR_BACKSLASHEND = 140; + const ERR_DOT_START = 141; + const ERR_DOT_END = 142; + const ERR_DOMAINHYPHENSTART = 143; + const ERR_DOMAINHYPHENEND = 144; + const ERR_UNCLOSEDQUOTEDSTR = 145; + const ERR_UNCLOSEDCOMMENT = 146; + const ERR_UNCLOSEDDOMLIT = 147; + const ERR_FWS_CRLF_X2 = 148; + const ERR_FWS_CRLF_END = 149; + const ERR_CR_NO_LF = 150; + const ERR_DEPREC_REACHED = 151; + const RFC5321_TLD = 9; + const RFC5321_TLDNUMERIC = 10; + const RFC5321_QUOTEDSTRING = 11; + const RFC5321_ADDRESSLITERAL = 12; + const RFC5321_IPV6DEPRECATED = 13; + const CFWS_COMMENT = 17; + const CFWS_FWS = 18; + const DEPREC_LOCALPART = 33; + const DEPREC_FWS = 34; + const DEPREC_QTEXT = 35; + const DEPREC_QP = 36; + const DEPREC_COMMENT = 37; + const DEPREC_CTEXT = 38; + const DEPREC_CFWS_NEAR_AT = 49; + const RFC5322_LOCAL_TOOLONG = 64; + const RFC5322_LABEL_TOOLONG = 63; + const RFC5322_DOMAIN = 65; + const RFC5322_TOOLONG = 66; + const RFC5322_DOMAIN_TOOLONG = 255; + const RFC5322_DOMAINLITERAL = 70; + const RFC5322_DOMLIT_OBSDTEXT = 71; + const RFC5322_IPV6_GRPCOUNT = 72; + const RFC5322_IPV6_2X2XCOLON = 73; + const RFC5322_IPV6_BADCHAR = 74; + const RFC5322_IPV6_MAXGRPS = 75; + const RFC5322_IPV6_COLONSTRT = 76; + const RFC5322_IPV6_COLONEND = 77; + const DNSWARN_NO_MX_RECORD = 5; + const DNSWARN_NO_RECORD = 6; + + protected $parser; + protected $warnings = array(); + protected $error; + protected $threshold = 255; + + public function __construct() + { + $this->parser = new EmailParser(new EmailLexer()); + } + + public function isValid($email, $checkDNS = false, $strict = false) + { + try { + $this->parser->parse((string)$email); + $this->warnings = $this->parser->getWarnings(); + } catch (\Exception $e) { + $rClass = new \ReflectionClass($this); + $this->error = $rClass->getConstant($e->getMessage()); + return false; + } + + $dns = true; + if ($checkDNS) { + $dns = $this->checkDNS(); + } + + if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) { + $this->error = self::ERR_DEPREC_REACHED; + + return false; + } + + return ($strict) ? (!$this->hasWarnings() && $dns) : true; + } + + /** + * @return boolean + */ + public function hasWarnings() + { + return !empty($this->warnings); + } + + /** + * @return array + */ + public function getWarnings() + { + return $this->warnings; + } + + /** + * @return string + */ + public function getError() + { + return $this->error; + } + + /** + * @param int $threshold + * + * @return EmailValidator + */ + public function setThreshold($threshold) + { + $this->threshold = (int) $threshold; + + return $this; + } + + /** + * @return int + */ + public function getThreshold() + { + return $this->threshold; + } + + protected function checkDNS() + { + $checked = false; + if (!function_exists('dns_get_record') && ( + in_array(self::DNSWARN_NO_RECORD, $this->warnings) && + in_array(self::DNSWARN_NO_MX_RECORD, $this->warnings) + )) { + return $checked; + } + + $result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX'); + $checked = true; + + if (!$result) { + $this->warnings[] = self::DNSWARN_NO_RECORD; + $checked = false; + $this->addTLDWarnings(); + } + + return $checked; + } + + protected function addTLDWarnings() + { + if (!in_array(self::DNSWARN_NO_RECORD, $this->warnings) && + !in_array(self::DNSWARN_NO_MX_RECORD, $this->warnings) && + in_array(self::RFC5322_DOMAINLITERAL, $this->warnings) + ) { + $this->warnings[] = self::RFC5321_TLD; + } + } +} diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php new file mode 100644 index 00000000000..d622b947e0f --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php @@ -0,0 +1,299 @@ +lexer->moveNext(); + + if ($this->lexer->token['type'] === EmailLexer::S_DOT) { + throw new \InvalidArgumentException('ERR_DOT_START'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) { + throw new \InvalidArgumentException('ERR_NODOMAIN'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { + $this->warnings[] = EmailValidator::DEPREC_COMMENT; + $this->parseDomainComments(); + } + + $domain = $this->doParseDomainPart(); + + $prev = $this->lexer->getPrevious(); + $length = strlen($domain); + + if ($prev['type'] === EmailLexer::S_DOT) { + throw new \InvalidArgumentException('ERR_DOT_END'); + } + if ($prev['type'] === EmailLexer::S_HYPHEN) { + throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND'); + } + if ($length > self::DOMAIN_MAX_LENGTH) { + $this->warnings[] = EmailValidator::RFC5322_DOMAIN_TOOLONG; + } + if ($prev['type'] === EmailLexer::S_CR) { + throw new \InvalidArgumentException('ERR_FWS_CRLF_END'); + } + $this->domainPart = $domain; + } + + public function getDomainPart() + { + return $this->domainPart; + } + + public function checkIPV6Tag($addressLiteral, $maxGroups = 8) + { + $prev = $this->lexer->getPrevious(); + if ($prev['type'] === EmailLexer::S_COLON) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONEND; + } + + $IPv6 = substr($addressLiteral, 5); + //Daniel Marschall's new IPv6 testing strategy + $matchesIP = explode(':', $IPv6); + $groupCount = count($matchesIP); + $colons = strpos($IPv6, '::'); + + if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_BADCHAR; + } + + if ($colons === false) { + // We need exactly the right number of groups + if ($groupCount !== $maxGroups) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_GRPCOUNT; + } + return; + } + + if ($colons !== strrpos($IPv6, '::')) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_2X2XCOLON; + return; + } + + if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { + // RFC 4291 allows :: at the start or end of an address + //with 7 other groups in addition + ++$maxGroups; + } + + if ($groupCount > $maxGroups) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_MAXGRPS; + } elseif ($groupCount === $maxGroups) { + $this->warnings[] = EmailValidator::RFC5321_IPV6DEPRECATED; + } + } + + protected function doParseDomainPart() + { + $domain = ''; + do { + $prev = $this->lexer->getPrevious(); + + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { + $this->parseComments(); + $this->lexer->moveNext(); + } + + $this->checkConsecutiveDots(); + $this->checkDomainPartExceptions($prev); + + if ($this->hasBrackets()) { + $this->parseDomainLiteral(); + } + + $this->checkLabelLength($prev); + + if ($this->isFWS()) { + $this->parseFWS(); + } + + $domain .= $this->lexer->token['value']; + $this->lexer->moveNext(); + } while ($this->lexer->token); + + return $domain; + } + + protected function parseDomainLiteral() + { + if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT; + } + if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { + $lexer = clone $this->lexer; + $lexer->moveNext(); + if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { + $this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT; + } + } + + return $this->doParseDomainLiteral(); + } + + protected function doParseDomainLiteral() + { + $IPv6TAG = false; + $addressLiteral = ''; + do { + if ($this->lexer->token['type'] === EmailLexer::C_NUL) { + throw new \InvalidArgumentException('ERR_EXPECTING_DTEXT'); + } + + if ($this->lexer->token['type'] === EmailLexer::INVALID || + $this->lexer->token['type'] === EmailLexer::C_DEL || + $this->lexer->token['type'] === EmailLexer::S_LF + ) { + $this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT; + } + + if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) { + throw new \InvalidArgumentException('ERR_EXPECTING_DTEXT'); + } + + if ($this->lexer->isNextTokenAny( + array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF) + )) { + $this->warnings[] = EmailValidator::CFWS_FWS; + $this->parseFWS(); + } + + if ($this->lexer->isNextToken(EmailLexer::S_CR)) { + throw new \InvalidArgumentException("ERR_CR_NO_LF"); + } + if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) { + $this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT; + $addressLiteral .= $this->lexer->token['value']; + $this->lexer->moveNext(); + $this->validateQuotedPair(); + } + if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) { + $IPv6TAG = true; + } + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEQBRACKET) { + break; + } + + $addressLiteral .= $this->lexer->token['value']; + + } while ($this->lexer->moveNext()); + + $addressLiteral = str_replace('[', '', $addressLiteral); + $addressLiteral = $this->checkIPV4Tag($addressLiteral); + + if (false === $addressLiteral) { + return $addressLiteral; + } + + if (!$IPv6TAG) { + $this->warnings[] = EmailValidator::RFC5322_DOMAINLITERAL; + return $addressLiteral; + } + + $this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL; + + $this->checkIPV6Tag($addressLiteral); + + return $addressLiteral; + } + + protected function checkIPV4Tag($addressLiteral) + { + $matchesIP = array(); + + // Extract IPv4 part from the end of the address-literal (if there is one) + if (preg_match( + '/\\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]?)$/', + $addressLiteral, + $matchesIP + ) > 0 + ) { + $index = strrpos($addressLiteral, $matchesIP[0]); + if ($index === 0) { + $this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL; + return false; + } + // Convert IPv4 part to IPv6 format for further testing + $addressLiteral = substr($addressLiteral, 0, $index) . '0:0'; + } + + return $addressLiteral; + } + + protected function checkDomainPartExceptions($prev) + { + if ($this->lexer->token['type'] === EmailLexer::S_COMMA) { + throw new \InvalidArgumentException('ERR_COMMA_IN_DOMAIN'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_AT) { + throw new \InvalidArgumentException('ERR_CONSECUTIVEATS'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) { + throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND'); + } + + if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH + && $this->lexer->isNextToken(EmailLexer::GENERIC)) { + throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + } + + protected function hasBrackets() + { + if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) { + return false; + } + + try { + $this->lexer->find(EmailLexer::S_CLOSEBRACKET); + } catch (\RuntimeException $e) { + throw new \InvalidArgumentException('ERR_EXPECTING_DOMLIT_CLOSE'); + } + + return true; + } + + protected function checkLabelLength($prev) + { + if ($this->lexer->token['type'] === EmailLexer::S_DOT && + $prev['type'] === EmailLexer::GENERIC && + strlen($prev['value']) > 63 + ) { + $this->warnings[] = EmailValidator::RFC5322_LABEL_TOOLONG; + } + } + + protected function parseDomainComments() + { + $this->isUnclosedComment(); + while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + $this->warnEscaping(); + $this->lexer->moveNext(); + } + + $this->lexer->moveNext(); + if ($this->lexer->isNextToken(EmailLexer::S_DOT)) { + throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + } + +} \ No newline at end of file diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php new file mode 100644 index 00000000000..47c7cc6597b --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php @@ -0,0 +1,94 @@ +lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) { + + if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) { + throw new \InvalidArgumentException('ERR_DOT_START'); + } + + $closingQuote = $this->checkDQUOTE($closingQuote); + if ($closingQuote && $parseDQuote) { + $this->parseDoubleQuote(); + $parseDQuote = false; + } + + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { + $this->parseComments(); + } + + $this->checkConsecutiveDots(); + + if ( + $this->lexer->token['type'] === EmailLexer::S_DOT && + $this->lexer->isNextToken(EmailLexer::S_AT) + ) { + throw new \InvalidArgumentException('ERR_DOT_END'); + } + + $this->warnEscaping(); + $this->isInvalidToken($this->lexer->token, $closingQuote); + + if ($this->isFWS()) { + $this->parseFWS(); + } + + $this->lexer->moveNext(); + } + + $prev = $this->lexer->getPrevious(); + if (strlen($prev['value']) > EmailValidator::RFC5322_LOCAL_TOOLONG) { + $this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG; + } + } + + protected function parseDoubleQuote() + { + $special = array ( + EmailLexer::S_CR => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_LF => true + ); + $setSpecialsWarning = true; + + $this->lexer->moveNext(); + while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) { + if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) { + $this->warnings[] = EmailValidator::CFWS_FWS; + $setSpecialsWarning = false; + } + $this->lexer->moveNext(); + } + } + + + protected function isInvalidToken($token, $closingQuote) + { + $forbidden = array( + EmailLexer::S_COMMA, + EmailLexer::S_CLOSEBRACKET, + EmailLexer::S_OPENBRACKET, + EmailLexer::S_GREATERTHAN, + EmailLexer::S_LOWERTHAN, + EmailLexer::S_COLON, + EmailLexer::S_SEMICOLON, + EmailLexer::INVALID + ); + + if (in_array($token['type'], $forbidden) && !$closingQuote) { + throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + } +} diff --git a/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php new file mode 100644 index 00000000000..b62b4055b80 --- /dev/null +++ b/core/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php @@ -0,0 +1,190 @@ +lexer = $lexer; + } + + public function getWarnings() + { + return $this->warnings; + } + + abstract function parse($str); + + /** + * validateQuotedPair + */ + protected function validateQuotedPair() + { + if (!($this->lexer->token['type'] === EmailLexer::INVALID + || $this->lexer->token['type'] === EmailLexer::C_DEL)) { + throw new \InvalidArgumentException('ERR_EXPECTING_QPAIR'); + } + + $this->warnings[] = EmailValidator::DEPREC_QP; + } + + /** + * @return string the the comment + * @throws \InvalidArgumentException + */ + protected function parseComments() + { + $this->isUnclosedComment(); + $this->warnings[] = EmailValidator::CFWS_COMMENT; + while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + $this->warnEscaping(); + $this->lexer->moveNext(); + } + + $this->lexer->moveNext(); + if ($this->lexer->isNextTokenAny(array(EmailLexer::GENERIC, EmailLexer::S_EMPTY))) { + throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + + if ($this->lexer->isNextToken(EmailLexer::S_AT)) { + $this->warnings[] = EmailValidator::DEPREC_CFWS_NEAR_AT; + } + } + + protected function isUnclosedComment() + { + try { + $this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS); + return true; + } catch (\RuntimeException $e) { + throw new \InvalidArgumentException('ERR_UNCLOSEDCOMMENT'); + } + } + + protected function parseFWS() + { + $previous = $this->lexer->getPrevious(); + + $this->checkCRLFInFWS(); + + if ($this->lexer->token['type'] === EmailLexer::S_CR) { + throw new \InvalidArgumentException("ERR_CR_NO_LF"); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) { + throw new \InvalidArgumentException("ERR_ATEXT_AFTER_CFWS"); + } + + if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) { + throw new \InvalidArgumentException('ERR_EXPECTING_CTEXT'); + } + + if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous['type'] === EmailLexer::S_AT) { + $this->warnings[] = EmailValidator::DEPREC_CFWS_NEAR_AT; + } else { + $this->warnings[] = EmailValidator::CFWS_FWS; + } + } + + protected function checkConsecutiveDots() + { + if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + throw new \InvalidArgumentException('ERR_CONSECUTIVEDOTS'); + } + } + + 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::S_SP || + $this->lexer->token['type'] === EmailLexer::S_HTAB) + ) { + 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 \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { + return false; + } + + $this->warnings[] = EmailValidator::DEPREC_QP; + 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 \InvalidArgumentException('ERR_EXPECTING_ATEXT'); + } + $this->warnings[] = EmailValidator::RFC5321_QUOTEDSTRING; + try { + $this->lexer->find(EmailLexer::S_DQUOTE); + $hasClosingQuote = true; + } catch (\Exception $e) { + throw new \InvalidArgumentException('ERR_UNCLOSEDQUOTEDSTR'); + } + + return $hasClosingQuote; + } + + protected function checkCRLFInFWS() + { + if ($this->lexer->token['type'] !== EmailLexer::CRLF) { + return; + } + if ($this->lexer->isNextToken(EmailLexer::CRLF)) { + throw new \InvalidArgumentException("ERR_FWS_CRLF_X2"); + } + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + throw new \InvalidArgumentException("ERR_FWS_CRLF_END"); + } + } +} \ No newline at end of file diff --git a/core/vendor/egulias/email-validator/tests/bootstrap.php b/core/vendor/egulias/email-validator/tests/bootstrap.php new file mode 100644 index 00000000000..676c4b1860c --- /dev/null +++ b/core/vendor/egulias/email-validator/tests/bootstrap.php @@ -0,0 +1,8 @@ +isValid($testingMail); +} +$b = microtime(true); +echo ($b - $a) . ' seconds with EmailValidator + instantiation' . PHP_EOL; + +$a = microtime(true); +$validator = new EmailValidator(); +for ($i = 0; $i < $iterations; $i++) { + $isValid = $validator->isValid($testingMail); +} +$b = microtime(true); +echo ($b - $a) . ' seconds with EmailValidator once instanced' . PHP_EOL; diff --git a/core/vendor/egulias/email-validator/tests/egulias/Performance/AgainstOldIsemail.php b/core/vendor/egulias/email-validator/tests/egulias/Performance/AgainstOldIsemail.php new file mode 100644 index 00000000000..99476c137a6 --- /dev/null +++ b/core/vendor/egulias/email-validator/tests/egulias/Performance/AgainstOldIsemail.php @@ -0,0 +1,34 @@ +isValid($testingMail); +} +$b = microtime(true); +echo ($b - $a) . ' seconds with EmailValidator + instantiation' . PHP_EOL; + +$a = microtime(true); +$validator = new EmailValidator(); +for ($i = 0; $i < $iterations; $i++) { + $isValid = $validator->isValid($testingMail); +} +$b = microtime(true); +echo ($b - $a) . ' seconds with EmailValidator once instanced' . PHP_EOL; diff --git a/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailLexerTest.php b/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailLexerTest.php new file mode 100644 index 00000000000..5ee3f3e0a8e --- /dev/null +++ b/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailLexerTest.php @@ -0,0 +1,80 @@ +assertInstanceOf('Doctrine\Common\Lexer\AbstractLexer', $lexer); + } + + /** + * @dataProvider getTokens + * + */ + public function testLexerTokens($str, $token) + { + $lexer = new EmailLexer(); + $lexer->setInput($str); + $lexer->moveNext(); + $lexer->moveNext(); + $this->assertEquals($token, $lexer->token['type']); + } + + public function testLexerForTab() + { + $lexer = new EmailLexer(); + $lexer->setInput("foo\tbar"); + $lexer->moveNext(); + $lexer->skipUntil(EmailLexer::S_HTAB); + $lexer->moveNext(); + $this->assertEquals(EmailLexer::S_HTAB, $lexer->token['type']); + } + + public function testLexerSearchToken() + { + $lexer = new EmailLexer(); + $lexer->setInput("foo\tbar"); + $lexer->moveNext(); + $this->assertTrue($lexer->find(EmailLexer::S_HTAB)); + } + + public function getTokens() + { + return array( + array("foo", EmailLexer::GENERIC), + array("\r", EmailLexer::S_CR), + array("\t", EmailLexer::S_HTAB), + array("\r\n", EmailLexer::CRLF), + array("\n", EmailLexer::S_LF), + array(" ", EmailLexer::S_SP), + array("@", EmailLexer::S_AT), + array("IPv6", EmailLexer::S_IPV6TAG), + array("::", EmailLexer::S_DOUBLECOLON), + array(":", EmailLexer::S_COLON), + array(".", EmailLexer::S_DOT), + array("\"", EmailLexer::S_DQUOTE), + array("-", EmailLexer::S_HYPHEN), + array("\\", EmailLexer::S_BACKSLASH), + array("(", EmailLexer::S_OPENPARENTHESIS), + array(")", EmailLexer::S_CLOSEPARENTHESIS), + array('<', EmailLexer::S_LOWERTHAN), + array('>', EmailLexer::S_GREATERTHAN), + array('[', EmailLexer::S_OPENBRACKET), + array(']', EmailLexer::S_CLOSEBRACKET), + array(';', EmailLexer::S_SEMICOLON), + array(',', EmailLexer::S_COMMA), + array('<', EmailLexer::S_LOWERTHAN), + array('>', EmailLexer::S_GREATERTHAN), + array('{', EmailLexer::S_OPENQBRACKET), + array('}', EmailLexer::S_CLOSEQBRACKET), + array('', EmailLexer::S_EMPTY), + array(chr(31), EmailLexer::INVALID) + ); + } +} diff --git a/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailValidatorTest.php b/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailValidatorTest.php new file mode 100644 index 00000000000..81fcf4dff05 --- /dev/null +++ b/core/vendor/egulias/email-validator/tests/egulias/Tests/EmailValidator/EmailValidatorTest.php @@ -0,0 +1,280 @@ +validator = new EmailValidator(); + } + + protected function tearDown() + { + $this->validator = null; + } + + /** + * @dataProvider getValidEmails + */ + public function testValidEmails($email) + { + $this->assertTrue($this->validator->isValid($email)); + } + + public function getValidEmails() + { + return array( + array('fabien@symfony.com'), + array('example@example.co.uk'), + array('fabien_potencier@example.fr'), + array('example@localhost'), + array('fab\'ien@symfony.com'), + array('fab\ ien@symfony.com'), + array('example((example))@fakedfake.co.uk'), + array('example@faked(fake).co.uk'), + array('fabien+@symfony.com'), + array('инфо@письмо.рф'), + array('"username"@example.com'), + array('"user,name"@example.com'), + array('"user name"@example.com'), + array('"user@name"@example.com'), + ); + } + + /** + * @dataProvider getInvalidEmails + */ + public function testInvalidEmails($email) + { + $this->assertFalse($this->validator->isValid($email)); + } + + public function getInvalidEmails() + { + return array( + array('example.@example.co.uk'), + array('example@example@example.co.uk'), + array('(fabien_potencier@example.fr)'), + array('example(example)example@example.co.uk'), + array('.example@localhost'), + array('ex\ample@localhost'), + array('example@local\host'), + array('example@localhost.'), + array('user name@example.com'), + array('username@ example . com'), + array('example@(fake).com'), + array('example@(fake.com'), + array('username@example,com'), + array('usern,ame@example.com'), + array('user[na]me@example.com'), + ); + } + + /** + * @dataProvider getInvalidEmailsWithErrors + */ + public function testInvalidEmailsWithErrorsCheck($errors, $email) + { + $this->assertFalse($this->validator->isValid($email)); + + $this->assertEquals($errors, $this->validator->getError()); + } + + public function getInvalidEmailsWithErrors() + { + return array( + array(EmailValidator::ERR_NOLOCALPART, '@example.co.uk'), + array(EmailValidator::ERR_NODOMAIN, 'example@'), + array(EmailValidator::ERR_DOMAINHYPHENEND, 'example@example-.co.uk'), + array(EmailValidator::ERR_DOMAINHYPHENEND, 'example@example-'), + array(EmailValidator::ERR_CONSECUTIVEATS, 'example@@example.co.uk'), + array(EmailValidator::ERR_CONSECUTIVEDOTS, 'example..example@example.co.uk'), + array(EmailValidator::ERR_CONSECUTIVEDOTS, 'example@example..co.uk'), + array(EmailValidator::ERR_EXPECTING_ATEXT, '@example.fr'), + array(EmailValidator::ERR_DOT_START, '.example@localhost'), + array(EmailValidator::ERR_DOT_START, 'example@.localhost'), + array(EmailValidator::ERR_DOT_END, 'example@localhost.'), + array(EmailValidator::ERR_DOT_END, 'example.@example.co.uk'), + array(EmailValidator::ERR_UNCLOSEDCOMMENT, '(example@localhost'), + array(EmailValidator::ERR_UNCLOSEDQUOTEDSTR, '"example@localhost'), + array(EmailValidator::ERR_EXPECTING_ATEXT, 'exa"mple@localhost'), + //This was the original. But atext is not allowed after \n + //array(EmailValidator::ERR_EXPECTING_ATEXT, "exampl\ne@example.co.uk"), + array(EmailValidator::ERR_ATEXT_AFTER_CFWS, "exampl\ne@example.co.uk"), + array(EmailValidator::ERR_EXPECTING_DTEXT, "example@[[]"), + array(EmailValidator::ERR_ATEXT_AFTER_CFWS, "exampl\te@example.co.uk"), + array(EmailValidator::ERR_CR_NO_LF, "example@exa\rmple.co.uk"), + array(EmailValidator::ERR_CR_NO_LF, "example@[\r]"), + array(EmailValidator::ERR_CR_NO_LF, "exam\rple@example.co.uk"), + ); + } + + /** + * @dataProvider getInvalidEmailsWithWarnings + */ + public function testValidEmailsWithWarningsCheck($warnings, $email) + { + $this->assertTrue($this->validator->isValid($email, true)); + + $this->assertEquals($warnings, $this->validator->getWarnings()); + } + + public function getInvalidEmailsWithWarnings() + { + return array( + array(array( EmailValidator::DEPREC_CFWS_NEAR_AT,), 'example @example.co.uk'), + array(array( EmailValidator::DEPREC_CFWS_NEAR_AT,), 'example@ example.co.uk'), + array(array( EmailValidator::CFWS_COMMENT,), 'example@example(examplecomment).co.uk'), + array( + array( + EmailValidator::CFWS_COMMENT, + EmailValidator::DEPREC_CFWS_NEAR_AT, + ), + 'example(examplecomment)@example.co.uk' + ), + array( + array( + EmailValidator::RFC5321_QUOTEDSTRING, + EmailValidator::CFWS_FWS, + ), + "\"\t\"@example.co.uk" + ), + array( + array( + EmailValidator::RFC5321_QUOTEDSTRING, + EmailValidator::CFWS_FWS, + ), + "\"\r\"@example.co.uk" + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[127.0.0.1]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5321_IPV6DEPRECATED, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370::]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5322_IPV6_MAXGRPS, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334::]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5322_IPV6_2X2XCOLON, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:1::1::1]' + ), + array( + array( + EmailValidator::RFC5322_DOMLIT_OBSDTEXT, + EmailValidator::RFC5322_DOMAINLITERAL, + EmailValidator::DNSWARN_NO_RECORD, + ), + "example@[\n]" + ), + array( + array( + EmailValidator::RFC5322_DOMAINLITERAL, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[::1]' + ), + array( + array( + EmailValidator::RFC5322_DOMAINLITERAL, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[::123.45.67.178]' + ), + array( + array( + EmailValidator::RFC5322_IPV6_COLONSTRT, + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5322_IPV6_GRPCOUNT, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6::2001:0db8:85a3:0000:0000:8a2e:0370:7334]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5322_IPV6_BADCHAR, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:z001:0db8:85a3:0000:0000:8a2e:0370:7334]' + ), + array( + array( + EmailValidator::RFC5321_ADDRESSLITERAL, + EmailValidator::RFC5322_IPV6_COLONEND, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:]' + ), + array( + array( + EmailValidator::RFC5321_QUOTEDSTRING, + ), + '"example"@example.co.uk' + ), + array( + array( + EmailValidator::RFC5322_LOCAL_TOOLONG, + ), + 'too_long_localpart_too_long_localpart_too_long_localpart_too_long_localpart@example.co.uk' + ), + array( + array( + EmailValidator::RFC5322_LABEL_TOOLONG, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart.co.uk' + ), + array( + array( + EmailValidator::RFC5322_DOMAIN_TOOLONG, + EmailValidator::RFC5322_TOOLONG, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocal'. + 'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'. + 'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart' + ), + array( + array( + EmailValidator::RFC5322_DOMAIN_TOOLONG, + EmailValidator::RFC5322_TOOLONG, + EmailValidator::DNSWARN_NO_RECORD, + ), + 'example@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocal'. + 'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'. + 'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpar' + ), + ); + } +}