From f2f8b0cf0e7f6b9ed425b294e0d5dfc875076a65 Mon Sep 17 00:00:00 2001 From: Erayd Date: Sat, 11 Mar 2017 07:04:03 +1300 Subject: [PATCH 1/3] Add provided schema under a dummy / internal URI (fixes #376) In order to resolve internal $ref references within a user-provided schema, SchemaStorage needs to know about the schema. As user-supplied schemas do not have an associated URI, use a dummy / internal one instead. --- src/JsonSchema/SchemaStorage.php | 6 +++++- src/JsonSchema/Validator.php | 3 +++ tests/SchemaStorageTest.php | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index 6450572e..fe0d1b38 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -3,6 +3,7 @@ namespace JsonSchema; use JsonSchema\Entity\JsonPointer; +use JsonSchema\Exception\InvalidArgumentException; use JsonSchema\Exception\UnresolvableJsonPointerException; use JsonSchema\Iterator\ObjectIterator; use JsonSchema\Uri\UriResolver; @@ -43,7 +44,10 @@ public function getUriResolver() */ public function addSchema($id, $schema = null) { - if (is_null($schema)) { + if (is_null($schema) && $id !== 'internal://provided-schema') { + // if the schema was user-provided to Validator and is still null, then assume this is + // what the user intended, as there's no way for us to retrieve anything else. User-supplied + // schemas do not have an associated URI when passed via Validator::validate(). $schema = $this->uriRetriever->retrieve($id); } $objectIterator = new ObjectIterator($schema); diff --git a/src/JsonSchema/Validator.php b/src/JsonSchema/Validator.php index e2a919bc..4deb8444 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -41,6 +41,9 @@ public function validate(&$value, $schema = null, $checkMode = null) $this->factory->setConfig($checkMode); } + // add provided schema to SchemaStorage with internal URI to allow internal $ref resolution + $this->factory->getSchemaStorage()->addSchema('internal://provided-schema', $schema); + $validator = $this->factory->createInstanceFor('schema'); $validator->check($value, $schema); diff --git a/tests/SchemaStorageTest.php b/tests/SchemaStorageTest.php index c3388bf4..92e1d5c3 100644 --- a/tests/SchemaStorageTest.php +++ b/tests/SchemaStorageTest.php @@ -11,6 +11,7 @@ use JsonSchema\SchemaStorage; use JsonSchema\Uri\UriRetriever; +use JsonSchema\Validator; use Prophecy\Argument; class SchemaStorageTest extends \PHPUnit_Framework_TestCase @@ -31,6 +32,15 @@ public function testResolveRef() ); } + public function testResolveTopRef() + { + $input = json_decode('{"propertyOne":"notANumber"}'); + $schema = json_decode('{"$ref":"#/definition","definition":{"properties":{"propertyOne":{"type":"number"}}}}'); + $v = new Validator(); + $v->validate($input, $schema); + $this->assertFalse($v->isValid()); + } + /** * @depends testResolveRef */ From 44c1e649b558e47f27c59fd6a2a85bb3562bcf13 Mon Sep 17 00:00:00 2001 From: Erayd Date: Sun, 12 Mar 2017 10:26:57 +1300 Subject: [PATCH 2/3] Remove dangling use --- src/JsonSchema/SchemaStorage.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index fe0d1b38..bbb7d537 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -3,7 +3,6 @@ namespace JsonSchema; use JsonSchema\Entity\JsonPointer; -use JsonSchema\Exception\InvalidArgumentException; use JsonSchema\Exception\UnresolvableJsonPointerException; use JsonSchema\Iterator\ObjectIterator; use JsonSchema\Uri\UriResolver; From d2835a71674797e29920c961fbe2cb71694f5238 Mon Sep 17 00:00:00 2001 From: Erayd Date: Sun, 12 Mar 2017 10:27:37 +1300 Subject: [PATCH 3/3] Change URI to class constant on SchemaStorage --- src/JsonSchema/SchemaStorage.php | 4 +++- src/JsonSchema/Validator.php | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/JsonSchema/SchemaStorage.php b/src/JsonSchema/SchemaStorage.php index bbb7d537..55d7985a 100644 --- a/src/JsonSchema/SchemaStorage.php +++ b/src/JsonSchema/SchemaStorage.php @@ -10,6 +10,8 @@ class SchemaStorage implements SchemaStorageInterface { + const INTERNAL_PROVIDED_SCHEMA_URI = 'internal://provided-schema'; + protected $uriRetriever; protected $uriResolver; protected $schemas = array(); @@ -43,7 +45,7 @@ public function getUriResolver() */ public function addSchema($id, $schema = null) { - if (is_null($schema) && $id !== 'internal://provided-schema') { + if (is_null($schema) && $id !== self::INTERNAL_PROVIDED_SCHEMA_URI) { // if the schema was user-provided to Validator and is still null, then assume this is // what the user intended, as there's no way for us to retrieve anything else. User-supplied // schemas do not have an associated URI when passed via Validator::validate(). diff --git a/src/JsonSchema/Validator.php b/src/JsonSchema/Validator.php index 4deb8444..9f44e512 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -12,6 +12,7 @@ use JsonSchema\Constraints\BaseConstraint; use JsonSchema\Constraints\Constraint; use JsonSchema\Exception\InvalidConfigException; +use JsonSchema\SchemaStorage; /** * A JsonSchema Constraint @@ -42,7 +43,7 @@ public function validate(&$value, $schema = null, $checkMode = null) } // add provided schema to SchemaStorage with internal URI to allow internal $ref resolution - $this->factory->getSchemaStorage()->addSchema('internal://provided-schema', $schema); + $this->factory->getSchemaStorage()->addSchema(SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI, $schema); $validator = $this->factory->createInstanceFor('schema'); $validator->check($value, $schema);