Skip to content

Commit

Permalink
Fix #818
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 5, 2022
1 parent 724567f commit 772bd09
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 14 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ JSON library.
`byte[]`/`char[]`/String-with-offsets input
#812: Add explicit bounds checks for `JsonFactory.createParser()` methods
that take `byte[]`/`char[]`-with-offsets input
#818: Calling `JsonPointer.compile(...)` on very deeply nested expression
throws `StackOverflowErrror`
2.13.4 (03-Sep-2022)
Expand Down
65 changes: 53 additions & 12 deletions src/main/java/com/fasterxml/jackson/core/JsonPointer.java
Original file line number Diff line number Diff line change
Expand Up @@ -562,37 +562,56 @@ private final static int _parseIndex(String str) {
}
return NumberInput.parseInt(str);
}

protected static JsonPointer _parseTail(String input) {
final int end = input.length();

protected static JsonPointer _parseTail(String fullPath)
{
PointerParent parent = null;

// first char is the contextual slash, skip
for (int i = 1; i < end; ) {
char c = input.charAt(i);
int i = 1;
int end = fullPath.length();

while (i < end) {
char c = fullPath.charAt(i);
if (c == '/') { // common case, got a segment
return new JsonPointer(input, input.substring(1, i),
_parseTail(input.substring(i)));
parent = new PointerParent(parent, fullPath, fullPath.substring(1, i));
fullPath = fullPath.substring(i);
i = 1;
end = fullPath.length();
continue;
}
++i;
// quoting is different; offline this case
if (c == '~' && i < end) { // possibly, quote
// 04-Oct-2022, tatu: Let's decode escaped segment
// instead of recursive call
StringBuilder sb = new StringBuilder(32);
i = _extractEscapedSegment(input, i, sb);
i = _extractEscapedSegment(fullPath, i, sb);
final String segment = sb.toString();
if (i < 0) { // end!
return new JsonPointer(input, segment, EMPTY);
return _buildPath(fullPath, segment, parent);
}
return new JsonPointer(input, segment,
_parseTail(input.substring(i)));
parent = new PointerParent(parent, fullPath, segment);
fullPath = fullPath.substring(i);
i = 1;
end = fullPath.length();
continue;
}
// otherwise, loop on
}
// end of the road, no escapes
return new JsonPointer(input, input.substring(1), EMPTY);
return _buildPath(fullPath, fullPath.substring(1), parent);
}

private static JsonPointer _buildPath(String fullPath, String segment,
PointerParent parent) {
JsonPointer curr = new JsonPointer(fullPath, segment, EMPTY);
for (; parent != null; parent = parent.parent) {
curr = new JsonPointer(parent.fullPath, parent.segment, curr);
}
return curr;
}

/**
* Method called to extract the next segment of the path, in case
* where we seem to have encountered a (tilde-)escaped character
Expand Down Expand Up @@ -665,6 +684,28 @@ protected JsonPointer _constructHead(int suffixLength, JsonPointer last)
_matchingElementIndex, next._constructHead(suffixLength, last));
}

/*
/**********************************************************
/* Helper class used to replace call stack (2.14+)
/**********************************************************
*/

/**
* Helper class used to replace call stack when parsing JsonPointer
* expressions.
*/
private static class PointerParent {
public final PointerParent parent;
public final String fullPath;
public final String segment;

PointerParent(PointerParent pp, String fp, String sgm) {
parent = pp;
fullPath = fp;
segment = sgm;
}
}

/*
/**********************************************************
/* Support for JDK serialization (2.14+)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.fasterxml.jackson.failing;
package com.fasterxml.jackson.core.fuzz;

import com.fasterxml.jackson.core.BaseTest;
import com.fasterxml.jackson.core.JsonPointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void doIllegalTest(String s) {
public void doLegalTest(String s) {
double actual = significandToDouble(s.getBytes(StandardCharsets.ISO_8859_1));
double expected = Double.parseDouble(s);
System.out.println(expected + " == " + actual);
// System.out.println(expected + " == " + actual);
assertEquals(expected, actual);
}

Expand Down

0 comments on commit 772bd09

Please sign in to comment.