From 446a4d09413fa0b7ec8244c070a5adbb5d8daf22 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 13 Aug 2024 17:14:45 -0400 Subject: [PATCH] Improve error message when compiling a `$ref` inside an unknown keyword (#148) Signed-off-by: Juan Cruz Viotti --- DEPENDENCIES | 2 +- test/CMakeLists.txt | 1 + test/compile/fail_ref_from_unknown_keyword.sh | 35 +++++++++++++++++++ .../src/jsonschema/default_compiler_draft4.h | 8 ++++- 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100755 test/compile/fail_ref_from_unknown_keyword.sh diff --git a/DEPENDENCIES b/DEPENDENCIES index 967ea8de..3639ee0b 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,4 +1,4 @@ vendorpull https://github.com/sourcemeta/vendorpull dea311b5bfb53b6926a4140267959ae334d3ecf4 noa https://github.com/sourcemeta/noa 7e26abce7a4e31e86a16ef2851702a56773ca527 -jsontoolkit https://github.com/sourcemeta/jsontoolkit 2b44aee9b2be18a03b375c0b1f15c7623db8b922 +jsontoolkit https://github.com/sourcemeta/jsontoolkit e7a8f35b0b85cd87b5fa587b2ae767ed939a0b4d hydra https://github.com/sourcemeta/hydra 3c53d3fdef79e9ba603d48470a508cc45472a0dc diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af021265..a6402635 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -140,6 +140,7 @@ add_jsonschema_test_unix(compile/pass_2) add_jsonschema_test_unix(compile/fail_no_schema) add_jsonschema_test_unix(compile/fail_schema_invalid_json) add_jsonschema_test_unix(compile/fail_unknown_metaschema) +add_jsonschema_test_unix(compile/fail_ref_from_unknown_keyword) # Identify add_jsonschema_test_unix(identify/fail_resolve_from_no_match) diff --git a/test/compile/fail_ref_from_unknown_keyword.sh b/test/compile/fail_ref_from_unknown_keyword.sh new file mode 100755 index 00000000..9442b1bd --- /dev/null +++ b/test/compile/fail_ref_from_unknown_keyword.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +TMP="$(mktemp -d)" +clean() { rm -rf "$TMP"; } +trap clean EXIT + +cat << 'EOF' > "$TMP/schema.json" +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "foo": { "$ref": "#/$defs/bar" }, + "baz": { "type": "string" } + }, + "$defs": { + "bar": { + "$ref": "#/properties/baz" + } + } +} +EOF + +"$1" compile "$TMP/schema.json" 2>"$TMP/stderr.txt" \ + && CODE="$?" || CODE="$?" +test "$CODE" = "1" || exit 1 + +cat << 'EOF' > "$TMP/expected.txt" +error: The schema location is inside of an unknown keyword + #/properties/baz + at schema location "/$defs/bar/$ref" +EOF + +diff "$TMP/stderr.txt" "$TMP/expected.txt" diff --git a/vendor/jsontoolkit/src/jsonschema/default_compiler_draft4.h b/vendor/jsontoolkit/src/jsonschema/default_compiler_draft4.h index f804ac4d..fb251e62 100644 --- a/vendor/jsontoolkit/src/jsonschema/default_compiler_draft4.h +++ b/vendor/jsontoolkit/src/jsonschema/default_compiler_draft4.h @@ -23,7 +23,13 @@ auto compiler_draft4_core_ref(const SchemaCompilerContext &context, const auto current{keyword_location(schema_context)}; assert(context.frame.contains({type, current})); const auto &entry{context.frame.at({type, current})}; - assert(context.references.contains({type, entry.pointer})); + if (!context.references.contains({type, entry.pointer})) { + assert(schema_context.schema.at(dynamic_context.keyword).is_string()); + throw SchemaReferenceError( + schema_context.schema.at(dynamic_context.keyword).to_string(), + entry.pointer, "The schema location is inside of an unknown keyword"); + } + const auto &reference{context.references.at({type, entry.pointer})}; const auto label{std::hash{}(reference.destination)};