Skip to content

Commit

Permalink
draft2019-09 anchor
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Dec 25, 2023
1 parent 6ad97e9 commit 1c59376
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ namespace jsonschema {
}
}

std::cout << "\ncontext\n";
/*std::cout << "\ncontext\n";
for (const auto& uri : new_uris)
{
std::cout << " " << uri.string() << "\n";
}
}*/

return compilation_context(new_uris);
}
Expand Down
59 changes: 49 additions & 10 deletions include/jsoncons_ext/jsonschema/draft201909/schema_parser_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace draft201909 {
schema_location relative(it->value().template as<std::string>());
is_ref = true;
auto id = relative.resolve(new_context.get_base_uri());
std::cout << "$ref " << relative.string() << ", " << id.string() << "\n";
//std::cout << "$ref " << relative.string() << ", " << id.string() << "\n";
auto ref = get_or_create_reference(id);
validator = ref.get();
subschemas_.emplace_back(std::move(ref));
Expand Down Expand Up @@ -155,16 +155,19 @@ namespace draft201909 {
it = schema.find("$anchor"); // If $anchor is found, this schema can be referenced by the id
if (it != schema.object_range().end())
{
std::string id = it->value().template as<std::string>();
schema_location relative("#"+id);
std::string anchor = it->value().template as<std::string>();
if (!validate_anchor(anchor))
{
std::string message("Invalid anchor ");
message.append(anchor.data(), anchor.size());
JSONCONS_THROW(schema_error(message));
}
schema_location relative("#"+anchor);
insert_schema(relative, validator);
for (const auto& uri : new_context.uris())
if (new_context.get_base_uri().is_absolute())
{
if (uri.is_absolute())
{
schema_location new_uri = relative.resolve(uri);
insert_schema(new_uri, validator);
}
schema_location new_uri = relative.resolve(new_context.get_base_uri());
insert_schema(new_uri, validator);
}
}
}
Expand Down Expand Up @@ -916,12 +919,21 @@ namespace draft201909 {
const compilation_context& context)
{
std::string schema_path = context.make_schema_path_with("allOf");
auto new_context2 = context.update_uris(schema, schema_path);
std::vector<validator_type> subschemas;

size_t c = 0;
for (const auto& subsch : schema.array_range())
{
subschemas.emplace_back(make_subschema_validator(subsch, context, {all_of_criterion<Json>::key(), std::to_string(c++)}));
auto new_context = context.update_uris(subsch, std::vector<std::string>{});

/*std::cout << "\nThe context\n";
for (const auto& uri : new_context.uris())
{
std::cout << " " << uri.string() << "\n";
}*/

subschemas.emplace_back(make_subschema_validator(subsch, new_context, {all_of_criterion<Json>::key(), std::to_string(c++)}));
}
return jsoncons::make_unique<combining_validator<Json,all_of_criterion<Json>>>(std::move(schema_path), std::move(subschemas));
}
Expand Down Expand Up @@ -1245,6 +1257,33 @@ namespace draft201909 {
}
}

static bool validate_anchor(const std::string& anchor)
{
bool is_valid = !anchor.empty();
for (std::size_t i = 0; is_valid && i < anchor.size(); ++i)
{
switch (anchor[i])
{
case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':
case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z':
case '_':
break;
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
case '-':
case '.':
if (i == 0)
{
is_valid = false;
}
break;
default:
is_valid = false;
break;
}
}
return is_valid;
}

};

} // namespace draft201909
Expand Down
39 changes: 14 additions & 25 deletions test/jsonschema/issues/draft2019-09/issue1.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
[
[
{
"description": "same $anchor with different base uri",
"description": "invalid anchors",
"comment": "Section 8.2.3",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:1234/draft2019-09/foobar",
"$defs": {
"A": {
"$id": "child1",
"allOf": [
{
"$id": "child2",
"$anchor": "my_anchor",
"type": "number"
},
{
"$anchor": "my_anchor",
"type": "string"
}
]
}
},
"$ref": "child1#my_anchor"
"$ref": "https://json-schema.org/draft/2019-09/schema"
},
"tests": [
{
"description": "$ref resolves to /$defs/A/allOf/1",
"data": "a",
"valid": true
"description": "MUST start with a letter (and not #)",
"data": { "$anchor" : "#foo" },
"valid": false
}/*,
{
"description": "$ref does not resolve to /$defs/A/allOf/0",
"data": 1,
"description": "JSON pointers are not valid",
"data": { "$anchor" : "/a/b" },
"valid": false
},
{
"description": "invalid with valid beginning",
"data": { "$anchor" : "foo#something" },
"valid": false
}*/
]
Expand Down
94 changes: 92 additions & 2 deletions test/jsonschema/issues/draft2019-09/issue1.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,95 @@
Could not open ./jsonschema/JSON-Schema-Test-Suite/remotes/child1 for schema loading

Test case: "$ref resolves to /$defs/A/allOf/1"
Failed: #: Expected number, found string
"$id": "http://localhost:1234/draft2019-09/foobar"

"$id": "child1"

context
#
http://localhost:1234/draft2019-09/foobar
$ref child1#my_anchor, http://localhost:1234/draft2019-09/child1#my_anchor

context
http://localhost:1234/draft2019-09/foobar#/$defs/A
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1array
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1array
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1string
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1string
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1string
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1string
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1integer
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1#/http:~1~1localhost:1234~1draft2019-09~1child1#~1number
http://localhost:1234/draft2019-09/child1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/0
http://localhost:1234/draft2019-09/child1#/allOf/0
http://localhost:1234/draft2019-09/child2

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child1#/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2#/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child1#/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2#/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child1#/allOf/0/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2#/http:~1~1localhost:1234~1draft2019-09~1child2#~1number
http://localhost:1234/draft2019-09/child2

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/1
http://localhost:1234/draft2019-09/child1#/allOf/1

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/1/http:~1~1localhost:1234~1draft2019-09~1child1#~1allOf~11~1string
http://localhost:1234/draft2019-09/child1#/allOf/1/http:~1~1localhost:1234~1draft2019-09~1child1#~1allOf~11~1string

context
http://localhost:1234/draft2019-09/foobar#/$defs/A/allOf/1/http:~1~1localhost:1234~1draft2019-09~1child1#~1allOf~11~1string
http://localhost:1234/draft2019-09/child1#/allOf/1/http:~1~1localhost:1234~1draft2019-09~1child1#~1allOf~11~1string

16 changes: 7 additions & 9 deletions test/jsonschema/src/jsonschema_draft201909_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ namespace {
void jsonschema_tests(const std::string& fpath)
{
std::fstream is(fpath);
REQUIRE(is);
if (!is)
{
std::cout << "Cannot open file: " << fpath << "\n";
return;
}

json tests = json::parse(is);

Expand Down Expand Up @@ -92,8 +96,7 @@ TEST_CASE("jsonschema draft2019-09 tests")
SECTION("tests")
{
//jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/anchor.json");
#if 0
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalItems.json");
//jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalItems.json");
#ifdef JSONCONS_HAS_STD_REGEX
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalProperties.json");
#endif
Expand All @@ -103,9 +106,7 @@ TEST_CASE("jsonschema draft2019-09 tests")
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/const.json");
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/contains.json");
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/default.json");
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/definitions.json");

jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/dependencies.json");
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/defs.json");

jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/enum.json");
jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/exclusiveMaximum.json");
Expand Down Expand Up @@ -164,8 +165,5 @@ TEST_CASE("jsonschema draft2019-09 tests")
//jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uri.json");
//jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uri-reference.json");
//jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uri-template.json");

jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/content.json");
#endif
}
}

0 comments on commit 1c59376

Please sign in to comment.