Skip to content

Commit 2d404b8

Browse files
eraydbighappyface
authored andcommitted
[BUGFIX] Split "uri" format into "uri" & "uri-reference", fix meta-schema bug (#419)
* Split "uri" format into "uri" and "uri-reference" * Correct format for id & $ref in draft-03/04 meta-schemas See json-schema-org/JSON-Schema-Test-Suite#177 (comment)
1 parent 9fe7822 commit 2d404b8

File tree

5 files changed

+46
-7
lines changed

5 files changed

+46
-7
lines changed

src/JsonSchema/ConstraintError.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ConstraintError extends Enum
2828
const FORMAT_STYLE = 'styleFormat';
2929
const FORMAT_TIME = 'timeFormat';
3030
const FORMAT_URL = 'urlFormat';
31+
const FORMAT_URL_REF = 'urlRefFormat';
3132
const INVALID_SCHEMA = 'invalidSchema';
3233
const LENGTH_MAX = 'maxLength';
3334
const LENGTH_MIN = 'minLength';
@@ -77,6 +78,7 @@ public function getMessage()
7778
self::FORMAT_STYLE => 'Invalid style',
7879
self::FORMAT_TIME => 'Invalid time %s, expected format hh:mm:ss',
7980
self::FORMAT_URL => 'Invalid URL format',
81+
self::FORMAT_URL_REF => 'Invalid URL reference format',
8082
self::LENGTH_MAX => 'Must be at most %d characters long',
8183
self::INVALID_SCHEMA => 'Schema is not valid',
8284
self::LENGTH_MIN => 'Must be at least %d characters long',

src/JsonSchema/Constraints/FormatConstraint.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =
9999
break;
100100

101101
case 'uri':
102+
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
103+
$this->addError(ConstraintError::FORMAT_URL(), $path, array('format' => $schema->format));
104+
}
105+
break;
106+
107+
case 'uriref':
108+
case 'uri-reference':
102109
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
103110
// FILTER_VALIDATE_URL does not conform to RFC-3986, and cannot handle relative URLs, but
104111
// the json-schema spec uses RFC-3986, so need a bit of hackery to properly validate them.
@@ -118,7 +125,7 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =
118125
$validURL = null;
119126
}
120127
if ($validURL === null) {
121-
$this->addError(ConstraintError::FORMAT_URL(), $path, array('format' => $schema->format));
128+
$this->addError(ConstraintError::FORMAT_URL_REF(), $path, array('format' => $schema->format));
122129
}
123130
}
124131
break;

src/JsonSchema/SchemaStorage.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ public function addSchema($id, $schema = null)
5858
$schema = BaseConstraint::arrayToObjectRecursive($schema);
5959
}
6060

61+
// workaround for bug in draft-03 & draft-04 meta-schemas (id & $ref defined with incorrect format)
62+
// see https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/177#issuecomment-293051367
63+
if (is_object($schema) && property_exists($schema, 'id')) {
64+
if ($schema->id == 'http://json-schema.org/draft-04/schema#') {
65+
$schema->properties->id->format = 'uri-reference';
66+
} elseif ($schema->id == 'http://json-schema.org/draft-03/schema#') {
67+
$schema->properties->id->format = 'uri-reference';
68+
$schema->properties->{'$ref'}->format = 'uri-reference';
69+
}
70+
}
71+
6172
$objectIterator = new ObjectIterator($schema);
6273
foreach ($objectIterator as $toResolveSchema) {
6374
if (property_exists($toResolveSchema, '$ref') && is_string($toResolveSchema->{'$ref'})) {

tests/Constraints/FormatTest.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,12 @@ public function getValidFormats()
143143
array('555 320 1212', 'phone'),
144144

145145
array('http://bluebox.org', 'uri'),
146-
array('//bluebox.org', 'uri'),
147-
array('/absolutePathReference/', 'uri'),
148-
array('./relativePathReference/', 'uri'),
149-
array('./relative:PathReference/', 'uri'),
150-
array('relativePathReference/', 'uri'),
151-
array('relative/Path:Reference/', 'uri'),
146+
array('//bluebox.org', 'uri-reference'),
147+
array('/absolutePathReference/', 'uri-reference'),
148+
array('./relativePathReference/', 'uri-reference'),
149+
array('./relative:PathReference/', 'uri-reference'),
150+
array('relativePathReference/', 'uri-reference'),
151+
array('relative/Path:Reference/', 'uri-reference'),
152152

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

@@ -200,6 +200,12 @@ public function getInvalidFormats()
200200
array('htt:/bluebox.org', 'uri'),
201201
array('.relative:path/reference/', 'uri'),
202202
array('', 'uri'),
203+
array('//bluebox.org', 'uri'),
204+
array('/absolutePathReference/', 'uri'),
205+
array('./relativePathReference/', 'uri'),
206+
array('./relative:PathReference/', 'uri'),
207+
array('relativePathReference/', 'uri'),
208+
array('relative/Path:Reference/', 'uri'),
203209

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

tests/SchemaStorageTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,17 @@ public function testGetUriResolver()
289289
$s->addSchema('http://json-schema.org/draft-04/schema#');
290290
$this->assertInstanceOf('\JsonSchema\Uri\UriResolver', $s->getUriResolver());
291291
}
292+
293+
public function testMetaSchemaFixes()
294+
{
295+
$s = new SchemaStorage();
296+
$s->addSchema('http://json-schema.org/draft-03/schema#');
297+
$s->addSchema('http://json-schema.org/draft-04/schema#');
298+
$draft_03 = $s->getSchema('http://json-schema.org/draft-03/schema#');
299+
$draft_04 = $s->getSchema('http://json-schema.org/draft-04/schema#');
300+
301+
$this->assertEquals('uri-reference', $draft_03->properties->id->format);
302+
$this->assertEquals('uri-reference', $draft_03->properties->{'$ref'}->format);
303+
$this->assertEquals('uri-reference', $draft_04->properties->id->format);
304+
}
292305
}

0 commit comments

Comments
 (0)