Skip to content

Commit ec8288c

Browse files
committed
FIX ATTEMPT
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent e8ad3ee commit ec8288c

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

src/core/jsonschema/frame.cc

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
471471
base_uris;
472472
std::unordered_map<sourcemeta::core::Pointer, std::vector<JSON::String>>
473473
base_dialects;
474+
std::unordered_map<sourcemeta::core::Pointer, JSON::String>
475+
pointer_base_dialects;
474476

475477
for (const auto &path : paths) {
476478
// Passing paths that overlap is undefined behavior. No path should
@@ -545,6 +547,7 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
545547

546548
// Base dialect
547549
assert(entry.base_dialect.has_value());
550+
pointer_base_dialects.insert({entry.pointer, entry.base_dialect.value()});
548551

549552
// Schema identifier
550553
std::optional<JSON::String> id{sourcemeta::core::identify(
@@ -826,10 +829,22 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
826829
const auto maybe_base_entry{this->locations_.find(
827830
{SchemaReferenceType::Static, current_base})};
828831

829-
const auto current_base_dialect{
830-
maybe_base_entry == this->locations_.cend()
831-
? root_base_dialect.value()
832-
: maybe_base_entry->second.base_dialect};
832+
// Find the base_dialect by walking up the pointer hierarchy
833+
std::optional<JSON::String> current_base_dialect;
834+
for (auto current_ptr = pointer; !current_base_dialect.has_value();) {
835+
auto base_dialect_iter = pointer_base_dialects.find(current_ptr);
836+
if (base_dialect_iter != pointer_base_dialects.end()) {
837+
current_base_dialect = base_dialect_iter->second;
838+
} else if (current_ptr.empty()) {
839+
current_base_dialect =
840+
maybe_base_entry == this->locations_.cend()
841+
? root_base_dialect.value()
842+
: maybe_base_entry->second.base_dialect;
843+
break;
844+
} else {
845+
current_ptr = current_ptr.initial();
846+
}
847+
}
833848

834849
const auto subschema{subschemas.find(pointer)};
835850

@@ -842,7 +857,7 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
842857
SchemaFrame::LocationType::Subschema, std::move(result),
843858
root_id, current_base, pointer,
844859
pointer.resolve_from(nearest_bases.second),
845-
dialects.first.front(), current_base_dialect,
860+
dialects.first.front(), current_base_dialect.value(),
846861
{subschema->second.instance_location},
847862
subschema->second.parent, false, true);
848863
} else {
@@ -851,7 +866,7 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
851866
SchemaFrame::LocationType::Subschema, std::move(result),
852867
root_id, current_base, pointer,
853868
pointer.resolve_from(nearest_bases.second),
854-
dialects.first.front(), current_base_dialect, {},
869+
dialects.first.front(), current_base_dialect.value(), {},
855870
subschema->second.parent, false, true);
856871
}
857872
} else {
@@ -860,7 +875,7 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
860875
SchemaFrame::LocationType::Pointer, std::move(result),
861876
root_id, current_base, pointer,
862877
pointer.resolve_from(nearest_bases.second),
863-
dialects.first.front(), current_base_dialect, {},
878+
dialects.first.front(), current_base_dialect.value(), {},
864879
dialects.second, false, true);
865880
}
866881
}

src/core/jsonschema/walker.cc

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,26 @@ auto walk(const std::optional<sourcemeta::core::Pointer> &parent,
5757
sourcemeta::core::SchemaIdentificationStrategy::Strict,
5858
maybe_current_dialect)};
5959
const auto is_schema_resource{level == 0 || id.has_value()};
60-
const auto current_dialect{is_schema_resource ? maybe_current_dialect.value()
61-
: dialect};
62-
const auto current_base_dialect{
63-
is_schema_resource
64-
? sourcemeta::core::base_dialect(subschema, resolver, current_dialect)
65-
.value_or(base_dialect)
66-
: base_dialect};
60+
61+
const auto has_schema_keyword{subschema.is_object() &&
62+
subschema.defines("$schema")};
63+
const auto subschema_base_dialect{
64+
has_schema_keyword ? sourcemeta::core::base_dialect(subschema, resolver,
65+
maybe_current_dialect)
66+
.value_or(base_dialect)
67+
: base_dialect};
68+
const auto should_process_schema_without_id{
69+
has_schema_keyword && !is_schema_resource &&
70+
ref_overrides_adjacent_keywords(subschema_base_dialect)};
71+
72+
const auto current_dialect{is_schema_resource ||
73+
should_process_schema_without_id
74+
? maybe_current_dialect.value()
75+
: dialect};
76+
const auto current_base_dialect{is_schema_resource ||
77+
should_process_schema_without_id
78+
? subschema_base_dialect
79+
: base_dialect};
6780

6881
const auto vocabularies{sourcemeta::core::vocabularies(
6982
resolver, current_base_dialect, current_dialect)};

0 commit comments

Comments
 (0)