diff --git a/src/json-validator.cpp b/src/json-validator.cpp index 1a801bd..3ffd087 100644 --- a/src/json-validator.cpp +++ b/src/json-validator.cpp @@ -65,6 +65,8 @@ class schema_ref : public schema { const std::string id_; std::weak_ptr target_; + std::shared_ptr target_strong_; // for references to references keep also the shared_ptr because + // no one else might use it after resolving void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final { @@ -95,7 +97,13 @@ public: : schema(root), id_(id) {} const std::string &id() const { return id_; } - void set_target(const std::shared_ptr &target) { target_ = target; } + + void set_target(const std::shared_ptr &target, bool strong = false) + { + target_ = target; + if (strong) + target_strong_ = target; + } }; } // namespace @@ -1277,13 +1285,17 @@ std::shared_ptr schema::make(json &schema, schema.erase(attr); - // special case where break draft-7 and allow overriding of properties when a $ref is used + // special case where we break draft-7 and allow overriding of properties when a $ref is used attr = schema.find("default"); if (attr != schema.end()) { // copy the referenced schema depending on the underlying type and modify the default value - if (auto *ref_sch = dynamic_cast(sch.get())) { - sch = std::make_shared(*ref_sch); - sch->set_default_value(attr.value()); + if (dynamic_cast(sch.get())) { + // create a new reference schema use the original reference (which will be resolved later) + // to store this overloaed default value #209 + auto overloaded_ref_sch = std::make_shared(uris[0].to_string(), root); + overloaded_ref_sch->set_target(sch, true); + overloaded_ref_sch->set_default_value(attr.value()); + sch = overloaded_ref_sch; } else if (auto *type_sch = dynamic_cast(sch.get())) { sch = std::make_shared(*type_sch); sch->set_default_value(attr.value()); diff --git a/test/issue-209/CMakeLists.txt b/test/issue-209/CMakeLists.txt new file mode 100644 index 0000000..fa4c564 --- /dev/null +++ b/test/issue-209/CMakeLists.txt @@ -0,0 +1,3 @@ +add_test_simple_schema(Issue::209 + ${CMAKE_CURRENT_SOURCE_DIR}/entities.schema.json + ${CMAKE_CURRENT_SOURCE_DIR}/instance.json) diff --git a/test/issue-209/color.schema.json b/test/issue-209/color.schema.json new file mode 100644 index 0000000..2d4227b --- /dev/null +++ b/test/issue-209/color.schema.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.invalid/color.schema.json", + "title": "color", + "description": "X11/HTML/CSS color name as a JSON string", + "type": "string", + "enum": [ "White", "Black", "Red" ] +} diff --git a/test/issue-209/entities.schema.json b/test/issue-209/entities.schema.json new file mode 100644 index 0000000..95828b8 --- /dev/null +++ b/test/issue-209/entities.schema.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.invalid/entities.schema.json", + "title": "Entities", + "type": "array", + "items": { + "type": "object", + "required": [ "name" ], + "properties": { + "name": { + "type": "string" + }, + "fg": { "$ref": "color.schema.json", "default": "Black" } + } + } +} diff --git a/test/issue-209/instance.json b/test/issue-209/instance.json new file mode 100644 index 0000000..8de2c32 --- /dev/null +++ b/test/issue-209/instance.json @@ -0,0 +1,10 @@ +[ + { + "name": "player", + "fg": "White" + }, + { + "name": "enemy", + "fg": "Red" + } +]