JamesNK / Newtonsoft.Json.Schema

Json.NET Schema is a powerful, complete and easy to use JSON Schema framework for .NET

Home Page:http://www.newtonsoft.com/jsonschema

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Invalid Schema $ref Output

owenneil opened this issue · comments

I've run into a case where a loaded schema is being output with invalid $ref elements that point to themselves through a layer of indirection of another $ref when output with the JSchemaWriterReferenceHandling.Always setting.

Broken.json

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "$type": "schema",
    "definitions": {
        "linkItemArray": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/linkItem"
            }
        },
        "navLinkItem": {
            "type": "object",
            "properties": {
                "image": {
                    "anyOf": [
                        {
                            "$ref": "External#/definitions/reference"
                        }
                    ]
                }
            }
        },
        "navLinkItemArray": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/navLinkItem"
            }
        },
        "linkItem": {
            "type": "object",
            "properties": {
                "image": {
                    "anyOf": [
                        {
                            "$ref": "External#/definitions/reference"
                        }
                    ]
                }
            }
        }
    },
    "id": "Broken",
    "type": "object",
    "properties": {
        "linkItemArrayProp": {
            "$ref": "#/definitions/linkItemArray"
        },
        "navLinkItemArrayProp": {
            "$ref": "#/definitions/navLinkItemArray"
        }
    }
}

With External Reference External.json:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "$type": "schema",
  "id": "External",
  "type": "object",
  "definitions": {
    "reference": {
      "type": "object"
    }
  }
}

Given this, the output with JSchemaWriterReferenceHandling.Always is:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "Broken",
  "$type": "schema",
  "definitions": {
    "linkItemArray": {
      "type": "array",
      "items": {
        "$ref": "Broken#/definitions/linkItem"
      }
    },
    "navLinkItem": {
      "type": "object",
      "properties": {
        "image": {
          "anyOf": [
            {
              "type": "object"
            }
          ]
        }
      }
    },
    "navLinkItemArray": {
      "type": "array",
      "items": {
        "$ref": "Broken#/definitions/navLinkItem"
      }
    },
    "linkItem": {
      "type": "object",
      "properties": {
        "image": {
          "anyOf": [
            {
              "$ref": "Broken#/definitions/linkItemArray/items/properties/image/anyOf/0" <-- This is actually linking to itself. 
            }
          ]
        }
      }
    }
  },
  "type": "object",
  "properties": {
    "linkItemArrayProp": {
      "$ref": "Broken#/definitions/linkItemArray"
    },
    "navLinkItemArrayProp": {
      "$ref": "Broken#/definitions/navLinkItemArray"
    }
  }
}

I've simplified the case down the minimum I've been able to reproduce, but we have a lot of schemas and this is hitting on many of them after updating from a fairly old combination of Newtonsoft.Json (3.0.2) and Newtonsoft.Json.Schema (10.0.3) to the current released versions.

commented

We have the same issue. In our case we want a schema without any $refs because we don't use recursion. We use JSchemaWriterSettings.Never but still get a reference that points to the element it's in. This seems to be the same problem as above.
The bug occurs in version 3.0.14 and 3.0.15 but not in 3.0.13. So as a workaround we will stay on that old version for now.