diff --git a/src/jsonschema/compile_evaluate.cc b/src/jsonschema/compile_evaluate.cc index 5b9ed06a2..d2c2c0794 100644 --- a/src/jsonschema/compile_evaluate.cc +++ b/src/jsonschema/compile_evaluate.cc @@ -1192,9 +1192,11 @@ auto evaluate_step( context.push(loop); EVALUATE_CONDITION_GUARD("SchemaCompilerLoopItemsFromAnnotationIndex", loop, instance); + const auto &target{context.resolve_target(loop.target, instance)}; + EVALUATE_IMPLICIT_PRECONDITION("SchemaCompilerLoopItemsFromAnnotationIndex", + loop, target.is_array()); CALLBACK_PRE(loop, context.instance_location()); const auto &value{context.resolve_value(loop.value, instance)}; - const auto &target{context.resolve_target(loop.target, instance)}; assert(target.is_array()); const auto &array{target.as_array()}; result = true; diff --git a/src/jsonschema/default_compiler_2019_09.h b/src/jsonschema/default_compiler_2019_09.h index 1a188e107..6119a8ce3 100644 --- a/src/jsonschema/default_compiler_2019_09.h +++ b/src/jsonschema/default_compiler_2019_09.h @@ -247,34 +247,35 @@ auto compiler_2019_09_applicator_unevaluateditems( children = std::move(loop_children); } - SchemaCompilerTemplate loop; if (schema_context.vocabularies.contains( "https://json-schema.org/draft/2019-09/vocab/applicator") && dependencies.contains("items")) { - loop.push_back(make( - true, context, schema_context, relative_dynamic_context, + SchemaCompilerTemplate condition{make( + false, context, schema_context, relative_dynamic_context, JSON{true}, + {}, SchemaCompilerTargetType::Annotations, std::move(dependencies))}; + return {make( + true, context, schema_context, dynamic_context, SchemaCompilerValueString{"items"}, std::move(children), - SchemaCompilerTemplate{})); + std::move(condition))}; } else if (schema_context.vocabularies.contains( "https://json-schema.org/draft/2020-12/vocab/applicator") && dependencies.contains("prefixItems")) { - loop.push_back(make( - true, context, schema_context, relative_dynamic_context, + SchemaCompilerTemplate condition{make( + false, context, schema_context, relative_dynamic_context, JSON{true}, + {}, SchemaCompilerTargetType::Annotations, std::move(dependencies))}; + return {make( + true, context, schema_context, dynamic_context, SchemaCompilerValueString{"prefixItems"}, std::move(children), - SchemaCompilerTemplate{})); + std::move(condition))}; } else { - loop.push_back(make( - true, context, schema_context, relative_dynamic_context, + SchemaCompilerTemplate condition{make( + false, context, schema_context, relative_dynamic_context, JSON{true}, + {}, SchemaCompilerTargetType::Annotations, std::move(dependencies))}; + return {make( + true, context, schema_context, dynamic_context, SchemaCompilerValueUnsignedInteger{0}, std::move(children), - SchemaCompilerTemplate{})); + std::move(condition))}; } - - SchemaCompilerTemplate condition{make( - false, context, schema_context, relative_dynamic_context, JSON{true}, {}, - SchemaCompilerTargetType::Annotations, std::move(dependencies))}; - return {make( - false, context, schema_context, dynamic_context, JSON::Type::Array, - std::move(loop), std::move(condition))}; } auto compiler_2019_09_applicator_unevaluatedproperties( @@ -298,13 +299,6 @@ auto compiler_2019_09_applicator_unevaluatedproperties( dependencies.emplace("additionalProperties"); } - SchemaCompilerTemplate condition{make( - false, context, schema_context, relative_dynamic_context, - SchemaCompilerTarget{SchemaCompilerTargetType::InstanceBasename, - empty_pointer}, - {}, SchemaCompilerTargetType::ParentAnnotations, - std::move(dependencies))}; - SchemaCompilerTemplate children{compile(context, schema_context, relative_dynamic_context, empty_pointer, empty_pointer)}; @@ -312,6 +306,12 @@ auto compiler_2019_09_applicator_unevaluatedproperties( true, context, schema_context, relative_dynamic_context, SchemaCompilerValueNone{}, {}, SchemaCompilerTargetType::Instance)); + SchemaCompilerTemplate condition{make( + false, context, schema_context, relative_dynamic_context, + SchemaCompilerTarget{SchemaCompilerTargetType::InstanceBasename, + empty_pointer}, + {}, SchemaCompilerTargetType::ParentAnnotations, + std::move(dependencies))}; SchemaCompilerTemplate wrapper{make( false, context, schema_context, relative_dynamic_context, SchemaCompilerValueNone{}, std::move(children), std::move(condition))};