Skip to content

Commit

Permalink
Fix non-conforming URL validation
Browse files Browse the repository at this point in the history
Json schema spec says URLs are validated as per RFC-3986, but PHP's
FILTER_VALIDATE_URL can't cope with relative path references, which are
explicitly allowed. See https://tools.ietf.org/html/rfc3986#section-4.2
for further information.
  • Loading branch information
erayd committed Feb 22, 2017
1 parent ffb35e9 commit b415918
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/JsonSchema/Constraints/FormatConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,26 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =

case 'uri':
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
$this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format));
// FILTER_VALIDATE_URL does not conform to RFC-3986, and cannot handle relative URLs, but
// the json-schema spec uses RFC-3986, so need a bit of hackery to properly validate them.
// See https://tools.ietf.org/html/rfc3986#section-4.2 for additional information.
if (substr($element, 0, 2) === '//') { // network-path reference
$validURL = filter_var('scheme:' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
} elseif (substr($element, 0, 1) === '/') { // absolute-path reference
$validURL = filter_var('scheme://host' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
} elseif (strlen($element)) { // relative-path reference
$pathParts = explode('/', $element, 2)[0];
if ($pathParts[0] !== '.' && strpos($pathParts, ':') !== false) {
$validURL = null;
} else {
$validURL = filter_var('scheme://host/' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
}
} else {
$validURL = null;
}
if ($validURL === null) {
$this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format));
}
}
break;

Expand Down
4 changes: 4 additions & 0 deletions tests/Constraints/FormatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ public function getValidFormats()
array('555 320 1212', 'phone'),

array('http://bluebox.org', 'uri'),
array('//bluebox.org', 'uri'),
array('/absolutePathReference/', 'uri'),
array('relativePathReference/', 'uri'),

array('[email protected]', 'email'),

Expand Down Expand Up @@ -175,6 +178,7 @@ public function getInvalidFormats()
array('1 123 4424', 'phone'),

array('htt:/bluebox.org', 'uri'),
array('', 'uri'),

array('info@somewhere', 'email'),

Expand Down

0 comments on commit b415918

Please sign in to comment.