Skip to content

Commit 724567f

Browse files
committed
Minor refactoring of JsonPointer in preparation for tackling #818
1 parent 2a6527f commit 724567f

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

src/main/java/com/fasterxml/jackson/core/JsonPointer.java

+32-20
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,16 @@ protected static JsonPointer _parseTail(String input) {
576576
++i;
577577
// quoting is different; offline this case
578578
if (c == '~' && i < end) { // possibly, quote
579-
return _parseQuotedTail(input, i);
579+
// 04-Oct-2022, tatu: Let's decode escaped segment
580+
// instead of recursive call
581+
StringBuilder sb = new StringBuilder(32);
582+
i = _extractEscapedSegment(input, i, sb);
583+
final String segment = sb.toString();
584+
if (i < 0) { // end!
585+
return new JsonPointer(input, segment, EMPTY);
586+
}
587+
return new JsonPointer(input, segment,
588+
_parseTail(input.substring(i)));
580589
}
581590
// otherwise, loop on
582591
}
@@ -585,26 +594,29 @@ protected static JsonPointer _parseTail(String input) {
585594
}
586595

587596
/**
588-
* Method called to parse tail of pointer path, when a potentially
589-
* escaped character has been seen.
597+
* Method called to extract the next segment of the path, in case
598+
* where we seem to have encountered a (tilde-)escaped character
599+
* within segment.
590600
*
591601
* @param input Full input for the tail being parsed
592602
* @param i Offset to character after tilde
603+
* @param sb StringBuilder into which unquoted segment is added
593604
*
594-
* @return Pointer instance constructed
605+
* @return Offset at which slash was encountered, if any, or -1
606+
* if expression ended without seeing unescaped slash
595607
*/
596-
protected static JsonPointer _parseQuotedTail(String input, int i) {
608+
protected static int _extractEscapedSegment(String input, int i,
609+
StringBuilder sb)
610+
{
597611
final int end = input.length();
598-
StringBuilder sb = new StringBuilder(Math.max(16, end));
599612
if (i > 2) {
600613
sb.append(input, 1, i-1);
601614
}
602615
_appendEscape(sb, input.charAt(i++));
603616
while (i < end) {
604617
char c = input.charAt(i);
605618
if (c == '/') { // end is nigh!
606-
return new JsonPointer(input, sb.toString(),
607-
_parseTail(input.substring(i)));
619+
return i;
608620
}
609621
++i;
610622
if (c == '~' && i < end) {
@@ -614,7 +626,18 @@ protected static JsonPointer _parseQuotedTail(String input, int i) {
614626
sb.append(c);
615627
}
616628
// end of the road, last segment
617-
return new JsonPointer(input, sb.toString(), EMPTY);
629+
return -1;
630+
}
631+
632+
private static void _appendEscape(StringBuilder sb, char c) {
633+
if (c == '0') {
634+
c = '~';
635+
} else if (c == '1') {
636+
c = '/';
637+
} else {
638+
sb.append('~');
639+
}
640+
sb.append(c);
618641
}
619642

620643
protected JsonPointer _constructHead()
@@ -642,17 +665,6 @@ protected JsonPointer _constructHead(int suffixLength, JsonPointer last)
642665
_matchingElementIndex, next._constructHead(suffixLength, last));
643666
}
644667

645-
private static void _appendEscape(StringBuilder sb, char c) {
646-
if (c == '0') {
647-
c = '~';
648-
} else if (c == '1') {
649-
c = '/';
650-
} else {
651-
sb.append('~');
652-
}
653-
sb.append(c);
654-
}
655-
656668
/*
657669
/**********************************************************
658670
/* Support for JDK serialization (2.14+)

src/test/java/com/fasterxml/jackson/failing/Fuzz51806JsonPointerParseTest.java renamed to src/test/java/com/fasterxml/jackson/failing/Fuzz51806JsonPointerParse818Test.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
// For https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51806
77
// (reported as [core#818]
8-
public class Fuzz51806JsonPointerParseTest extends BaseTest
8+
public class Fuzz51806JsonPointerParse818Test extends BaseTest
99
{
1010
// Before fix, looks like this is enough to cause StackOverflowError
1111
private final static int TOO_DEEP_PATH = 6000;

0 commit comments

Comments
 (0)