Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored: beberlei pointed me to some strange behaviors of filter_v…

…ar(). So I adapted SF2 code for a more secure assertion.
  • Loading branch information...
commit e3f2ad419d74cdb31716142aed112cfa38664202 1 parent ac66f95
Bastian Feder lapistano authored
Showing with 50 additions and 7 deletions.
  1. +27 −3 lib/Assert/Assertion.php
  2. +23 −4 tests/Assert/Tests/AssertTest.php
30 lib/Assert/Assertion.php
View
@@ -650,20 +650,44 @@ static public function email($value, $message = null, $propertyPath = null)
}
/**
- * Assert that value is an URL (using
- * input_filter/FILTER_VALIDATE_URL).
+ * Assert that value is an URL.
+ *
+ * This code snipped was taken from the Symfony project and modified to the special demands of this method.
*
* @param mixed $value
* @param string $message
* @param string $propertyPath
* @return void
* @throws \Assert\AssertionFailedException
+ *
+ *
+ * @link https://github.com/symfony/Validator/blob/master/Constraints/UrlValidator.php
+ * @link https://github.com/symfony/Validator/blob/master/Constraints/Url.php
*/
static public function url($value, $message = null, $propertyPath = null)
{
static::string($value, $message, $propertyPath);
- if ( !filter_var($value, FILTER_VALIDATE_URL)) {
+ $protocols = array('http', 'https');
+
+ $pattern = '~^
+ (%s):// # protocol
+ (
+ ([\pL\pN\pS-]+\.)+[\pL]+ # a domain name
+ | # or
+ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # a IP address
+ | # or
+ \[
+ (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
+ \] # a IPv6 address
+ )
+ (:[0-9]+)? # a port (optional)
+ (/?|/\S+) # a /, nothing or a / with something
+ $~ixu';
+
+ $pattern = sprintf($pattern, implode('|', $protocols));
+
+ if (!preg_match($pattern, $value)) {
throw static::createException($message, static::INVALID_URL, $propertyPath);
}
27 tests/Assert/Tests/AssertTest.php
View
@@ -343,19 +343,38 @@ public function testValidEmail()
public function testInvalidUrl($url)
{
$this->setExpectedException('Assert\AssertionFailedException', null, Assertion::INVALID_URL);
+
Assertion::url($url);
}
public static function invalidUrlDataprovider()
{
return array(
- 'empty string' => array(""),
- 'no protocol' => array("url.de"),
+ 'null value' => array(""),
+ 'empty string' => array(" "),
+ 'no scheme' => array("url.de"),
+ 'unsupported scheme' => array("git://url.de"),
+ 'Http with query (no / between tld und ?)' => array("http://example.org?do=something"),
+ 'Http with query and port (no / between port und ?)' => array("http://example.org:8080?do=something"),
);
}
- public function testValidUrl()
+ /**
+ * @dataProvider validUrlDataprovider
+ */
+ public function testValidUrl($url)
+ {
+ Assertion::url($url);
+ }
+ public static function validUrlDataprovider()
{
- Assertion::url("http://example.org");
+ return array(
+ 'straight with Http' => array("http://example.org"),
+ 'Http with path' => array("http://example.org/do/something"),
+ 'Http with query' => array("http://example.org/index.php?do=something"),
+ 'Http with port' => array("http://example.org:8080"),
+ 'Http with all possibilities' => array("http://example.org:8080/do/something/index.php?do=something"),
+ 'straight with Https' => array("https://example.org"),
+ );
}
public function testInvalidDigit()
Please sign in to comment.
Something went wrong with that request. Please try again.