Fixing Email Validator to handle edge case where email address is valid but fails ascii conversion.

This commit is contained in:
Aaron Mueller
2021-03-31 11:50:24 -07:00
parent a03fb0c01e
commit 3593696b93
3 changed files with 21 additions and 2 deletions

View File

@ -6,6 +6,7 @@ Yii Framework 2 Change Log
- Enh #18534: Added `prepareSearchQuery` property in `yii\rest\IndexAction` (programmis)
- Enh #18566: Throw the original exception when `yii\web\Controller::bindInjectedParams()` catches HttpException (pigochu)
- Bug #18585: Fix `yii\validators\EmailValidator` to handle an edge case where `IDN` is enabled, but fails ascii conversion for valid email addresses (ihitbuttons)
- Bug #18574: Fix `yii\web\DbSession` to use the correct db if strict mode is used (Mignar)
- Bug #17479: Fix `yii\grid\ActionColumn` to render icons when no glyphicons are available (simialbi)
- Bug #18544: Fix `yii\validators\NumberValidator` to disallow values with whitespaces (bizley)
@ -16,7 +17,6 @@ Yii Framework 2 Change Log
- Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley)
- Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley)
2.0.41.1 March 04, 2021
-----------------------

View File

@ -77,7 +77,21 @@ class EmailValidator extends Validator
$valid = false;
} else {
if ($this->enableIDN) {
$matches['local'] = $this->idnToAscii($matches['local']);
// https://github.com/yiisoft/yii2/issues/18585
$localIDNTest = $this->idnToAscii($matches['local']);
if ($localIDNTest === false) {
$newPatternExploded = explode('@', $this->pattern);
$newPattern = $newPatternExploded[0] . "$/";
$newFullPatternExploded = explode('@', $this->fullPattern);
$newFullPattern = $newFullPatternExploded[0] . '@' . $newFullPatternExploded[1] ."$/";
if (!preg_match($newPattern, $matches['local']) || ($this->allowName && preg_match($newFullPattern, $matches['local']))) {
$matches['local'] = $localIDNTest;
}
} else {
$matches['local'] = $localIDNTest;
}
$matches['domain'] = $this->idnToAscii($matches['domain']);
$value = $matches['name'] . $matches['open'] . $matches['local'] . '@' . $matches['domain'] . $matches['close'];
}

View File

@ -33,6 +33,7 @@ class EmailValidatorTest extends TestCase
$this->assertTrue($validator->validate('Abc.123@example.com'));
$this->assertTrue($validator->validate('user+mailbox/department=shipping@example.com'));
$this->assertTrue($validator->validate('!#$%&\'*+-/=?^_`.{|}~@example.com'));
$this->assertTrue($validator->validate('firstName.x.lastName.-nd@example.com'));
$this->assertFalse($validator->validate('rmcreative.ru'));
$this->assertFalse($validator->validate('Carsten Brandt <mail@cebe.cc>'));
$this->assertFalse($validator->validate('"Carsten Brandt" <mail@cebe.cc>'));
@ -50,6 +51,7 @@ class EmailValidatorTest extends TestCase
$this->assertTrue($validator->validate('Carsten Brandt <mail@cebe.cc>'));
$this->assertTrue($validator->validate('"Carsten Brandt" <mail@cebe.cc>'));
$this->assertTrue($validator->validate('<mail@cebe.cc>'));
$this->assertTrue($validator->validate('"FirstName LastName" <firstName.x.lastName.-nd@example.com>'));
$this->assertFalse($validator->validate('info@örtliches.de'));
$this->assertFalse($validator->validate('üñîçøðé@üñîçøðé.com'));
$this->assertFalse($validator->validate('sam@рмкреатиф.ru'));
@ -61,6 +63,7 @@ class EmailValidatorTest extends TestCase
$this->assertFalse($validator->validate('Short Name <localPartMoreThan64Characters-blah-blah-blah-blah-blah-blah-blah-blah@example.com>'));
$this->assertFalse($validator->validate('Short Name <domainNameIsMoreThan254Characters@example-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah.com>'));
$this->assertFalse($validator->validate(['developer@yiiframework.com']));
}
public function testValidateValueIdn()
@ -81,6 +84,7 @@ class EmailValidatorTest extends TestCase
$this->assertTrue($validator->validate('sam@rmcreative.ru'));
$this->assertTrue($validator->validate('5011@gmail.com'));
$this->assertTrue($validator->validate('üñîçøðé@üñîçøðé.com'));
$this->assertTrue($validator->validate('firstName.x.lastName.-nd@example.com'));
$this->assertFalse($validator->validate('rmcreative.ru'));
$this->assertFalse($validator->validate('Carsten Brandt <mail@cebe.cc>'));
$this->assertFalse($validator->validate('"Carsten Brandt" <mail@cebe.cc>'));
@ -102,6 +106,7 @@ class EmailValidatorTest extends TestCase
$this->assertTrue($validator->validate('test@example.com'));
$this->assertTrue($validator->validate('John Smith <john.smith@example.com>'));
$this->assertTrue($validator->validate('"Такое имя достаточно длинное, но оно все равно может пройти валидацию" <shortmail@example.com>'));
$this->assertTrue($validator->validate('"FirstName LastName" <firstName.x.lastName.-nd@example.com>'));
$this->assertFalse($validator->validate('John Smith <example.com>'));
$this->assertFalse($validator->validate('Короткое имя <после-преобразования-в-idn-тут-будет-больше-чем-64-символа@пример.com>'));
$this->assertFalse($validator->validate('Короткое имя <тест@это-доменное-имя.после-преобразования-в-idn.будет-содержать-больше-254-символов.бла-бла-бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.com>'));