ajv-validator / ajv

The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)
https://ajv.js.org
MIT License
13.75k stars 872 forks source link

RangeError: Maximum call stack size exceeded when using recursive reference #27

Closed jdwilliams15 closed 9 years ago

jdwilliams15 commented 9 years ago

Correct me if I'm doing something wrong. Wrote this based on: http://spacetelescope.github.io/understanding-json-schema/index.html

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "testrec",
  "type": "object",
  "properties": {
    "layout": {
      "id": "layout",
      "type": "object",
      "properties": {
        "layout": { "type": "string" },
        "panels": {
          "type": "array",
          "items": {
            "oneOf": [
              { "type": "string" },
              { "$ref": "layout" }
            ]
          }
        }
      },
      "required": [
        "layout",
        "panels"
      ]
    }
  }
}
epoberezkin commented 9 years ago

I will look into it. I does go into endless loop trying to resolve this reference in this case.

I suspect the problem may be that you are using IDs that are not proper URIs (although generally they are supported).

As a temporary workaround I suggest moving the schema for layout property to a separate file and referring to it as #:

testrec.json:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://yourdomain/testrec.json#",
  "type": "object",
  "properties": {
    "layout": { "$ref": "layout.json#" }
  }
}

layout.json:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://yourdomain/layout.json#",
  "type": "object",
  "properties": {
    "layout": { "type": "string" },
    "panels": {
      "type": "array",
      "items": {
        "oneOf": [
          { "type": "string" },
          { "$ref": "#" }
        ]
      }
    }
  },
  "required": [
    "layout",
    "panels"
  ]
}

code:

ajv.addSchema(require('layout.json'));
var validate = ajv.compile(require('testrec.json'));
var valid = validate(data);

This should work (there are many samples like that in tests).

Please let me know if it does/doesn't. Also please make sure that you are using the latest version.

In any case I'll look at the issue. Thanks for reporting!

blakeembrey commented 9 years ago

FWIW, I just run into infinite loop crash with an internal reference in my own JSON schema test.

epoberezkin commented 9 years ago

Yes, needs fixing. Will do it.

epoberezkin commented 9 years ago

closed with a0c342c58f7a15ba1b9723d58c00145235b45bcf

blakeembrey commented 9 years ago

@epoberezkin Nice :+1: It's still crashing for me though. If it helps, I'm using https://raw.githubusercontent.com/mulesoft-labs/raml-object-standard/master/schema.json and the validate function (https://github.com/mulesoft-labs/raml-object-standard/blob/master/test/support/validate.js) modified to use ajv.

epoberezkin commented 9 years ago

@blakeembrey great, thanks :) do you maybe have some valid/invalid samples?

epoberezkin commented 9 years ago

@blakeembrey RAML schema now compiles - it actually helped improving how #13 was solved.

I had to change some regular expressions in RAML schema (see lines 503 and 534 in b3fb2e58c7843e780a7b9c3e5fdbd079537371f2): I think it is wrong to escape "/" in this regex variation (you don't escape "/" in lines 142 and 389; escaping it also breaks ajv). Maybe it is wrong and something needs to be changed in how I escape regex strings (escapeRegExp function). I also removed unnecessary escaping in lines 142 and 389 - only "-" needs to be escaped inside [].

Thanks a lot for help. I would appreciate if you let me know if it actually validates correctly :).

blakeembrey commented 9 years ago

Awesome, I'll give it a go. The slashes worked fine with other schema validators, so I wasn't sure about that - don't suppose you have a reference in the spec I can read?

epoberezkin commented 9 years ago

json-schema spec advises to use a subset of ecma262 regular expressions: http://json-schema.org/latest/json-schema-validation.html#anchor6 . That probably means [a-zA-Z0-9_] instead of \w and [0-9] instead of \d, although I am not sure about that. They will work in JavaScript of course.

It says nothing specifically about how escaping should work, but it's not a universal rule that '/' has to be escaped in regular expressions. Even RegExp constructor doesn't require escaping '/'. Although it produces the same results for '/' and '\/'. So I guess I can make ajv support the latter as well :).