diff --git a/src/json-schema-errors.js b/src/json-schema-errors.js index a385849..f84a123 100644 --- a/src/json-schema-errors.js +++ b/src/json-schema-errors.js @@ -126,6 +126,8 @@ async function toAbsoluteKeywordLocation(schema, keywordLocation) { /** @type API.evaluateSchema */ export const evaluateSchema = (schemaLocation, instance, context) => { const instanceLocation = Instance.uri(instance); + // The error index stores property name locations ("#*/foo") without the "*" + const indexedInstanceLocation = instanceLocation.replace(/^#\*/, "#"); let valid = true; /** @type API.NormalizedOutput */ @@ -137,7 +139,7 @@ export const evaluateSchema = (schemaLocation, instance, context) => { const schemaNode = context.ast[schemaLocation]; if (typeof schemaNode === "boolean") { - const isSchemaValid = getReportedValidity(schemaLocation, instanceLocation, context); + const isSchemaValid = getReportedValidity(schemaLocation, indexedInstanceLocation, context); if (schemaNode === false && isSchemaValid !== true) { valid = false; output[instanceLocation] = { @@ -159,8 +161,7 @@ export const evaluateSchema = (schemaLocation, instance, context) => { const validationKeyword = getKeyword(keywordUri); - const keywordInstanceLocation = instanceLocation.replace(/^#\*/, "#"); - let isKeywordValid = getReportedValidity(keywordLocation, keywordInstanceLocation, context); + let isKeywordValid = getReportedValidity(keywordLocation, indexedInstanceLocation, context); /** @type API.EvaluationContext */ const keywordContext = { @@ -178,7 +179,7 @@ export const evaluateSchema = (schemaLocation, instance, context) => { const keywordOutput = keyword.evaluate?.(keywordValue, instance, keywordContext); - const isReported = context.errorIndex[keywordLocation]?.[keywordInstanceLocation] !== undefined; + const isReported = context.errorIndex[keywordLocation]?.[indexedInstanceLocation] !== undefined; if (validationKeyword.simpleApplicator && !isReported && keywordOutput?.some((suboutput) => getValidity(suboutput) === false)) { isKeywordValid = false; } diff --git a/src/test-suite/tests/propertyNames.json b/src/test-suite/tests/propertyNames.json index 609e42e..169b831 100644 --- a/src/test-suite/tests/propertyNames.json +++ b/src/test-suite/tests/propertyNames.json @@ -48,6 +48,93 @@ "instance": 42, "errors": [] }, + { + "description": "propertyNames false", + "compatibility": "6", + "schema": { + "propertyNames": false + }, + "instance": { "foo": 42 }, + "errors": [ + { + "messageId": "boolean-schema-message", + "instanceLocation": "#*/foo", + "schemaLocations": ["#/propertyNames"] + } + ] + }, + { + "description": "propertyNames with a false schema in allOf", + "compatibility": "6", + "schema": { + "propertyNames": { "allOf": [false] } + }, + "instance": { "foo": 42 }, + "errors": [ + { + "messageId": "boolean-schema-message", + "instanceLocation": "#*/foo", + "schemaLocations": ["#/propertyNames/allOf/0"] + } + ] + }, + { + "description": "propertyNames with a $ref to a false schema", + "compatibility": "6", + "schema": { + "propertyNames": { "$ref": "#/$defs/never" }, + "$defs": { + "never": false + } + }, + "instance": { "foo": 42 }, + "errors": [ + { + "messageId": "boolean-schema-message", + "instanceLocation": "#*/foo", + "schemaLocations": ["#/$defs/never"] + } + ] + }, + { + "description": "propertyNames false in anyOf", + "compatibility": "6", + "schema": { + "anyOf": [ + { "propertyNames": false }, + { "type": "string" } + ] + }, + "instance": { "foo": 42 }, + "errors": [ + { + "messageId": "anyOf-message", + "alternatives": [ + [ + { + "messageId": "boolean-schema-message", + "instanceLocation": "#*/foo", + "schemaLocations": ["#/anyOf/0/propertyNames"] + } + ], + [ + { + "messageId": "type-message", + "messageParams": { + "count": 1, + "type": "string", + "expectedTypes": { "or": ["string"] } + }, + "instanceLocation": "#", + "schemaLocations": ["#/anyOf/1/type"] + } + ] + ], + "instanceLocation": "#", + "schemaLocations": ["#/anyOf"] + } + ] + }, { "description": "propertyNames pass", "schema": {