Skip to content

Schema parsing with a resolver can result in a self referring $ref reference #370

@Fl0GUI

Description

@Fl0GUI

I encountered a situation where the following json is created:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://test.local/schema",
  "definitions": {
    "foo": {
      "properties": {
        "foobar": {
          "$ref": "#/definitions/bar"
        },
        "spam": {
          "const": "from other schema"
        }
      }
    },
    "bar": {
      "properties": {
        "goeswrong": {
          "$ref": "#/definitions/foo/properties/foobar/properties/goeswrong"
        }
      }
    }
  },
  "properties": {
    "prop": {
      "$ref": "#/definitions/foo"
    }
  }
}

Note that the goeswrong property has a reference which resolves to itself. I have not yet checked the json schema spec, but I doubt this is acceptable.

This output is created by this reproduction code:

using Newtonsoft.Json.Schema;

var otherSchema = """
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://test.local/other",
    "definitions": {
        "def": {
            "const": "from other schema"
        }
    }
}
""";

var resolver = new JSchemaPreloadedResolver();
resolver.Add(new("http://test.local/other"), otherSchema);

var readerSettings = new JSchemaReaderSettings
{
    Resolver = resolver
};

var schema = """
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://test.local/schema",
    "properties": {
        "prop": {"$ref":"#/definitions/foo"}
    },
    "definitions": {
      "foo": {
        "properties": {
          "foobar": {
            "$ref": "#/definitions/bar"
          },
          "spam": {
            "$ref": "other#/definitions/def"
          }
        },
      },
      "bar": {
        "properties": {
          "goeswrong": {
            "$ref": "other#/definitions/def",
          }
        }
      }
    }
}
""";

var result = JSchema.Parse(schema, readerSettings);
Console.WriteLine(result.ToString());

I've tried to reduce the example as simple as I could from a real life scenario. It's the best I could manage without internal knowledge of the Newtonsoft implementation.

I would expect that the resulting reference is #/definitions/foo/properties/spam or that it contains the definition from the other schema.

I am using Newtonsoft.Json.Schema v4.0.1 and net8.0.
I don't have the luxury to try other version, as this is what's used at the company. We're also not bothering to move to newer json schema specs, but I don't expect this to make a difference.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions