Skip to content

Validation fails to fail on missing required inner field #2360

@musteresel

Description

@musteresel

Initially reported here: xpol/lua-rapidjson#63

This happens in an Alpine Docker container:

$ apk list rapidjson
rapidjson-1.1.0-r8 x86_64 {rapidjson} (MIT) [installed]
$ apk list rapidjson-dev
rapidjson-dev-1.1.0-r8 x86_64 {rapidjson} (MIT) [installed]
$ apk list g++
g++-14.2.0-r6 x86_64 {gcc} (GPL-2.0-or-later AND LGPL-2.1-or-later) [installed]
$ g++ rj-test.cc -o rj-test && ./rj-test # Code to reproduce, see below
Accepted!

I have an "outer" array, which has "inner" objects, which need to have a "num" field.

JSON Schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Demo",
  "type": "object",
  "properties": {
    "outer": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/inner"
      }
    }
  },
  "required": ["outer"],
  "additionalProperties": false,
  "$defs": {
    "inner": {
      "type": "object",
      "properties": {
        "num": {
          "type": "number"
        }
      },
      "required": ["num"],
      "additionalProperties": false
    }
  }
}

JSON:

{
  "outer": [
    {
    }
  ]
}

Expected: Failing validation because "num" is missing, this happens for example with this online validator: https://www.jsonschemavalidator.net/
Outcome: Validation succeeds.

Code to reproduce:

#include "rapidjson/schema.h"
#include "rapidjson/stringbuffer.h"
#include <cstdio>

char const *schemaJson = R"({
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Demo",
  "type": "object",
  "properties": {
    "outer": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/inner"
      }
    }
  },
  "required": ["outer"],
  "additionalProperties": false,
  "$defs": {
    "inner": {
      "type": "object",
      "properties": {
        "num": {
          "type": "number"
        }
      },
      "required": ["num"],
      "additionalProperties": false
    }
  }
})";

char const *inputJson = R"(
{
  "outer": [
    {
    }
  ]
}
)";

int main()
{
    rapidjson::Document sd;
    if (sd.Parse(schemaJson).HasParseError())
    {
        size_t const offset = sd.GetErrorOffset();
        printf("Failed parsing schema: %d %zu %s\n", sd.GetParseError(), offset, schemaJson + offset);
        return 1;
    }
    rapidjson::SchemaDocument schema(sd);

    rapidjson::Document d;
    if (d.Parse(inputJson).HasParseError())
    {
        size_t const offset = d.GetErrorOffset();
        printf("Failed parsing json: %d %zu %s\n", d.GetParseError(), offset, inputJson + offset);
        return 1;
    }

    rapidjson::SchemaValidator validator(schema);
    if (!d.Accept(validator))
    {
        rapidjson::StringBuffer sb;
        validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
        printf("Invalid schema: %s\n", sb.GetString());
        printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
        sb.Clear();
        validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
        printf("Invalid document: %s\n", sb.GetString());
    }
    else
    {
        printf("Accepted!\n");
    }
}

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