Skip to content

1.0.60 Expects type To Be Array #461

@tomdeering-wf

Description

@tomdeering-wf

When dependabot brought us from using json-schema-validator 1.0.59 to 1.0.60 in an internal project, many tests started failing. The root cause seems to be that json-schema-validator 1.0.60 expects that "type" should be an array rather than a simple string, even though a simple string is allowed by the spec.

Here is a test case that reproduces the issue:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "address": {
      "type": "object",
      "properties": {
        "street": {
          "type": "string"
        },
        "city": {
          "type": "string"
        }
      },
      "required": [
        "street",
        "city"
      ]
    }
  },
  "required": [
    "firstName",
    "lastName",
    "address"
  ]
}

Validated using:

final var config = new SchemaValidatorsConfig();
config.addKeywordWalkListener(ValidatorTypeCode.PROPERTIES.getValue(), new JsonSchemaWalkListener() {
      private final List<ParseResult.Property> path = Lists.newArrayList();

      @Override
      public WalkFlow onWalkStart(final WalkEvent walkEvent) {
        // This method is more confusing than it should be on first blush. The reason for this is
        // that technically properties can have the literal name "properties" and can also contain
        // periods which means we need complex logic as we can use simple string splitting or
        // jsonpath. We have to track the state of our recursive descent to strip out known prefixes
        // from our current path.

        // The first event is always the outer object properties.
        if (walkEvent.getAt().equalsIgnoreCase("$")) {
          path.add(new ParseResult.Property("properties", "$.properties"));
          return WalkFlow.CONTINUE;
        }

        final var previous = path.get(path.size() - 1);
        final var path = walkEvent.getAt();

        var name = StringUtils.removeStart(path, previous.getPath() + ".");
        final var property = new ParseResult.Property(name, walkEvent.getAt());

        properties.add(property);

        final var nextProperty = new ParseResult.Property(name, walkEvent.getAt() + ".properties");
        this.path.add(nextProperty);

        return WalkFlow.CONTINUE;
      }

      @Override
      public void onWalkEnd(final WalkEvent walkEvent,
                            final Set<ValidationMessage> validationMessages) {

        this.path.remove(path.size() - 1);
      }
    });
final var jsFactory = JsonSchemaFactory.getInstance(V7);
final var schema = jsFactory.getSchema(stream /*Of draft 7 schema definition*/, config);
final var result = schema.walk(value, true);

Expected: No validation errors
Actual (1.0.59): No validation errors
Actual (1.0.60): [$.type: string found, array expected, $.properties.firstName.type: string found, array expected, $.properties.lastName.type: string found, array expected, $.properties.address.type: string found, array expected, $.properties.address.properties.street.type: string found, array expected, $.properties.address.properties.city.type: string found, array expected]

The only change that could have broken us seems to be #452, but I'm not sure how

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions