Skip to content

Commit 457d4df

Browse files
committed
fix: escape keys in JSON paths and add test for patternProperties
closes #22
1 parent c26e73c commit 457d4df

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

src/main/java/io/zenwave360/jsonrefparser/$Ref.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public URI getReferencingFileURI() {
7575

7676
@Override
7777
public String toString() {
78-
return "$Ref {" + (uri != null? uri.toString() : "") + path + '}';
78+
return "$Ref {" + (uri != null? uri.toString() : "") + (path != null? path : "") + '}';
7979
}
8080

8181
@Override
@@ -105,6 +105,9 @@ private static String mungedRef(String refString) {
105105
refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension)
106106
return "./" + refString;
107107
}
108+
if("#".equals(refString) || refString == null) {
109+
return REFERENCE_SEPARATOR;
110+
}
108111
return refString;
109112
}
110113

src/main/java/io/zenwave360/jsonrefparser/$RefParser.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public class $RefParser {
152152
private void mergeAllOf(Object value, String[] paths, URI currentFileURL) {
153153
// Use object identity to detect actual circular object references
154154
if (mergeAllOfObjectStack.contains(value)) {
155-
log.debug("Detected circular object reference during mergeAllOf at path: {}", Arrays.toString(paths));
155+
log.trace("Detected circular object reference during mergeAllOf at path: {}", Arrays.toString(paths));
156156
return; // Skip to prevent infinite recursion
157157
}
158158

@@ -283,7 +283,11 @@ private void dereference(ExtendedJsonContext jsonContext, Object value, String[]
283283

284284
try {
285285
if(paths.length > 0 && "$ref".equals(paths[paths.length -1])) {
286-
$Ref $ref = $Ref.of((String) value, currentFileURL);
286+
$Ref $ref = extractRef(value, currentFileURL);
287+
if($ref == null) {
288+
log.trace("{}Not a $ref '{}': {}", indent(), visitedNodeRef, value);
289+
return;
290+
}
287291
// Check for circular references using reference stack
288292
var targetNodeRef = String.format("%s%s",
289293
ObjectUtils.firstNonNull($ref.getURI(), currentFileURL),
@@ -342,6 +346,23 @@ private void dereference(ExtendedJsonContext jsonContext, Object value, String[]
342346
}
343347
}
344348

349+
private $Ref extractRef(Object value, URI currentFileURL) {
350+
String refString;
351+
if (value instanceof String) {
352+
refString = (String) value;
353+
} else if (value instanceof Map<?, ?> && ((Map) value).containsKey("$ref")) {
354+
Object refObj = ((Map) value).get("$ref");
355+
if (!(refObj instanceof String)) {
356+
throw new IllegalArgumentException("Invalid $ref value");
357+
}
358+
refString = (String) refObj;
359+
// Opcional: verificar que no haya otras claves no permitidas
360+
} else {
361+
return null;
362+
}
363+
return $Ref.of(refString, currentFileURL);
364+
}
365+
345366
private void replaceWith$Ref(ExtendedJsonContext jsonContext, String jsonPath, Object resolved) {
346367
Map<String, Object> original = jsonContext.read(jsonPath);
347368
if(original.containsKey("$ref") && original.size() == 1) {
@@ -397,11 +418,10 @@ private Object dereference($Ref $ref, ExtendedJsonContext jsonContext, URI curre
397418
}
398419
// resolve internal path
399420
if(StringUtils.isNotBlank($ref.getPath())) {
400-
String jsonPaths[] = $ref.getPath().replace($Ref.REFERENCE_SEPARATOR, "").split("/");
421+
String[] jsonPaths = $ref.getPath().replace($Ref.REFERENCE_SEPARATOR, "").split("/");
401422
String jsonPath = jsonPath(jsonPaths);
402423
try {
403-
Object resolved = jsonContext.read(jsonPath);
404-
return resolved;
424+
return jsonContext.read(jsonPath);
405425
} catch (Exception e) {
406426
log.error("Error reading internal path: {}", $ref, e);
407427
throw e;
@@ -418,6 +438,9 @@ protected Resolver getResolver(RefFormat refFormat, URI currentURL) {
418438
}
419439

420440
private String jsonPath(String[] paths) {
441+
if(paths.length == 0 || paths[0].isEmpty()) {
442+
return "$";
443+
}
421444
return "$" + Arrays.stream(paths).map(path -> "['" + escapeKey(path) + "']").collect(Collectors.joining());
422445
}
423446

0 commit comments

Comments
 (0)