default values - RangeError: Maximum call stack size exceeded
fogine opened this issue · 4 comments
What version of Ajv are you using? Does the issue happen if you use the latest version?
6.5.0
Ajv options object
{useDefaults: false}
JSON Schema
function Default() {}
Default.prototype.toJSON = function toJSON() {
return {};
};
const def = new Default;
def.prop = {
Default: def // it fails because of this circular enumerable property
};
const schema = {
type: 'object',
properties: {
prop: {
type: 'object',
default: def
}
}
};
Your code
ajv.addSchema(schema, 'test');
Validation result, data AFTER validation, error messages
RangeError: Maximum call stack size exceeded
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:58:5)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
at _traverse (/path/to/project/node_modules/json-schema-traverse/index.js:72:9)
What results did you expect?
When useDefaults=false
I'd expect that ajv
is gonna ignore default
keyword and not traverse its enumerable properties.
Although it should not fail even with useDefaults=true
when the default value object implements toJSON
method.
Are you going to resolve the issue?
possible bugfix provided here:
epoberezkin/json-schema-traverse#5
In ajv library, used here:
https://github.com/epoberezkin/ajv/blob/master/lib/compile/resolve.js#L239
note: I see now that default
property value is serialized because ajv
option serialize
is not set to false
...
@fogine ajv indeed doesn't support schemas with recursive data structures - they need to be serialisable (unless you disable it, as you wrote, but they would still be used as keys - so unless you use WeakMap as a cache, nothing will work). I will release json-schema-traverse.
@epoberezkin
Evgeny,
ajv indeed doesn't support schemas with recursive data structures
Is it theoretically possible to change that? Пожалуйста?
Only theoretically, I am afraid... The cost would be prohibitive - it's a major design change.
Effectively, what you are asking is to detect cycles and translate them to $refs - this is a more complex operation than avoiding cycles in the first place...
It does seem though like some separate library could possibly do ref-ing, in the same way there is a library that does de-ref-ing, which means it doesn't need to be done as part of Ajv - it can be defined and solved as a relatively isolated CS problem on the level of tech interview questions...