-
Notifications
You must be signed in to change notification settings - Fork 354
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
Fix infinite recursion on some schemas when setting defaults (#359) #365
Fix infinite recursion on some schemas when setting defaults (#359) #365
Conversation
9e30166
to
bb014e4
Compare
LGTM |
hmm in fact there's still an issue when trying to validate a schema, this fails : <?php
include_once __DIR__."/../vendor/autoload.php";
$validator = new \JsonSchema\Validator();
$data = (object)["propertyOne" => (object)[]];
$schema = (object)['$ref' => 'http://json-schema.org/draft-04/schema'];
echo __LINE__, PHP_EOL;
$validator->validate($data, $schema);
var_dump($validator->isValid());
echo __LINE__, PHP_EOL;
$validator->validate(
$data,
$schema,
\JsonSchema\Constraints\Constraint::CHECK_MODE_APPLY_DEFAULTS | \JsonSchema\Constraints\Constraint::CHECK_MODE_REQUIRE_DEFAULTS
);
var_dump($validator->isValid());
echo __LINE__, PHP_EOL;
|
I think |
Thanks - I'll get onto this in the morning; it's 11pm here :-). Note that I have not yet implemented a recursion fix in this PR - that is coming. |
Bit more complex than that - need to check whether they are actually required - but god knows what I was thinking when I committed the required-defaults-only feature it in its current state; it's more than a little bit incomplete! |
bb014e4
to
16a28ff
Compare
@mathroc Sorted. I also renamed the option to Still need to address the recursion thing. |
return true; | ||
} | ||
// draft-03 required is set | ||
if (isset($definition->required) && !is_array($definition->required) && $definition->required) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$definition->required
can be something else than a boolean ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup - in draft-04, it's an array of strings.
looks neat, I'll test it in the morning; it's 11pm here ;)
if I got this right, I don't think there is a recursion thing when |
@mathroc Sounds like we are in timezones exactly 12 hours apart! You're in the UK?
There could be if you wrote a schema that required the looping defaults. Plus, it turns out that the spec says that validators aren't allowed to infinitely recurse, so I still have to deal with it. Thanks for your good wishes! :-) |
France, you're in NZ ?
indeed. I wonder: is there a "finite" json document that would be valid according to such a schema ? (even without applying defaults) {
"$anyOf": [{
"type" : "object",
"properties": {
"a": {
"type": "string",
"default": "A"
}
},
"required" : ["a"],
"additionalProperties": false
},{
"type" : "object",
"properties": {
"b": {
"type": "string",
"default": "B"
}
},
"required" : ["b"],
"additionalProperties": false
}]
} |
Yep, I'm a Kiwi :-). Re your schema question - as I understand it, the schema you have quoted above would be satisfied by either an object containing only a string |
yes but what would be the json document if called with en empty object and the it should be either an object containing only a string b, or an object containing only a string a, yes. but which one? I've not tested it, but it might also return an object with both so now, there is valid json documents for this schema : {
"$anyOf": [{
"type" : "object",
"properties": {
"a": {
"$ref": "#",
"default": {}
}
},
"required" : ["a"],
"additionalProperties": false
},{
"type" : "object",
"additionalProperties": false
}]
} but the current version of lib would recurse infinitely. what should the fixed version return ? and I think that's a schema would have the issue even with ps: sorry if I'm being too talkative |
I'll have to think on it - let me fix the recursion first! |
And no, you're not being too talkative - you're making me think, which is a good thing here. |
Never mind, my brain cooperated and threw up an array recursion: {
"items": [
{
"$ref": "#",
"default": []
}
]
} Time to deal with the array cases now... |
11de406
to
8af9398
Compare
Rebased. |
Travis fail is Travis' fault; the build for PHP-7.1 never ran. Tests should all be passing. |
I don't entirely follow all this, but I see no obvious black holes. LGTM |
@shmax Which part(s) are you finding confusing? I tried to make it obvious what I was doing, but if it's problematic for you to follow, maybe I wasn't clear enough - it might be worth my while to add some more comments in the code. |
Naw, I meant the meta discussion regarding recursion and the finer points of the spec and such; had my attention elsewhere while it was going on and I didn't follow along as closely as I should have. I trust that you guys have it properly sorted, and the code looks fine. LGTM |
Gotcha - thanks :-) |
I finally took the time to look at it and test it, everything looks fine to me, LGTM! |
not that it matters that much, but why is this pr for 6.0.0-dev instead of master ? it does not seems to contains BC break |
@shmax @mathroc I have just added one final commit after your LGTMs to fix #377 (c92dfae), if you also wish to review that. I would have done it as a separate PR, except that the default code has significantly changed in this one, so it was more logical to put it here. @bighappyface Anything else that needs doing to this PR before merging? |
Throws an exception when the ref can't be resolved to a useful file URI, rather than waiting for something further down the line to fail after the fact.
If CHECK_MODE_ONLY_REQUIRED_DEFAULTS is set, then only apply defaults if they are marked as required.
c92dfae
to
f63d938
Compare
Rebased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
…nbow#359) (jsonrainbow#365) * Don't try to fetch files that don't exist Throws an exception when the ref can't be resolved to a useful file URI, rather than waiting for something further down the line to fail after the fact. * Refactor defaults code to use LooseTypeCheck where appropriate * Test for not treating non-containers like arrays * Update comments * Rename variable for clarity * Add CHECK_MODE_ONLY_REQUIRED_DEFAULTS If CHECK_MODE_ONLY_REQUIRED_DEFAULTS is set, then only apply defaults if they are marked as required. * Workaround for $this scope issue on PHP-5.3 * Fix infinite recursion via $ref when applying defaults * Add missing second test for array case * Add test for setting a default value for null * Also fix infinite recursion via $ref for array defaults * Move nested closure into separate method * $parentSchema will always be set when $name is, so don't check it * Handle nulls properly - fixes issue jsonrainbow#377
* Add URI translation for retrieval & add local copies of spec schema * Add use line for InvalidArgumentException & adjust scope (#372) Fixes issue #371 * add quiet option (#382) * add quiet option * use verbose instead of quiet * add quiet option * always output dump-schema * always output dump-schema-url * fix typo and ws * [BUGFIX] Add provided schema under a dummy / internal URI (fixes #376) (#378) * 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. * Remove dangling use * Change URI to class constant on SchemaStorage * Add option to disable validation of "format" constraint (#383) * Add more unit tests (#366) * Add test coverage for coercion API * Complete test coverage for SchemaStorage * Add test coverage for ObjectIterator * Add exception test for JsonPointer * MabeEnum\Enum appears to use singletons - add testing const * Don't check this line for coverage mbstring is on all test platforms, so this line will never be reached. * Add test for TypeConstraint::validateTypeNameWording() * Add test for exception on TypeConstraint::validateType() * PHPunit doesn't like an explanation with its @codeCoverageIgnore... * Add various tests for UriRetriever * Add tests for FileGetContents * Add tests for JsonSchema\Uri\Retrievers\Curl * Add missing bad-syntax test file * Restrict ignore to the exception line only * Fix exception scope * Allow the schema to be an associative array (#389) * Allow the schema to be an associative array Implements #388. * Use json_decode(json_encode()) for array -> object cast * Skip exception check on PHP versions < 5.5.0 * Skip test on HHVM, as it's happy to encode resources * Enable FILTER_FLAG_EMAIL_UNICODE for email format if present (#398) * Don't throw exceptions until after checking anyOf / oneOf (#394) Fixes #393 * Fix infinite recursion on some schemas when setting defaults (#359) (#365) * Don't try to fetch files that don't exist Throws an exception when the ref can't be resolved to a useful file URI, rather than waiting for something further down the line to fail after the fact. * Refactor defaults code to use LooseTypeCheck where appropriate * Test for not treating non-containers like arrays * Update comments * Rename variable for clarity * Add CHECK_MODE_ONLY_REQUIRED_DEFAULTS If CHECK_MODE_ONLY_REQUIRED_DEFAULTS is set, then only apply defaults if they are marked as required. * Workaround for $this scope issue on PHP-5.3 * Fix infinite recursion via $ref when applying defaults * Add missing second test for array case * Add test for setting a default value for null * Also fix infinite recursion via $ref for array defaults * Move nested closure into separate method * $parentSchema will always be set when $name is, so don't check it * Handle nulls properly - fixes issue #377 * Add option to also validate the schema (#357) * Remove stale files from #357 (obviated by #362) (#400) * Stop #386 sneaking in alongside another PR backport
…nbow#359) (jsonrainbow#365) * Don't try to fetch files that don't exist Throws an exception when the ref can't be resolved to a useful file URI, rather than waiting for something further down the line to fail after the fact. * Refactor defaults code to use LooseTypeCheck where appropriate * Test for not treating non-containers like arrays * Update comments * Rename variable for clarity * Add CHECK_MODE_ONLY_REQUIRED_DEFAULTS If CHECK_MODE_ONLY_REQUIRED_DEFAULTS is set, then only apply defaults if they are marked as required. * Workaround for $this scope issue on PHP-5.3 * Fix infinite recursion via $ref when applying defaults * Add missing second test for array case * Add test for setting a default value for null * Also fix infinite recursion via $ref for array defaults * Move nested closure into separate method * $parentSchema will always be set when $name is, so don't check it * Handle nulls properly - fixes issue jsonrainbow#377
Made this PR to collaborate with @mathroc on #359. The root cause has been located and is not a bug, but the recursion needs to be mitigated, as infinite recursion of a validator is in violation of the spec.
Will backport the fix to 5.2.0 once this PR is merged.
Changes Relating to #359
CHECK_MODE_ONLY_REQUIRED_DEFAULTS
Other Changes
Seeing as I'm doing this defaults-related PR anyway, I figured I might as well do a little tidying-up of the defaults code, plus fix any other bugs I run into while tracking this one down.
LooseTypeCheck
where appropriate$ref
null
null
are correctly appliedDefaultPropertiesTest::testLeaveBasicTypesAlone
null
/ not overwritingnull
(fixes Handling of nulls when applying defaults #377)