Compare commits

..

26 Commits

Author SHA1 Message Date
Eduardo Gulias Davis 518f80a0ff Merge pull request #35 from craue/fix-strict-check
make strict check work again
2014-11-06 09:59:44 +01:00
Christian Raue 2ec7babda6 fixed strict check 2014-11-05 01:09:55 +01:00
Christian Raue 05367768d6 improved tests for strict checking 2014-11-04 14:01:13 +01:00
Eduardo Gulias Davis 5c3a79217c Merge pull request #33 from egulias/32_strict_and_dns_bug
#32 - Fixed usage of DNS check and strict parameter
2014-11-03 00:13:57 +01:00
Eduardo Gulias Davis 749b423775 #32 - Fixed usage of DNS check and strict parameter 2014-11-03 00:05:58 +01:00
Eduardo Gulias Davis 49494c3189 Merge pull request #31 from egulias/18-discrep-isemail
#18 Differences with isemail
2014-10-26 23:13:52 +01:00
Eduardo Gulias Davis 8b62522238 Scrutinizer patch 2014-10-26 23:02:09 +01:00
Eduardo Gulias Davis 82fb2d6ce1 Remove under development tests emails 2014-10-26 22:55:42 +01:00
Eduardo Gulias Davis 2933b7bbd1 Reset state 2014-10-26 22:54:30 +01:00
Eduardo Gulias Davis f5c48f62d3 Remove commens 2014-10-26 22:54:21 +01:00
Eduardo Gulias Davis 43650e8566 Merge pull request #29 from rdohms/patch-1
Update README.md
2014-10-22 14:39:14 +02:00
Rafael Dohms 3d94cc6487 Update README.md
Updated composer installation instructions.
It now follows the recommendation of using the "require" command and letting Composer auto-define the latest version.
2014-10-22 14:29:38 +02:00
Eduardo Gulias Davis 65c8c3d7bb Merge pull request #28 from DotZecker/patch-1
Fix namespace
2014-10-21 23:52:23 +02:00
Rafael Antonio 57f8ae443b Fix namespace 2014-10-21 09:28:45 +02:00
Eduardo Gulias Davis 18df863858 #18 - [WIP] - Almost done with erros, dobule backslask left and utf8 chars 2014-10-14 00:48:32 +02:00
Eduardo Gulias Davis 953cbdbbcf Merge pull request #26 from stof/patch-1
Fixed the SensioLabsInsight project id
2014-09-17 14:47:23 +02:00
Christophe Coevoet 41cb75ec00 Fixed the SensioLabsInsight project id
Closes #23
2014-09-17 14:12:41 +02:00
Eduardo Gulias Davis 8927160d8d Merge pull request #25 from thewilkybarkid/constraint
Improve suggested constraint
2014-09-17 11:02:18 +02:00
thewilkybarkid 887605ad1b Fix typo 2014-09-17 09:06:33 +01:00
thewilkybarkid 43e1825cd8 Improve suggested constraint 2014-09-17 09:06:22 +01:00
Eduardo Gulias Davis 2f44d7b1e1 #23 - SensioLabsInsight errors 2014-09-16 23:20:11 +02:00
Eduardo Gulias Davis 355cb7e604 Merge pull request #22 from stof/patch-1
Fixed the branch alias for master
2014-09-16 23:00:05 +02:00
Eduardo Gulias Davis d6fcd2d7ca Merge pull request #24 from mhor/patch-1
Typo
2014-09-16 22:58:54 +02:00
Maxime Horcholle 9be8eb420a typo 2014-09-16 19:07:39 +02:00
Christophe Coevoet 20066b1c1e Fixed the branch alias for master 2014-09-16 17:45:41 +02:00
Eduardo Gulias Davis 39b451bb2b #19 and #10 - Improvement of QuotedPart parsing 2014-09-02 00:35:48 +02:00
11 changed files with 359 additions and 128 deletions
+10 -5
View File
@@ -1,8 +1,13 @@
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) 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/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)[![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## ##Installation##
Install via composer. Add to your current compooser.json ```require``` key: ```"egulias/email-validator":"1.0.x-dev" ```
Run the command below to install via Composer
```shell
composer require egulias/email-validator
```
##Usage## ##Usage##
@@ -24,7 +29,7 @@ More advanced example (returns detailed diagnostic error codes):
```php ```php
<?php <?php
use egulias\EmailValidator\EmailValidator; use Egulias\EmailValidator\EmailValidator;
$validator = new EmailValidator; $validator = new EmailValidator;
$email = 'dominic@sayers.cc'; $email = 'dominic@sayers.cc';
@@ -46,6 +51,6 @@ As this is a port from another library and work, here are other people related t
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib * 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 * Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function
##Licence## ##License##
Released under the MIT Licence attached with this code. Released under the MIT License attached with this code.
+1 -1
View File
@@ -10,7 +10,7 @@
], ],
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.0.x-dev" "dev-master": "1.3.x-dev"
} }
}, },
"require": { "require": {
Generated
+82 -87
View File
@@ -1,9 +1,10 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "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" "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
], ],
"hash": "cca347a6b95164b1121e034b95f824ec", "hash": "9e9dff0cc08c7292600453e681201e13",
"packages": [ "packages": [
{ {
"name": "doctrine/lexer", "name": "doctrine/lexer",
@@ -61,16 +62,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "guzzle/guzzle", "name": "guzzle/guzzle",
"version": "v3.9.1", "version": "v3.9.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle3.git", "url": "https://github.com/guzzle/guzzle3.git",
"reference": "92d9934f2fca1da15178c91239576ae26e505e60" "reference": "54991459675c1a2924122afbb0e5609ade581155"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/92d9934f2fca1da15178c91239576ae26e505e60", "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/54991459675c1a2924122afbb0e5609ade581155",
"reference": "92d9934f2fca1da15178c91239576ae26e505e60", "reference": "54991459675c1a2924122afbb0e5609ade581155",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -114,7 +115,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.8-dev" "dev-master": "3.9-dev"
} }
}, },
"autoload": { "autoload": {
@@ -149,7 +150,7 @@
"rest", "rest",
"web service" "web service"
], ],
"time": "2014-05-07 17:04:22" "time": "2014-08-11 04:32:36"
}, },
{ {
"name": "psr/log", "name": "psr/log",
@@ -195,18 +196,18 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/satooshi/php-coveralls.git", "url": "https://github.com/satooshi/php-coveralls.git",
"reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4" "reference": "94389a0ebdb64857d6899b5e0254dffa99e5aa96"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/b7271847c84d160f5b0aae83e45c225e8ffc96f4", "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/94389a0ebdb64857d6899b5e0254dffa99e5aa96",
"reference": "b7271847c84d160f5b0aae83e45c225e8ffc96f4", "reference": "94389a0ebdb64857d6899b5e0254dffa99e5aa96",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"guzzle/guzzle": ">=3.0", "guzzle/guzzle": ">=2.7",
"php": ">=5.3", "php": ">=5.3",
"psr/log": "1.0.0", "psr/log": "1.0.0",
"symfony/config": ">=2.0", "symfony/config": ">=2.0",
@@ -216,7 +217,7 @@
}, },
"require-dev": { "require-dev": {
"apigen/apigen": "2.8.*@stable", "apigen/apigen": "2.8.*@stable",
"pdepend/pdepend": "dev-master", "pdepend/pdepend": "dev-master as 2.0.0",
"phpmd/phpmd": "dev-master", "phpmd/phpmd": "dev-master",
"phpunit/php-invoker": ">=1.1.0,<1.2.0", "phpunit/php-invoker": ">=1.1.0,<1.2.0",
"phpunit/phpunit": "3.7.*@stable", "phpunit/phpunit": "3.7.*@stable",
@@ -262,21 +263,21 @@
"github", "github",
"test" "test"
], ],
"time": "2014-05-14 13:09:37" "time": "2014-07-09 10:45:38"
}, },
{ {
"name": "symfony/config", "name": "symfony/config",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/Config", "target-dir": "Symfony/Component/Config",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Config.git", "url": "https://github.com/symfony/Config.git",
"reference": "2effc67af6f21a0d267210b72d0b0b691d113528" "reference": "080eabdc256c1d7a3a7cf6296271edb68eb1ab2b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Config/zipball/2effc67af6f21a0d267210b72d0b0b691d113528", "url": "https://api.github.com/repos/symfony/Config/zipball/080eabdc256c1d7a3a7cf6296271edb68eb1ab2b",
"reference": "2effc67af6f21a0d267210b72d0b0b691d113528", "reference": "080eabdc256c1d7a3a7cf6296271edb68eb1ab2b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -286,7 +287,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -299,49 +300,49 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony Config Component", "description": "Symfony Config Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-04-22 08:11:06" "time": "2014-08-31 03:22:04"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/Console", "target-dir": "Symfony/Component/Console",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Console.git", "url": "https://github.com/symfony/Console.git",
"reference": "24f723436e62598c9dddee2a8573d6992504dc5d" "reference": "748beed2a1e73179c3f5154d33fe6ae100c1aeb1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/24f723436e62598c9dddee2a8573d6992504dc5d", "url": "https://api.github.com/repos/symfony/Console/zipball/748beed2a1e73179c3f5154d33fe6ae100c1aeb1",
"reference": "24f723436e62598c9dddee2a8573d6992504dc5d", "reference": "748beed2a1e73179c3f5154d33fe6ae100c1aeb1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.3.3"
}, },
"require-dev": { "require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1" "symfony/event-dispatcher": "~2.1"
}, },
"suggest": { "suggest": {
"psr/log": "For using the console logger",
"symfony/event-dispatcher": "" "symfony/event-dispatcher": ""
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -354,41 +355,42 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-05-14 21:48:29" "time": "2014-08-14 16:10:54"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/EventDispatcher", "target-dir": "Symfony/Component/EventDispatcher",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/EventDispatcher.git", "url": "https://github.com/symfony/EventDispatcher.git",
"reference": "e539602e5455aa086c0e81e604745af7789e4d8a" "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e539602e5455aa086c0e81e604745af7789e4d8a", "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/8faf5cc7e80fde74a650a36e60d32ce3c3e0457b",
"reference": "e539602e5455aa086c0e81e604745af7789e4d8a", "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.3.3"
}, },
"require-dev": { "require-dev": {
"symfony/dependency-injection": "~2.0" "psr/log": "~1.0",
"symfony/config": "~2.0",
"symfony/dependency-injection": "~2.0",
"symfony/stopwatch": "~2.2"
}, },
"suggest": { "suggest": {
"symfony/dependency-injection": "", "symfony/dependency-injection": "",
@@ -397,7 +399,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -410,34 +412,32 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-04-16 10:34:31" "time": "2014-07-28 13:20:46"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/Filesystem", "target-dir": "Symfony/Component/Filesystem",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Filesystem.git", "url": "https://github.com/symfony/Filesystem.git",
"reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4" "reference": "a765efd199e02ff4001c115c318e219030be9364"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/a3af8294bcce4a7c1b2892363b0c9d8109affad4", "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a765efd199e02ff4001c115c318e219030be9364",
"reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4", "reference": "a765efd199e02ff4001c115c318e219030be9364",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -446,7 +446,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -459,34 +459,32 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony Filesystem Component", "description": "Symfony Filesystem Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-04-16 10:34:31" "time": "2014-09-03 09:00:14"
}, },
{ {
"name": "symfony/stopwatch", "name": "symfony/stopwatch",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/Stopwatch", "target-dir": "Symfony/Component/Stopwatch",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Stopwatch.git", "url": "https://github.com/symfony/Stopwatch.git",
"reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a" "reference": "22ab4f76cdeefd38b00022a6be5709190a2fd046"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/343bcc0360f2c22f371884b8f6a9fee8d1aa431a", "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/22ab4f76cdeefd38b00022a6be5709190a2fd046",
"reference": "343bcc0360f2c22f371884b8f6a9fee8d1aa431a", "reference": "22ab4f76cdeefd38b00022a6be5709190a2fd046",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -495,7 +493,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -508,34 +506,32 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony Stopwatch Component", "description": "Symfony Stopwatch Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-04-18 20:37:09" "time": "2014-08-14 16:10:54"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v2.4.5", "version": "v2.5.4",
"target-dir": "Symfony/Component/Yaml", "target-dir": "Symfony/Component/Yaml",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Yaml.git", "url": "https://github.com/symfony/Yaml.git",
"reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265" "reference": "01a7695bcfb013d0a15c6757e15aae120342986f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/fd22bb88c3a6f73c898b39bec185a9e211b06265", "url": "https://api.github.com/repos/symfony/Yaml/zipball/01a7695bcfb013d0a15c6757e15aae120342986f",
"reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265", "reference": "01a7695bcfb013d0a15c6757e15aae120342986f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -544,7 +540,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.4-dev" "dev-master": "2.5-dev"
} }
}, },
"autoload": { "autoload": {
@@ -557,20 +553,18 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
} }
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "http://symfony.com", "homepage": "http://symfony.com",
"time": "2014-05-12 09:27:48" "time": "2014-08-31 03:22:04"
} }
], ],
"aliases": [ "aliases": [
@@ -580,6 +574,7 @@
"stability-flags": { "stability-flags": {
"satooshi/php-coveralls": 20 "satooshi/php-coveralls": 20
}, },
"prefer-stable": false,
"platform": { "platform": {
"php": ">= 5.3.3" "php": ">= 5.3.3"
}, },
+61 -5
View File
@@ -31,10 +31,13 @@ class EmailLexer extends AbstractLexer
const S_SEMICOLON = 275; const S_SEMICOLON = 275;
const S_OPENQBRACKET = 276; const S_OPENQBRACKET = 276;
const S_CLOSEQBRACKET = 277; const S_CLOSEQBRACKET = 277;
const S_SLASH = 278;
const S_EMPTY = null; const S_EMPTY = null;
const GENERIC = 300; const GENERIC = 300;
const CRLF = 301; const CRLF = 301;
const INVALID = 302; const INVALID = 302;
const ASCII_INVALID_FROM = 127;
const ASCII_INVALID_TO = 199;
/** /**
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3) * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
@@ -52,6 +55,7 @@ class EmailLexer extends AbstractLexer
';' => self::S_SEMICOLON, ';' => self::S_SEMICOLON,
'@' => self::S_AT, '@' => self::S_AT,
'\\' => self::S_BACKSLASH, '\\' => self::S_BACKSLASH,
'/' => self::S_SLASH,
',' => self::S_COMMA, ',' => self::S_COMMA,
'.' => self::S_DOT, '.' => self::S_DOT,
'"' => self::S_DQUOTE, '"' => self::S_DQUOTE,
@@ -67,14 +71,31 @@ class EmailLexer extends AbstractLexer
'>' => self::S_GREATERTHAN, '>' => self::S_GREATERTHAN,
'{' => self::S_OPENQBRACKET, '{' => self::S_OPENQBRACKET,
'}' => self::S_CLOSEQBRACKET, '}' => self::S_CLOSEQBRACKET,
'' => self::S_EMPTY '' => self::S_EMPTY,
'\0' => self::C_NUL,
); );
protected $invalidASCII = array(226 => 1,);
protected $hasInvalidTokens = false;
protected $previous; protected $previous;
public function reset()
{
$this->hasInvalidTokens = false;
parent::reset();
}
public function hasInvalidTokens()
{
return $this->hasInvalidTokens;
}
/** /**
* @param $type * @param $type
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @return boolean
*/ */
public function find($type) public function find($type)
{ {
@@ -84,6 +105,7 @@ class EmailLexer extends AbstractLexer
if (!$search->lookahead) { if (!$search->lookahead) {
throw new \UnexpectedValueException($type . ' not found'); throw new \UnexpectedValueException($type . ' not found');
} }
return true;
} }
/** /**
@@ -99,7 +121,7 @@ class EmailLexer extends AbstractLexer
/** /**
* moveNext * moveNext
* *
* @return mixed * @return boolean
*/ */
public function moveNext() public function moveNext()
{ {
@@ -111,7 +133,7 @@ class EmailLexer extends AbstractLexer
/** /**
* Lexical catchable patterns. * Lexical catchable patterns.
* *
* @return array * @return string[]
*/ */
protected function getCatchablePatterns() protected function getCatchablePatterns()
{ {
@@ -129,7 +151,7 @@ class EmailLexer extends AbstractLexer
/** /**
* Lexical non-catchable patterns. * Lexical non-catchable patterns.
* *
* @return array * @return string[]
*/ */
protected function getNonCatchablePatterns() protected function getNonCatchablePatterns()
{ {
@@ -145,14 +167,48 @@ class EmailLexer extends AbstractLexer
*/ */
protected function getType(&$value) protected function getType(&$value)
{ {
if ($this->isNullType($value)) {
return self::C_NUL;
}
if (isset($this->charValue[$value])) { if (isset($this->charValue[$value])) {
return $this->charValue[$value]; return $this->charValue[$value];
} }
if (preg_match('/[\x10-\x1F]+/', $value)) { if ($this->isInvalid($value)) {
$this->hasInvalidTokens = true;
return self::INVALID; return self::INVALID;
} }
return self::GENERIC; return self::GENERIC;
} }
/**
* @param string $value
*/
protected function isNullType($value)
{
if ($value === "\0") {
return true;
}
return false;
}
/**
* @param string $value
*/
protected function isInvalid($value)
{
if (preg_match('/[\x10-\x1F]+/', $value)) {
return true;
}
if (isset($this->invalidASCII[ord($value)])) {
return true;
}
return false;
}
} }
@@ -28,6 +28,9 @@ class EmailParser
$this->domainPartParser = new DomainPart($this->lexer); $this->domainPartParser = new DomainPart($this->lexer);
} }
/**
* @param string $str
*/
public function parse($str) public function parse($str)
{ {
$this->lexer->setInput($str); $this->lexer->setInput($str);
@@ -36,6 +39,10 @@ class EmailParser
throw new \InvalidArgumentException('ERR_NOLOCALPART'); throw new \InvalidArgumentException('ERR_NOLOCALPART');
} }
if ($this->lexer->hasInvalidTokens()) {
throw new \InvalidArgumentException('ERR_INVALID_ATEXT');
}
$this->localPartParser->parse($str); $this->localPartParser->parse($str);
$this->domainPartParser->parse($str); $this->domainPartParser->parse($str);
@@ -78,6 +85,10 @@ class EmailParser
return true; return true;
} }
/**
* @param string $localPart
* @param string $parsedDomainPart
*/
protected function addLongEmailWarning($localPart, $parsedDomainPart) protected function addLongEmailWarning($localPart, $parsedDomainPart)
{ {
if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) {
+2 -11
View File
@@ -2,8 +2,6 @@
namespace Egulias\EmailValidator; namespace Egulias\EmailValidator;
use Egulias\EmailValidator\Parser\LocalPart;
/** /**
* EmailValidator * EmailValidator
* *
@@ -97,7 +95,7 @@ class EmailValidator
return false; return false;
} }
return ($strict) ? (!$this->hasWarnings() && $dns) : true; return !$strict || (!$this->hasWarnings() && $dns);
} }
/** /**
@@ -146,16 +144,9 @@ class EmailValidator
protected function checkDNS() protected function checkDNS()
{ {
$checked = false; $checked = true;
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'); $result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX');
$checked = true;
if (!$result) { if (!$result) {
$this->warnings[] = self::DNSWARN_NO_RECORD; $this->warnings[] = self::DNSWARN_NO_RECORD;
@@ -23,6 +23,9 @@ class DomainPart extends Parser
if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) { if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) {
throw new \InvalidArgumentException('ERR_NODOMAIN'); throw new \InvalidArgumentException('ERR_NODOMAIN');
} }
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
throw new \InvalidArgumentException('ERR_DOMAINHYPHENEND');
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[] = EmailValidator::DEPREC_COMMENT; $this->warnings[] = EmailValidator::DEPREC_COMMENT;
@@ -103,6 +106,10 @@ class DomainPart extends Parser
do { do {
$prev = $this->lexer->getPrevious(); $prev = $this->lexer->getPrevious();
if ($this->lexer->token['type'] === EmailLexer::S_SLASH) {
throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED');
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->parseComments(); $this->parseComments();
$this->lexer->moveNext(); $this->lexer->moveNext();
@@ -210,6 +217,9 @@ class DomainPart extends Parser
return $addressLiteral; return $addressLiteral;
} }
/**
* @param string $addressLiteral
*/
protected function checkIPV4Tag($addressLiteral) protected function checkIPV4Tag($addressLiteral)
{ {
$matchesIP = array(); $matchesIP = array();
@@ -295,5 +305,4 @@ class DomainPart extends Parser
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
} }
} }
}
}
+77 -11
View File
@@ -3,15 +3,17 @@
namespace Egulias\EmailValidator\Parser; namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Parser\Parser;
use Egulias\EmailValidator\EmailValidator; use Egulias\EmailValidator\EmailValidator;
use \InvalidArgumentException;
class LocalPart extends Parser class LocalPart extends Parser
{ {
public function parse($localPart) public function parse($localPart)
{ {
$parseDQuote = true;
$closingQuote = false; $closingQuote = false;
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) { while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) { if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
@@ -19,6 +21,9 @@ class LocalPart extends Parser
} }
$closingQuote = $this->checkDQUOTE($closingQuote); $closingQuote = $this->checkDQUOTE($closingQuote);
if ($closingQuote && $parseDQuote) {
$parseDQuote = $this->parseDoubleQuote();
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->parseComments(); $this->parseComments();
@@ -26,20 +31,15 @@ class LocalPart extends Parser
$this->checkConsecutiveDots(); $this->checkConsecutiveDots();
if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_AT)) { if (
$this->lexer->token['type'] === EmailLexer::S_DOT &&
$this->lexer->isNextToken(EmailLexer::S_AT)
) {
throw new \InvalidArgumentException('ERR_DOT_END'); throw new \InvalidArgumentException('ERR_DOT_END');
} }
$this->warnEscaping(); $this->warnEscaping();
$this->isInvalidToken($this->lexer->token, $closingQuote);
if ($this->lexer->isNextTokenAny(
array(
EmailLexer::INVALID, EmailLexer::S_LOWERTHAN, EmailLexer::S_GREATERTHAN
)
)
) {
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
}
if ($this->isFWS()) { if ($this->isFWS()) {
$this->parseFWS(); $this->parseFWS();
@@ -53,4 +53,70 @@ class LocalPart extends Parser
$this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG; $this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG;
} }
} }
protected function parseDoubleQuote()
{
$parseAgain = true;
$special = array(
EmailLexer::S_CR => true,
EmailLexer::S_HTAB => true,
EmailLexer::S_LF => true
);
$invalid = array(
EmailLexer::C_NUL => true,
EmailLexer::S_HTAB => true,
EmailLexer::S_CR => true,
EmailLexer::S_LF => true
);
$setSpecialsWarning = true;
$this->lexer->moveNext();
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
$parseAgain = false;
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
$this->warnings[] = EmailValidator::CFWS_FWS;
$setSpecialsWarning = false;
}
$this->lexer->moveNext();
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
throw new InvalidArgumentException("ERR_EXPECTED_ATEXT");
}
}
$prev = $this->lexer->getPrevious();
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
if (!$this->checkDQUOTE(false)) {
throw new \InvalidArgumentException("ERR_UNCLOSED_DQUOTE");
}
}
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
throw new \InvalidArgumentException("ERR_EXPECED_AT");
}
return $parseAgain;
}
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');
}
}
} }
+20 -1
View File
@@ -102,6 +102,10 @@ abstract class Parser
protected function isFWS() protected function isFWS()
{ {
if ($this->escaped()) {
return false;
}
if ($this->lexer->token['type'] === EmailLexer::S_SP || if ($this->lexer->token['type'] === EmailLexer::S_SP ||
$this->lexer->token['type'] === EmailLexer::S_HTAB || $this->lexer->token['type'] === EmailLexer::S_HTAB ||
$this->lexer->token['type'] === EmailLexer::S_CR || $this->lexer->token['type'] === EmailLexer::S_CR ||
@@ -114,6 +118,20 @@ abstract class Parser
return false; return false;
} }
protected function escaped()
{
$previous = $this->lexer->getPrevious();
if ($previous['type'] === EmailLexer::S_BACKSLASH
&&
$this->lexer->token['type'] !== EmailLexer::GENERIC
) {
return true;
}
return false;
}
protected function warnEscaping() protected function warnEscaping()
{ {
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) { if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
@@ -145,6 +163,7 @@ abstract class Parser
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) { if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
} }
$this->warnings[] = EmailValidator::RFC5321_QUOTEDSTRING; $this->warnings[] = EmailValidator::RFC5321_QUOTEDSTRING;
try { try {
$this->lexer->find(EmailLexer::S_DQUOTE); $this->lexer->find(EmailLexer::S_DQUOTE);
@@ -168,4 +187,4 @@ abstract class Parser
throw new \InvalidArgumentException("ERR_FWS_CRLF_END"); throw new \InvalidArgumentException("ERR_FWS_CRLF_END");
} }
} }
} }
@@ -36,6 +36,23 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
$this->assertEquals(EmailLexer::S_HTAB, $lexer->token['type']); $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 testLexerHasInvalidTokens()
{
$lexer = new EmailLexer();
$lexer->setInput(chr(226));
$lexer->moveNext();
$lexer->moveNext();
$this->assertTrue($lexer->hasInvalidTokens());
}
public function getTokens() public function getTokens()
{ {
return array( return array(
@@ -53,6 +70,7 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
array("\"", EmailLexer::S_DQUOTE), array("\"", EmailLexer::S_DQUOTE),
array("-", EmailLexer::S_HYPHEN), array("-", EmailLexer::S_HYPHEN),
array("\\", EmailLexer::S_BACKSLASH), array("\\", EmailLexer::S_BACKSLASH),
array("/", EmailLexer::S_SLASH),
array("(", EmailLexer::S_OPENPARENTHESIS), array("(", EmailLexer::S_OPENPARENTHESIS),
array(")", EmailLexer::S_CLOSEPARENTHESIS), array(")", EmailLexer::S_CLOSEPARENTHESIS),
array('<', EmailLexer::S_LOWERTHAN), array('<', EmailLexer::S_LOWERTHAN),
@@ -66,7 +84,9 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
array('{', EmailLexer::S_OPENQBRACKET), array('{', EmailLexer::S_OPENQBRACKET),
array('}', EmailLexer::S_CLOSEQBRACKET), array('}', EmailLexer::S_CLOSEQBRACKET),
array('', EmailLexer::S_EMPTY), array('', EmailLexer::S_EMPTY),
array(chr(31), EmailLexer::INVALID) array(chr(31), EmailLexer::INVALID),
array(chr(226), EmailLexer::INVALID),
array(chr(0), EmailLexer::C_NUL)
); );
} }
} }
@@ -34,11 +34,19 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
array('fabien_potencier@example.fr'), array('fabien_potencier@example.fr'),
array('example@localhost'), array('example@localhost'),
array('fab\'ien@symfony.com'), array('fab\'ien@symfony.com'),
array('fab\ ien@symfony.com'),
array('example((example))@fakedfake.co.uk'), array('example((example))@fakedfake.co.uk'),
array('example@faked(fake).co.uk'), array('example@faked(fake).co.uk'),
array('fabien+@symfony.com'), array('fabien+@symfony.com'),
array('инфо@письмо.рф'), array('инфо@письмо.рф'),
array('"username"@example.com'),
array('"user,name"@example.com'),
array('"user name"@example.com'),
array('"user@name"@example.com'),
array('"\a"@iana.org'),
array('"test\ test"@iana.org'),
array('""@iana.org'),
array('"\""@iana.org'),
); );
} }
@@ -53,9 +61,10 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
public function getInvalidEmails() public function getInvalidEmails()
{ {
return array( return array(
array('example.@example.co.uk'), array('example.@example.co.uk'),
array('example@example@example.co.uk'), array('example@example@example.co.uk'),
array('(fabien_potencier@example.fr)'), array('(test_exampel@example.fr)'),
array('example(example)example@example.co.uk'), array('example(example)example@example.co.uk'),
array('.example@localhost'), array('.example@localhost'),
array('ex\ample@localhost'), array('ex\ample@localhost'),
@@ -66,6 +75,29 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
array('example@(fake).com'), array('example@(fake).com'),
array('example@(fake.com'), array('example@(fake.com'),
array('username@example,com'), array('username@example,com'),
array('usern,ame@example.com'),
array('user[na]me@example.com'),
array('"""@iana.org'),
array('"\"@iana.org'),
array('"test"test@iana.org'),
array('"test""test"@iana.org'),
array('"test"."test"@iana.org'),
array('"test".test@iana.org'),
array('"test"' . chr(0) . '@iana.org'),
array('"test\"@iana.org'),
array(chr(226) . '@iana.org'),
array('test@' . chr(226) . '.org'),
array('\r\ntest@iana.org'),
array('\r\n test@iana.org'),
array('\r\n \r\ntest@iana.org'),
array('\r\n \r\ntest@iana.org'),
array('\r\n \r\n test@iana.org'),
array('test@iana.org \r\n'),
array('test@iana.org \r\n '),
array('test@iana.org \r\n \r\n'),
array('test@iana.org \r\n\r\n'),
array('test@iana.org \r\n\r\n '),
array('test@iana/icann.org'),
); );
} }
@@ -105,20 +137,29 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
array(EmailValidator::ERR_CR_NO_LF, "example@exa\rmple.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, "example@[\r]"),
array(EmailValidator::ERR_CR_NO_LF, "exam\rple@example.co.uk"), array(EmailValidator::ERR_CR_NO_LF, "exam\rple@example.co.uk"),
array(EmailValidator::ERR_CR_NO_LF, "\"\r\"@localhost"),
); );
} }
/** /**
* @dataProvider getInvalidEmailsWithWarnings * @dataProvider getInvalidEmailsWithWarnings
*/ */
public function testInvalidEmailsWithWarningsCheck($warnings, $email) public function testValidEmailsWithWarningsCheck($warnings, $email)
{ {
$this->assertTrue($this->validator->isValid($email, true)); $this->assertTrue($this->validator->isValid($email, true));
$this->assertEquals($warnings, $this->validator->getWarnings()); $this->assertEquals($warnings, $this->validator->getWarnings());
} }
/**
* @dataProvider getInvalidEmailsWithWarnings
*/
public function testInvalidEmailsWithDnsCheckAndStrictMode($warnings, $email)
{
$this->assertFalse($this->validator->isValid($email, true, true));
$this->assertEquals($warnings, $this->validator->getWarnings());
}
public function getInvalidEmailsWithWarnings() public function getInvalidEmailsWithWarnings()
{ {
return array( return array(
@@ -139,6 +180,13 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
), ),
"\"\t\"@example.co.uk" "\"\t\"@example.co.uk"
), ),
array(
array(
EmailValidator::RFC5321_QUOTEDSTRING,
EmailValidator::CFWS_FWS,
),
"\"\r\"@example.co.uk"
),
array( array(
array( array(
EmailValidator::RFC5321_ADDRESSLITERAL, EmailValidator::RFC5321_ADDRESSLITERAL,
@@ -263,6 +311,17 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'. 'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'.
'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpar' 'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpar'
), ),
array(
array(
EmailValidator::DNSWARN_NO_RECORD,
),
'test@test'
),
); );
} }
public function testInvalidEmailsWithStrict()
{
$this->assertFalse($this->validator->isValid('"test"@test', false, true));
}
} }