Skip to content

Commit 4faa61f

Browse files
committed
Don't throw exceptions until after checking anyOf / oneOf (jsonrainbow#394)
Fixes jsonrainbow#393
1 parent ec7ed3e commit 4faa61f

File tree

2 files changed

+62
-8
lines changed

2 files changed

+62
-8
lines changed

src/JsonSchema/Constraints/UndefinedConstraint.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
1313
use JsonSchema\Entity\JsonPointer;
14+
use JsonSchema\Exception\ValidationException;
1415
use JsonSchema\Uri\UriResolver;
1516

1617
/**
@@ -243,11 +244,16 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i
243244
if (isset($schema->anyOf)) {
244245
$isValid = false;
245246
$startErrors = $this->getErrors();
247+
$caughtException = null;
246248
foreach ($schema->anyOf as $anyOf) {
247249
$initErrors = $this->getErrors();
248-
$this->checkUndefined($value, $anyOf, $path, $i);
249-
if ($isValid = (count($this->getErrors()) == count($initErrors))) {
250-
break;
250+
try {
251+
$this->checkUndefined($value, $anyOf, $path, $i);
252+
if ($isValid = (count($this->getErrors()) == count($initErrors))) {
253+
break;
254+
}
255+
} catch (ValidationException $e) {
256+
$isValid = false;
251257
}
252258
}
253259
if (!$isValid) {
@@ -262,12 +268,17 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i
262268
$matchedSchemas = 0;
263269
$startErrors = $this->getErrors();
264270
foreach ($schema->oneOf as $oneOf) {
265-
$this->errors = array();
266-
$this->checkUndefined($value, $oneOf, $path, $i);
267-
if (count($this->getErrors()) == 0) {
268-
$matchedSchemas++;
271+
try {
272+
$this->errors = array();
273+
$this->checkUndefined($value, $oneOf, $path, $i);
274+
if (count($this->getErrors()) == 0) {
275+
$matchedSchemas++;
276+
}
277+
$allErrors = array_merge($allErrors, array_values($this->getErrors()));
278+
} catch (ValidationException $e) {
279+
// deliberately do nothing here - validation failed, but we want to check
280+
// other schema options in the OneOf field.
269281
}
270-
$allErrors = array_merge($allErrors, array_values($this->getErrors()));
271282
}
272283
if ($matchedSchemas !== 1) {
273284
$this->addErrors(array_merge($allErrors, $startErrors));

tests/Constraints/OfPropertiesTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
namespace JsonSchema\Tests\Constraints;
1010

11+
use JsonSchema\Constraints\Constraint;
12+
use JsonSchema\Validator;
13+
1114
/**
1215
* Class OfPropertiesTest
1316
*/
@@ -208,4 +211,44 @@ public function getInvalidTests()
208211
)
209212
);
210213
}
214+
215+
public function testNoPrematureAnyOfException()
216+
{
217+
$schema = json_decode('{
218+
"type": "object",
219+
"properties": {
220+
"propertyOne": {
221+
"anyOf": [
222+
{"type": "number"},
223+
{"type": "string"}
224+
]
225+
}
226+
}
227+
}');
228+
$data = json_decode('{"propertyOne":"ABC"}');
229+
230+
$v = new Validator();
231+
$v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS);
232+
$this->assertTrue($v->isValid());
233+
}
234+
235+
public function testNoPrematureOneOfException()
236+
{
237+
$schema = json_decode('{
238+
"type": "object",
239+
"properties": {
240+
"propertyOne": {
241+
"oneOf": [
242+
{"type": "number"},
243+
{"type": "string"}
244+
]
245+
}
246+
}
247+
}');
248+
$data = json_decode('{"propertyOne":"ABC"}');
249+
250+
$v = new Validator();
251+
$v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS);
252+
$this->assertTrue($v->isValid());
253+
}
211254
}

0 commit comments

Comments
 (0)