Skip to content

[BUGFIX] Split "uri" format into "uri" & "uri-reference", fix meta-schema bug #419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/JsonSchema/ConstraintError.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ConstraintError extends Enum
const FORMAT_STYLE = 'styleFormat';
const FORMAT_TIME = 'timeFormat';
const FORMAT_URL = 'urlFormat';
const FORMAT_URL_REF = 'urlRefFormat';
const INVALID_SCHEMA = 'invalidSchema';
const LENGTH_MAX = 'maxLength';
const LENGTH_MIN = 'minLength';
Expand Down Expand Up @@ -77,6 +78,7 @@ public function getMessage()
self::FORMAT_STYLE => 'Invalid style',
self::FORMAT_TIME => 'Invalid time %s, expected format hh:mm:ss',
self::FORMAT_URL => 'Invalid URL format',
self::FORMAT_URL_REF => 'Invalid URL reference format',
self::LENGTH_MAX => 'Must be at most %d characters long',
self::INVALID_SCHEMA => 'Schema is not valid',
self::LENGTH_MIN => 'Must be at least %d characters long',
Expand Down
9 changes: 8 additions & 1 deletion src/JsonSchema/Constraints/FormatConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =
break;

case 'uri':
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
$this->addError(ConstraintError::FORMAT_URL(), $path, array('format' => $schema->format));
}
break;

case 'uriref':
case 'uri-reference':
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
// 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.
Expand All @@ -118,7 +125,7 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =
$validURL = null;
}
if ($validURL === null) {
$this->addError(ConstraintError::FORMAT_URL(), $path, array('format' => $schema->format));
$this->addError(ConstraintError::FORMAT_URL_REF(), $path, array('format' => $schema->format));
}
}
break;
Expand Down
11 changes: 11 additions & 0 deletions src/JsonSchema/SchemaStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ public function addSchema($id, $schema = null)
$schema = BaseConstraint::arrayToObjectRecursive($schema);
}

// workaround for bug in draft-03 & draft-04 meta-schemas (id & $ref defined with incorrect format)
// see https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/177#issuecomment-293051367
if (is_object($schema) && property_exists($schema, 'id')) {
if ($schema->id == 'http://json-schema.org/draft-04/schema#') {
$schema->properties->id->format = 'uri-reference';
} elseif ($schema->id == 'http://json-schema.org/draft-03/schema#') {
$schema->properties->id->format = 'uri-reference';
$schema->properties->{'$ref'}->format = 'uri-reference';
}
}

$objectIterator = new ObjectIterator($schema);
foreach ($objectIterator as $toResolveSchema) {
if (property_exists($toResolveSchema, '$ref') && is_string($toResolveSchema->{'$ref'})) {
Expand Down
18 changes: 12 additions & 6 deletions tests/Constraints/FormatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,12 @@ public function getValidFormats()
array('555 320 1212', 'phone'),

array('http://bluebox.org', 'uri'),
array('//bluebox.org', 'uri'),
array('/absolutePathReference/', 'uri'),
array('./relativePathReference/', 'uri'),
array('./relative:PathReference/', 'uri'),
array('relativePathReference/', 'uri'),
array('relative/Path:Reference/', 'uri'),
array('//bluebox.org', 'uri-reference'),
array('/absolutePathReference/', 'uri-reference'),
array('./relativePathReference/', 'uri-reference'),
array('./relative:PathReference/', 'uri-reference'),
array('relativePathReference/', 'uri-reference'),
array('relative/Path:Reference/', 'uri-reference'),

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

Expand Down Expand Up @@ -200,6 +200,12 @@ public function getInvalidFormats()
array('htt:/bluebox.org', 'uri'),
array('.relative:path/reference/', 'uri'),
array('', 'uri'),
array('//bluebox.org', 'uri'),
array('/absolutePathReference/', 'uri'),
array('./relativePathReference/', 'uri'),
array('./relative:PathReference/', 'uri'),
array('relativePathReference/', 'uri'),
array('relative/Path:Reference/', 'uri'),

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

Expand Down
13 changes: 13 additions & 0 deletions tests/SchemaStorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,17 @@ public function testGetUriResolver()
$s->addSchema('http://json-schema.org/draft-04/schema#');
$this->assertInstanceOf('\JsonSchema\Uri\UriResolver', $s->getUriResolver());
}

public function testMetaSchemaFixes()
{
$s = new SchemaStorage();
$s->addSchema('http://json-schema.org/draft-03/schema#');
$s->addSchema('http://json-schema.org/draft-04/schema#');
$draft_03 = $s->getSchema('http://json-schema.org/draft-03/schema#');
$draft_04 = $s->getSchema('http://json-schema.org/draft-04/schema#');

$this->assertEquals('uri-reference', $draft_03->properties->id->format);
$this->assertEquals('uri-reference', $draft_03->properties->{'$ref'}->format);
$this->assertEquals('uri-reference', $draft_04->properties->id->format);
}
}