diff --git a/src/core/jsonschema/format.cc b/src/core/jsonschema/format.cc index 266abeadf..1940c54ec 100644 --- a/src/core/jsonschema/format.cc +++ b/src/core/jsonschema/format.cc @@ -140,7 +140,7 @@ auto format(JSON &schema, const SchemaWalker &walker, const SchemaResolver &resolver, std::string_view default_dialect) -> void { assert(is_schema(schema)); - std::vector objects_to_reorder; + std::vector subschemas; { SchemaFrame frame{SchemaFrame::Mode::Locations}; @@ -152,16 +152,15 @@ auto format(JSON &schema, const SchemaWalker &walker, continue; } - auto &subschema{get(schema, entry.second.pointer)}; - if (subschema.is_object()) { - objects_to_reorder.push_back(&subschema); - } + subschemas.push_back(to_pointer(entry.second.pointer)); } } - // Now apply the reordering after the frame is destroyed - for (auto *object : objects_to_reorder) { - object->reorder(keyword_compare); + for (const auto &pointer : subschemas) { + auto &subschema{get(schema, pointer)}; + if (subschema.is_object()) { + subschema.reorder(keyword_compare); + } } } diff --git a/test/jsonschema/jsonschema_format_test.cc b/test/jsonschema/jsonschema_format_test.cc index ee319eca2..de5cbd1ef 100644 --- a/test/jsonschema/jsonschema_format_test.cc +++ b/test/jsonschema/jsonschema_format_test.cc @@ -452,3 +452,20 @@ TEST(JSONSchema_format, boolean_subschema_does_not_crash) { "additionalProperties": true })JSON"); } + +TEST(JSONSchema_format, reorder_does_not_invalidate_child_pointers) { + sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({ + "not": {}, + "$schema": "https://json-schema.org/draft/2020-12/schema" + })JSON"); + + sourcemeta::core::format(document, sourcemeta::core::schema_walker, + sourcemeta::core::schema_resolver); + + std::ostringstream stream; + sourcemeta::core::prettify(document, stream); + EXPECT_EQ(stream.str(), R"JSON({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "not": {} +})JSON"); +}