Skip to content

Commit 0d46d20

Browse files
committed
Don't throw exceptions until after checking anyOf / oneOf
Fixes #393
1 parent cf8e886 commit 0d46d20

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
@@ -12,6 +12,7 @@
1212
use JsonSchema\ConstraintError;
1313
use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
1414
use JsonSchema\Entity\JsonPointer;
15+
use JsonSchema\Exception\ValidationException;
1516
use JsonSchema\Uri\UriResolver;
1617

1718
/**
@@ -245,11 +246,16 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i
245246
if (isset($schema->anyOf)) {
246247
$isValid = false;
247248
$startErrors = $this->getErrors();
249+
$caughtException = null;
248250
foreach ($schema->anyOf as $anyOf) {
249251
$initErrors = $this->getErrors();
250-
$this->checkUndefined($value, $anyOf, $path, $i);
251-
if ($isValid = (count($this->getErrors()) == count($initErrors))) {
252-
break;
252+
try {
253+
$this->checkUndefined($value, $anyOf, $path, $i);
254+
if ($isValid = (count($this->getErrors()) == count($initErrors))) {
255+
break;
256+
}
257+
} catch (ValidationException $e) {
258+
$isValid = false;
253259
}
254260
}
255261
if (!$isValid) {
@@ -264,12 +270,17 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i
264270
$matchedSchemas = 0;
265271
$startErrors = $this->getErrors();
266272
foreach ($schema->oneOf as $oneOf) {
267-
$this->errors = array();
268-
$this->checkUndefined($value, $oneOf, $path, $i);
269-
if (count($this->getErrors()) == 0) {
270-
$matchedSchemas++;
273+
try {
274+
$this->errors = array();
275+
$this->checkUndefined($value, $oneOf, $path, $i);
276+
if (count($this->getErrors()) == 0) {
277+
$matchedSchemas++;
278+
}
279+
$allErrors = array_merge($allErrors, array_values($this->getErrors()));
280+
} catch (ValidationException $e) {
281+
// deliberately do nothing here - validation failed, but we want to check
282+
// other schema options in the OneOf field.
271283
}
272-
$allErrors = array_merge($allErrors, array_values($this->getErrors()));
273284
}
274285
if ($matchedSchemas !== 1) {
275286
$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
*/
@@ -223,4 +226,44 @@ public function getInvalidTests()
223226
)
224227
);
225228
}
229+
230+
public function testNoPrematureAnyOfException()
231+
{
232+
$schema = json_decode('{
233+
"type": "object",
234+
"properties": {
235+
"propertyOne": {
236+
"anyOf": [
237+
{"type": "number"},
238+
{"type": "string"}
239+
]
240+
}
241+
}
242+
}');
243+
$data = json_decode('{"propertyOne":"ABC"}');
244+
245+
$v = new Validator();
246+
$v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS);
247+
$this->assertTrue($v->isValid());
248+
}
249+
250+
public function testNoPrematureOneOfException()
251+
{
252+
$schema = json_decode('{
253+
"type": "object",
254+
"properties": {
255+
"propertyOne": {
256+
"oneOf": [
257+
{"type": "number"},
258+
{"type": "string"}
259+
]
260+
}
261+
}
262+
}');
263+
$data = json_decode('{"propertyOne":"ABC"}');
264+
265+
$v = new Validator();
266+
$v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS);
267+
$this->assertTrue($v->isValid());
268+
}
226269
}

0 commit comments

Comments
 (0)