From 509940ff390eeb58a17b9f5acb4fcfcccd97ebd2 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:41:45 +0800 Subject: [PATCH 1/2] Fix NPE when walking a missing node that will have missing properties --- .../com/networknt/schema/TypeFactory.java | 5 +++++ .../com/networknt/schema/JsonWalkTest.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/java/com/networknt/schema/TypeFactory.java b/src/main/java/com/networknt/schema/TypeFactory.java index b97d36a9a..cb986053d 100644 --- a/src/main/java/com/networknt/schema/TypeFactory.java +++ b/src/main/java/com/networknt/schema/TypeFactory.java @@ -75,6 +75,11 @@ public static JsonType getSchemaNodeType(JsonNode node) { * @return the json type */ public static JsonType getValueNodeType(JsonNode node, SchemaValidatorsConfig config) { + if (node == null) { + // This returns JsonType.UNKNOWN to be consistent with the behavior when + // JsonNodeType.MISSING + return JsonType.UNKNOWN; + } JsonNodeType type = node.getNodeType(); switch (type) { case OBJECT: diff --git a/src/test/java/com/networknt/schema/JsonWalkTest.java b/src/test/java/com/networknt/schema/JsonWalkTest.java index 99d73c6ae..33c17ff5d 100644 --- a/src/test/java/com/networknt/schema/JsonWalkTest.java +++ b/src/test/java/com/networknt/schema/JsonWalkTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.MissingNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.networknt.schema.walk.JsonSchemaWalkListener; import com.networknt.schema.walk.WalkEvent; @@ -110,6 +111,26 @@ void testWalkWithDifferentListeners() throws IOException { + "}"))); } + @Test + void testWalkMissingNodeWithPropertiesSchema() { + String schemaContents = "{\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"field\": {\n" + + " \"anyOf\": [\n" + + " {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " }"; + + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7); + JsonSchema schema = factory.getSchema(schemaContents); + schema.walk(MissingNode.getInstance(), true).getValidationMessages(); + } + private InputStream getSchema() { return getClass().getClassLoader().getResourceAsStream("schema/walk-schema.json"); } From 5ae2fff5dd556e19213e79fd90ee25112f9cb307 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Fri, 7 Feb 2025 20:45:22 +0800 Subject: [PATCH 2/2] Change to make expectation clearer --- src/test/java/com/networknt/schema/JsonWalkTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/networknt/schema/JsonWalkTest.java b/src/test/java/com/networknt/schema/JsonWalkTest.java index 33c17ff5d..af1c2ac07 100644 --- a/src/test/java/com/networknt/schema/JsonWalkTest.java +++ b/src/test/java/com/networknt/schema/JsonWalkTest.java @@ -17,6 +17,7 @@ import java.util.Set; import java.util.TreeSet; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; class JsonWalkTest { @@ -112,7 +113,7 @@ void testWalkWithDifferentListeners() throws IOException { } @Test - void testWalkMissingNodeWithPropertiesSchema() { + void testWalkMissingNodeWithPropertiesSchemaShouldNotThrow() { String schemaContents = "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" @@ -128,7 +129,8 @@ void testWalkMissingNodeWithPropertiesSchema() { JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7); JsonSchema schema = factory.getSchema(schemaContents); - schema.walk(MissingNode.getInstance(), true).getValidationMessages(); + JsonNode missingNode = MissingNode.getInstance(); + assertDoesNotThrow(() -> schema.walk(missingNode, true)); } private InputStream getSchema() {