Skip to content

Commit bce0156

Browse files
authored
Fix schema location for escaped json pointer (#1038)
1 parent bc61ef3 commit bce0156

File tree

4 files changed

+56
-20
lines changed

4 files changed

+56
-20
lines changed

src/main/java/com/networknt/schema/SchemaLocation.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package com.networknt.schema;
1717

18+
import java.io.UnsupportedEncodingException;
19+
import java.net.URLDecoder;
20+
import java.nio.charset.StandardCharsets;
1821
import java.util.Objects;
1922

2023
/**
@@ -230,7 +233,21 @@ public static JsonNodePath of(String fragmentString) {
230233
if (index != -1) {
231234
fragment = fragment.append(index);
232235
} else {
233-
fragment = fragment.append(fragmentPart.toString());
236+
String fragmentPartString = fragmentPart.toString();
237+
if (PathType.JSON_POINTER.equals(fragment.getPathType())) {
238+
if (fragmentPartString.contains("~")) {
239+
fragmentPartString = fragmentPartString.replace("~1", "/");
240+
fragmentPartString = fragmentPartString.replace("~0", "~");
241+
}
242+
if (fragmentPartString.contains("%")) {
243+
try {
244+
fragmentPartString = URLDecoder.decode(fragmentPartString, StandardCharsets.UTF_8.toString());
245+
} catch (UnsupportedEncodingException e) {
246+
// Do nothing
247+
}
248+
}
249+
}
250+
fragment = fragment.append(fragmentPartString);
234251
}
235252
}
236253
if (index == -1 && fragmentString.endsWith("/")) {

src/main/java/com/networknt/schema/utils/JsonNodes.java

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
*/
1616
package com.networknt.schema.utils;
1717

18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLDecoder;
20-
import java.nio.charset.StandardCharsets;
21-
2218
import com.fasterxml.jackson.databind.JsonNode;
2319
import com.networknt.schema.JsonNodePath;
2420

@@ -61,21 +57,7 @@ public static <T extends JsonNode> T get(JsonNode node, Object propertyOrIndex)
6157
if (propertyOrIndex instanceof Number) {
6258
value = node.get(((Number) propertyOrIndex).intValue());
6359
} else {
64-
// In the case of string this represents an escaped json pointer and thus does not reflect the property directly
65-
String unescaped = propertyOrIndex.toString();
66-
if (unescaped.contains("~")) {
67-
unescaped = unescaped.replace("~1", "/");
68-
unescaped = unescaped.replace("~0", "~");
69-
}
70-
if (unescaped.contains("%")) {
71-
try {
72-
unescaped = URLDecoder.decode(unescaped, StandardCharsets.UTF_8.toString());
73-
} catch (UnsupportedEncodingException e) {
74-
// Do nothing
75-
}
76-
}
77-
78-
value = node.get(unescaped);
60+
value = node.get(propertyOrIndex.toString());
7961
}
8062
return (T) value;
8163
}

src/test/java/com/networknt/schema/SchemaLocationTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
import static org.junit.jupiter.api.Assertions.*;
1919

20+
import java.util.Set;
21+
2022
import org.junit.jupiter.api.Test;
2123

24+
import com.networknt.schema.SpecVersion.VersionFlag;
25+
2226
class SchemaLocationTest {
2327

2428
@Test
@@ -173,6 +177,30 @@ void documentFragment() {
173177
assertTrue(SchemaLocation.Fragment.isDocumentFragment("#"));
174178
}
175179

180+
@Test
181+
void shouldLoadEscapedFragment() {
182+
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V202012);
183+
JsonSchema schema = factory.getSchema(SchemaLocation
184+
.of("classpath:schema/example-escaped.yaml#/paths/~1users/post/requestBody/application~1json/schema"));
185+
Set<ValidationMessage> result = schema.validate("1", InputFormat.JSON);
186+
assertFalse(result.isEmpty());
187+
result = schema.validate("{}", InputFormat.JSON);
188+
assertTrue(result.isEmpty());
189+
}
190+
191+
@Test
192+
void escapedJsonPointerFragment() {
193+
JsonNodePath fragment = SchemaLocation.Fragment.of("/paths/~1users/post/requestBody/application~1json/schema");
194+
assertEquals("/paths/~1users/post/requestBody/application~1json/schema", fragment.toString());
195+
assertEquals(6, fragment.getNameCount());
196+
assertEquals("paths", fragment.getName(0));
197+
assertEquals("/users", fragment.getName(1));
198+
assertEquals("post", fragment.getName(2));
199+
assertEquals("requestBody", fragment.getName(3));
200+
assertEquals("application/json", fragment.getName(4));
201+
assertEquals("schema", fragment.getName(5));
202+
}
203+
176204
@Test
177205
void ofNull() {
178206
assertNull(SchemaLocation.of(null));
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
paths:
2+
/users:
3+
post:
4+
requestBody:
5+
application/json:
6+
schema:
7+
anyOf:
8+
- type: object
9+
- type: string

0 commit comments

Comments
 (0)