diff --git a/src/main/java/com/networknt/schema/SchemaLocation.java b/src/main/java/com/networknt/schema/SchemaLocation.java index 1ded8240a..7fa564be0 100644 --- a/src/main/java/com/networknt/schema/SchemaLocation.java +++ b/src/main/java/com/networknt/schema/SchemaLocation.java @@ -15,6 +15,9 @@ */ package com.networknt.schema; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Objects; /** @@ -230,7 +233,21 @@ public static JsonNodePath of(String fragmentString) { if (index != -1) { fragment = fragment.append(index); } else { - fragment = fragment.append(fragmentPart.toString()); + String fragmentPartString = fragmentPart.toString(); + if (PathType.JSON_POINTER.equals(fragment.getPathType())) { + if (fragmentPartString.contains("~")) { + fragmentPartString = fragmentPartString.replace("~1", "/"); + fragmentPartString = fragmentPartString.replace("~0", "~"); + } + if (fragmentPartString.contains("%")) { + try { + fragmentPartString = URLDecoder.decode(fragmentPartString, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + // Do nothing + } + } + } + fragment = fragment.append(fragmentPartString); } } if (index == -1 && fragmentString.endsWith("/")) { diff --git a/src/main/java/com/networknt/schema/utils/JsonNodes.java b/src/main/java/com/networknt/schema/utils/JsonNodes.java index 565395959..5cbf7cc1c 100644 --- a/src/main/java/com/networknt/schema/utils/JsonNodes.java +++ b/src/main/java/com/networknt/schema/utils/JsonNodes.java @@ -15,10 +15,6 @@ */ package com.networknt.schema.utils; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; - import com.fasterxml.jackson.databind.JsonNode; import com.networknt.schema.JsonNodePath; @@ -61,21 +57,7 @@ public static T get(JsonNode node, Object propertyOrIndex) if (propertyOrIndex instanceof Number) { value = node.get(((Number) propertyOrIndex).intValue()); } else { - // In the case of string this represents an escaped json pointer and thus does not reflect the property directly - String unescaped = propertyOrIndex.toString(); - if (unescaped.contains("~")) { - unescaped = unescaped.replace("~1", "/"); - unescaped = unescaped.replace("~0", "~"); - } - if (unescaped.contains("%")) { - try { - unescaped = URLDecoder.decode(unescaped, StandardCharsets.UTF_8.toString()); - } catch (UnsupportedEncodingException e) { - // Do nothing - } - } - - value = node.get(unescaped); + value = node.get(propertyOrIndex.toString()); } return (T) value; } diff --git a/src/test/java/com/networknt/schema/SchemaLocationTest.java b/src/test/java/com/networknt/schema/SchemaLocationTest.java index 897f0b2ce..fabdb6ac1 100644 --- a/src/test/java/com/networknt/schema/SchemaLocationTest.java +++ b/src/test/java/com/networknt/schema/SchemaLocationTest.java @@ -17,8 +17,12 @@ import static org.junit.jupiter.api.Assertions.*; +import java.util.Set; + import org.junit.jupiter.api.Test; +import com.networknt.schema.SpecVersion.VersionFlag; + class SchemaLocationTest { @Test @@ -173,6 +177,30 @@ void documentFragment() { assertTrue(SchemaLocation.Fragment.isDocumentFragment("#")); } + @Test + void shouldLoadEscapedFragment() { + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V202012); + JsonSchema schema = factory.getSchema(SchemaLocation + .of("classpath:schema/example-escaped.yaml#/paths/~1users/post/requestBody/application~1json/schema")); + Set result = schema.validate("1", InputFormat.JSON); + assertFalse(result.isEmpty()); + result = schema.validate("{}", InputFormat.JSON); + assertTrue(result.isEmpty()); + } + + @Test + void escapedJsonPointerFragment() { + JsonNodePath fragment = SchemaLocation.Fragment.of("/paths/~1users/post/requestBody/application~1json/schema"); + assertEquals("/paths/~1users/post/requestBody/application~1json/schema", fragment.toString()); + assertEquals(6, fragment.getNameCount()); + assertEquals("paths", fragment.getName(0)); + assertEquals("/users", fragment.getName(1)); + assertEquals("post", fragment.getName(2)); + assertEquals("requestBody", fragment.getName(3)); + assertEquals("application/json", fragment.getName(4)); + assertEquals("schema", fragment.getName(5)); + } + @Test void ofNull() { assertNull(SchemaLocation.of(null)); diff --git a/src/test/resources/schema/example-escaped.yaml b/src/test/resources/schema/example-escaped.yaml new file mode 100644 index 000000000..273e35732 --- /dev/null +++ b/src/test/resources/schema/example-escaped.yaml @@ -0,0 +1,9 @@ +paths: + /users: + post: + requestBody: + application/json: + schema: + anyOf: + - type: object + - type: string \ No newline at end of file