Skip to content

Commit

Permalink
feature #24308 [Validator] support protocolless urls validation (MyDi…
Browse files Browse the repository at this point in the history
…gitalLife)

This PR was merged into the 4.1-dev branch.

Discussion
----------

[Validator] support protocolless urls validation

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #24287
| License       | MIT

As specified in issue #24287 URL's starting with no protocol but with just `//` are valid URL's and should be accepted by the validator. This pull request fixes the regex used to validate URL's.

Commits
-------

d845406 [Validator] support protocolless urls validation
  • Loading branch information
nicolas-grekas committed Feb 14, 2018
2 parents d7658d2 + d845406 commit e684973
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Symfony/Component/Validator/Constraints/Url.php
Expand Up @@ -104,6 +104,7 @@ class Url extends Constraint
* @deprecated since Symfony 4.1, to be removed in 5.0
*/
public $checkDNS = self::CHECK_DNS_TYPE_NONE;
public $relativeProtocol = false;

public function __construct($options = null)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Validator/Constraints/UrlValidator.php
Expand Up @@ -61,7 +61,8 @@ public function validate($value, Constraint $constraint)
return;
}

$pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols));
$pattern = $constraint->relativeProtocol ? str_replace('(%s):', '(?:(%s):)?', static::PATTERN) : static::PATTERN;
$pattern = sprintf($pattern, implode('|', $constraint->protocols));

if (!preg_match($pattern, $value)) {
$this->context->buildViolation($constraint->message)
Expand Down
Expand Up @@ -65,6 +65,30 @@ public function testValidUrls($url)
$this->assertNoViolation();
}

/**
* @dataProvider getValidRelativeUrls
* @dataProvider getValidUrls
*/
public function testValidRelativeUrl($url)
{
$constraint = new Url(array(
'relativeProtocol' => true,
));

$this->validator->validate($url, $constraint);

$this->assertNoViolation();
}

public function getValidRelativeUrls()
{
return array(
array('//google.com'),
array('//symfony.fake/blog/'),
array('//symfony.com/search?type=&q=url+validator'),
);
}

public function getValidUrls()
{
return array(
Expand Down Expand Up @@ -147,6 +171,46 @@ public function testInvalidUrls($url)
->assertRaised();
}

/**
* @dataProvider getInvalidRelativeUrls
* @dataProvider getInvalidUrls
*/
public function testInvalidRelativeUrl($url)
{
$constraint = new Url(array(
'message' => 'myMessage',
'relativeProtocol' => true,
));

$this->validator->validate($url, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$url.'"')
->setCode(Url::INVALID_URL_ERROR)
->assertRaised();
}

public function getInvalidRelativeUrls()
{
return array(
array('/google.com'),
array('//goog_le.com'),
array('//google.com::aa'),
array('//google.com:aa'),
array('//127.0.0.1:aa/'),
array('//[::1'),
array('//hello.☎/'),
array('//:password@symfony.com'),
array('//:password@@symfony.com'),
array('//username:passwordsymfony.com'),
array('//usern@me:password@symfony.com'),
array('//example.com/exploit.html?<script>alert(1);</script>'),
array('//example.com/exploit.html?hel lo'),
array('//example.com/exploit.html?not_a%hex'),
array('//'),
);
}

public function getInvalidUrls()
{
return array(
Expand Down

0 comments on commit e684973

Please sign in to comment.