From 16758049b359e00cd7306caacdbfbb70376ad367 Mon Sep 17 00:00:00 2001 From: Yaytay Date: Sat, 3 Sep 2022 08:19:36 +0100 Subject: [PATCH 1/4] Permit escaping of path separators in JavaPropsMapper. Only works for single character separators and escapes. Only works with chars, not code points. Removes escape chars before separator chars, leaves other escapes alone. Sticks with the original processing until it encounters an escape before separator. --- .../dataformat/javaprop/JavaPropsSchema.java | 30 +++++++++-- .../javaprop/util/JPropPathSplitter.java | 53 +++++++++++++++++-- .../dataformat/javaprop/MapParsingTest.java | 8 ++- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java index a4cb37de..7b39f73c 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java @@ -63,6 +63,15 @@ public class JavaPropsSchema */ protected String _pathSeparator = "."; + /** + * Default escape character to use for single character path separators + * , enabling the pathSeparator to be included in a segment. + * Note that this is only used if the path separator is a single character + * and the default value (backslash) is subject to the processing of backslashes + * by the JDK Properties.load method (i.e. two backslashes will be required in the properties file). + */ + protected char _pathSeparatorEscapeChar = '\\'; + /** * Default start marker for index access, if any; empty String may be used * to indicate no marker-based index detection should be made. @@ -158,6 +167,7 @@ public JavaPropsSchema() { } public JavaPropsSchema(JavaPropsSchema base) { _firstArrayOffset = base._firstArrayOffset; _pathSeparator = base._pathSeparator; + _pathSeparatorEscapeChar = base._pathSeparatorEscapeChar; _indexMarker = base._indexMarker; _parseSimpleIndexes = base._parseSimpleIndexes; _writeIndexUsingMarkers = base._writeIndexUsingMarkers; @@ -211,6 +221,19 @@ public JavaPropsSchema withPathSeparator(String v) { return s; } + /** + * Mutant factory method for constructing a new instance with + * specified path separator escape; default being backslash ("\"). + */ + public JavaPropsSchema withPathSeparatorEscapeChar(char v) { + if (_equals(v, _pathSeparator)) { + return this; + } + JavaPropsSchema s = new JavaPropsSchema(this); + s._pathSeparatorEscapeChar = v; + return s; + } + /** * Mutant factory method for constructing a new instance that * specifies that no "path splitting" is to be done: this is @@ -396,9 +419,10 @@ public String pathSeparator() { return _pathSeparator; } - /** - * @since 2.10 - */ + public char pathSeparatorEscapeChar() { + return _pathSeparatorEscapeChar; + } + public String prefix() { return _prefix; } diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java index ab37d24c..3ce45756 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java @@ -1,5 +1,7 @@ package com.fasterxml.jackson.dataformat.javaprop.util; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,7 +49,7 @@ private static JPropPathSplitter pathOnlySplitter(JavaPropsSchema schema) } // otherwise it's still quite simple if (sep.length() == 1) { - return new CharPathOnlySplitter(sep.charAt(0), schema.parseSimpleIndexes()); + return new CharPathOnlySplitter(sep.charAt(0), schema.pathSeparatorEscapeChar(), schema.parseSimpleIndexes()); } return new StringPathOnlySplitter(sep, schema.parseSimpleIndexes()); } @@ -139,12 +141,14 @@ public JPropNode splitAndAdd(JPropNode parent, public static class CharPathOnlySplitter extends JPropPathSplitter { protected final char _pathSeparatorChar; + protected final char _escapeChar; - public CharPathOnlySplitter(char sepChar, boolean useIndex) + public CharPathOnlySplitter(char sepChar, char escapeChar, boolean useIndex) { super(useIndex); _pathSeparatorChar = sepChar; - } + _escapeChar = escapeChar; + } @Override public JPropNode splitAndAdd(JPropNode parent, @@ -157,16 +161,57 @@ public JPropNode splitAndAdd(JPropNode parent, while ((ix = key.indexOf(_pathSeparatorChar, start)) >= start) { if (ix > start) { // segment before separator + if (key.charAt(ix - 1) == _escapeChar) { //potentially escaped, so process slowly + return _continueWithEscapes(curr, key, start, value); + } String segment = key.substring(start, ix); curr = _addSegment(curr, segment); } start = ix + 1; - if (start == key.length()) { + if (start == keyLen) { break; } } return _lastSegment(curr, key, start, keyLen).setValue(value); } + + // Working character by character to handle escapes is slower + // than using indexOf, so only do it if we have an escape char + // before the path separator char. + // Note that this resets back to the previous start, so one segment + // is scanned twice. + private JPropNode _continueWithEscapes(JPropNode parent, String key, int start, String value) { + JPropNode curr = parent; + + int keylen = key.length(); + boolean esc = false; + + StringBuilder segment = new StringBuilder(); + + for (int ix = start; ix < keylen; ++ix) { + int cc = key.charAt(ix); + if (cc ==_escapeChar) { + esc = !esc; + } else if (cc == _pathSeparatorChar) { + if (esc) { + segment.append(key, start, ix - 1); + segment.append((char) cc); + start = ix + 1; + esc = false; + } else { + segment.append(key, start, ix); + curr = _addSegment(curr, segment.toString()); + segment = new StringBuilder(); + } + } else if (esc) { + esc = false; + } + } + segment.append(key, start, keylen); + curr = _addSegment(curr, segment.toString()).setValue(value); + + return curr; + } } /** diff --git a/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java b/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java index d9f89dcb..4aee80f9 100644 --- a/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java +++ b/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java @@ -25,13 +25,19 @@ public void testMapWithBranch() throws Exception final String INPUT = "map=first\n" +"map.b=second\n" +"map.xyz=third\n" + +"map.ab\\\\.c=fourth\n" + +"map.ab\\\\cd\\\\.ef\\\\.gh\\\\\\\\ij=fifth\n" + +"map.\\\\.=sixth\n" ; MapWrapper w = MAPPER.readValue(INPUT, MapWrapper.class); assertNotNull(w.map); - assertEquals(3, w.map.size()); + assertEquals(6, w.map.size()); assertEquals("first", w.map.get("")); assertEquals("second", w.map.get("b")); assertEquals("third", w.map.get("xyz")); + assertEquals("fourth", w.map.get("ab.c")); + assertEquals("fifth", w.map.get("ab\\cd.ef.gh\\\\ij")); + assertEquals("sixth", w.map.get(".")); } } From 496b204a3b94f34f5230cd841788b7380fa91e7e Mon Sep 17 00:00:00 2001 From: Yaytay Date: Sat, 3 Sep 2022 08:21:44 +0100 Subject: [PATCH 2/4] Remove superfluous imports. --- .../jackson/dataformat/javaprop/util/JPropPathSplitter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java index 3ce45756..38a528ce 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java @@ -1,7 +1,5 @@ package com.fasterxml.jackson.dataformat.javaprop.util; -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; import java.util.regex.Matcher; import java.util.regex.Pattern; From 26218f6a5b452e1124515c81beaca7f56aeb6133 Mon Sep 17 00:00:00 2001 From: Yaytay Date: Sun, 4 Sep 2022 08:34:55 +0100 Subject: [PATCH 3/4] Default escape is now '\0', escapes escape escapes (only) when they precede the path separator, more testing. --- .../dataformat/javaprop/JavaPropsSchema.java | 8 +- .../javaprop/util/JPropPathSplitter.java | 43 ++++++---- .../dataformat/javaprop/MapParsingTest.java | 84 +++++++++++++++++-- 3 files changed, 108 insertions(+), 27 deletions(-) diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java index 7b39f73c..3082baaf 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java @@ -70,7 +70,7 @@ public class JavaPropsSchema * and the default value (backslash) is subject to the processing of backslashes * by the JDK Properties.load method (i.e. two backslashes will be required in the properties file). */ - protected char _pathSeparatorEscapeChar = '\\'; + protected char _pathSeparatorEscapeChar = '\0'; /** * Default start marker for index access, if any; empty String may be used @@ -223,7 +223,11 @@ public JavaPropsSchema withPathSeparator(String v) { /** * Mutant factory method for constructing a new instance with - * specified path separator escape; default being backslash ("\"). + * specified path separator escape; default being null ('\0') which + * should effectively disable escape processing. + * Any escape character may be used, backslash ('\\') is the most obvious candidate + * but be aware that the JDK Properties loader will dedupe all backslash characters + * before the JavaPropsMapper gets to see them. */ public JavaPropsSchema withPathSeparatorEscapeChar(char v) { if (_equals(v, _pathSeparator)) { diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java index 38a528ce..9a55bb29 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java @@ -182,28 +182,35 @@ private JPropNode _continueWithEscapes(JPropNode parent, String key, int start, JPropNode curr = parent; int keylen = key.length(); - boolean esc = false; + int escCount = 0; StringBuilder segment = new StringBuilder(); for (int ix = start; ix < keylen; ++ix) { - int cc = key.charAt(ix); - if (cc ==_escapeChar) { - esc = !esc; - } else if (cc == _pathSeparatorChar) { - if (esc) { - segment.append(key, start, ix - 1); - segment.append((char) cc); - start = ix + 1; - esc = false; - } else { - segment.append(key, start, ix); - curr = _addSegment(curr, segment.toString()); - segment = new StringBuilder(); - } - } else if (esc) { - esc = false; - } + int cc = key.charAt(ix); + if (cc ==_escapeChar) { + escCount++; + } else if (cc == _pathSeparatorChar) { + if (escCount > 0) { + segment.append(key, start, ix - ((escCount + 1) >> 1)); + if (escCount % 2 == 0) { + curr = _addSegment(curr, segment.toString()); + segment = new StringBuilder(); + start = ix + 1; + } else { + segment.append((char) cc); + start = ix + 1; + escCount = 0; + } + } else { + segment.append(key, start, ix); + curr = _addSegment(curr, segment.toString()); + segment = new StringBuilder(); + start = ix + 1; + } + } else if (escCount > 0) { + escCount = 0; + } } segment.append(key, start, keylen); curr = _addSegment(curr, segment.toString()).setValue(value); diff --git a/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java b/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java index 4aee80f9..2770140c 100644 --- a/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java +++ b/properties/src/test/java/com/fasterxml/jackson/dataformat/javaprop/MapParsingTest.java @@ -7,10 +7,9 @@ public class MapParsingTest extends ModuleTestBase { static class MapWrapper { - public Map map; + public Map map; } - private final ObjectMapper MAPPER = newPropertiesMapper(); /* /********************************************************************** @@ -18,26 +17,97 @@ static class MapWrapper { /********************************************************************** */ - public void testMapWithBranch() throws Exception + public void testMapWithBranchNoEscaping() throws Exception { + ObjectMapper mapper = newPropertiesMapper(); + // basically "extra" branch should become as first element, and // after that ordering by numeric value final String INPUT = "map=first\n" +"map.b=second\n" +"map.xyz=third\n" +"map.ab\\\\.c=fourth\n" - +"map.ab\\\\cd\\\\.ef\\\\.gh\\\\\\\\ij=fifth\n" - +"map.\\\\.=sixth\n" ; - MapWrapper w = MAPPER.readValue(INPUT, MapWrapper.class); + MapWrapper w = mapper.readValue(INPUT, MapWrapper.class); assertNotNull(w.map); - assertEquals(6, w.map.size()); + assertEquals(4, w.map.size()); + assertEquals("first", w.map.get("")); + assertEquals("second", w.map.get("b")); + assertEquals("third", w.map.get("xyz")); + assertEquals("fourth", ((Map) w.map.get("ab\\")).get("c")); + } + + public void testMapWithBranchBackslashEscape() throws Exception + { + JavaPropsMapper mapper = newPropertiesMapper(); + + // Lots of backslash escaped values + final String INPUT = "map=first\n" + +"map.b=second\n" + +"map.xyz=third\n" + +"map.ab\\\\.c=fourth\n" // ab\. => ab.c + +"map.ab\\\\cd\\\\.ef\\\\.gh\\\\\\\\ij=fifth\n" // ab\cd\.df\.gh\\ij => ab\cd.df.gh\\ij + +"map.\\\\.=sixth\n" // \. => . + +"map.ab\\\\.d=seventh\n" // ab\.d => ab.d + +"map.ef\\\\\\\\.d=eigth\n" // ef\\.d => ef\->d + +"map.ab\\\\\\\\\\\\.d=ninth\n" // ab\\\.d => ab\.d + +"map.xy\\\\.d.ij=tenth\n" // xy\.d.ij => xy.d->ij + +"map.xy\\\\\\\\.d.ij=eleventh\n" // xy\\.d.ij => xy\->d->ij + +"map.xy\\\\\\\\\\\\.d.ij=twelfth\n" // xy\\\.d => xy\.d->ij + ; + MapWrapper w = mapper.reader(new JavaPropsSchema().withPathSeparatorEscapeChar('\\')).readValue(INPUT, MapWrapper.class); + assertNotNull(w.map); + System.out.println(w.map.toString()); + assertEquals(12, w.map.size()); assertEquals("first", w.map.get("")); assertEquals("second", w.map.get("b")); assertEquals("third", w.map.get("xyz")); assertEquals("fourth", w.map.get("ab.c")); assertEquals("fifth", w.map.get("ab\\cd.ef.gh\\\\ij")); assertEquals("sixth", w.map.get(".")); + assertEquals("seventh", w.map.get("ab.d")); + assertEquals("eigth", ((Map) w.map.get("ef\\")).get("d")); + assertEquals("ninth", w.map.get("ab\\.d")); + assertEquals("tenth", ((Map) w.map.get("xy.d")).get("ij")); + assertEquals("eleventh", ((Map) ((Map) w.map.get("xy\\")).get("d")).get("ij")); + assertEquals("twelfth", ((Map) w.map.get("xy\\.d")).get("ij")); + } + + + public void testMapWithBranchHashEscape() throws Exception + { + JavaPropsMapper mapper = newPropertiesMapper(); + + // Lots of backslash escaped values + final String INPUT = "map=first\n" + +"map.b=second\n" + +"map.xyz=third\n" + +"map.ab#.c=fourth\n" // ab#. => ab.c + +"map.ab#cd#.ef#.gh##ij=fifth\n" // ab#cd#.df#.gh##ij => ab#cd.df.gh##ij + +"map.#.=sixth\n" // #. => . + +"map.ab#.d=seventh\n" // ab#.d => ab.d + +"map.ef##.d=eigth\n" // ef##.d => ef#->d + +"map.ab###.d=ninth\n" // ab###.d => ab#.d + +"map.xy#.d.ij=tenth\n" // xy#.d.ij => xy.d->ij + +"map.xy##.d.ij=eleventh\n" // xy##.d.ij => xy#->d->ij + +"map.xy###.d.ij=twelfth\n" // xy###.d => xy#.d->ij + ; + MapWrapper w = mapper.reader(new JavaPropsSchema().withPathSeparatorEscapeChar('#')).readValue(INPUT, MapWrapper.class); + assertNotNull(w.map); + System.out.println(w.map.toString()); + assertEquals(12, w.map.size()); + assertEquals("first", w.map.get("")); + assertEquals("second", w.map.get("b")); + assertEquals("third", w.map.get("xyz")); + assertEquals("fourth", w.map.get("ab.c")); + assertEquals("fifth", w.map.get("ab#cd.ef.gh##ij")); + assertEquals("sixth", w.map.get(".")); + assertEquals("seventh", w.map.get("ab.d")); + assertEquals("eigth", ((Map) w.map.get("ef#")).get("d")); + assertEquals("ninth", w.map.get("ab#.d")); + assertEquals("tenth", ((Map) w.map.get("xy.d")).get("ij")); + assertEquals("eleventh", ((Map) ((Map) w.map.get("xy#")).get("d")).get("ij")); + assertEquals("twelfth", ((Map) w.map.get("xy#.d")).get("ij")); } } From 7238a8289437aa11bca2bb9c794526d04f800d93 Mon Sep 17 00:00:00 2001 From: Yaytay Date: Wed, 7 Sep 2022 08:40:49 +0100 Subject: [PATCH 4/4] Updates following review of PR. --- properties/README.md | 27 +++++++++ .../dataformat/javaprop/JavaPropsSchema.java | 56 ++++++++++++++++--- .../javaprop/util/JPropPathSplitter.java | 12 ++-- 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/properties/README.md b/properties/README.md index 220b97a4..edbd55a3 100644 --- a/properties/README.md +++ b/properties/README.md @@ -234,6 +234,33 @@ Currently existing configuration settings to use can be divide into three groups * `JavaPropsSchema.withPathSeparator(String)` to assign path separator (except if "" given, same as disabling) * `JavaPropsSchema.withoutPathSeparator()` to disable use of path logic; if so, only main-level properties are available, with exact property key as name +#### JavaPropsSchema.pathSeparatorEscapeChar + +* Marker used to enable the JavaPropsSchema.pathSeparator to be included in key names. +* Default value: '\0' (effectively disabling it). +* Mutator methods + * `JavaPropsSchema.withPathSeparatorEscapeChar(char)` to assign path separator escape char +* Notes + * The escape character is only used if the path separator is a single character. + * The escape character is only used for escaping either the pathSeparator character + or a sequence of escape characters immediately prior to the pathSeparator. + * Any escape character may be used. + * Backslash ('\\') is the most obvious character to use, but be aware that the JDK Properties + loader has its own rules for escape processing (documented in the Javadoc for [Properties.load] + (https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/Properties.html#load(java.io.Reader) ) + ) that will remove ALL duplicated backslash characters (and also carry out other escape handling) + before the JavaPropsMapper gets to see them. +* Examples + * Given a pathSeparator of "." and an escape char of '#' then + * a#.b + produces a segment called "a.b" + * a##.b + produces a segment called "a#" with a child called "b" + * a###.b + produces a segment called "a#.b" + * a#b + produces a segment called "a#b" - the escape processing is only used immediately prior to the path separator. + ### JavaPropsSchema: array representation #### JavaPropsSchema.firstArrayOffset diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java index 3082baaf..a7fbff42 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java @@ -66,9 +66,26 @@ public class JavaPropsSchema /** * Default escape character to use for single character path separators * , enabling the pathSeparator to be included in a segment. - * Note that this is only used if the path separator is a single character - * and the default value (backslash) is subject to the processing of backslashes - * by the JDK Properties.load method (i.e. two backslashes will be required in the properties file). + * Note that this is only used if the path separator is a single character. + * + * The default value is NULL ('\0') which effectively disables escape processing. + * + * The escape character is only used for escaping either the pathSeparator character + * or a sequence of escape characters immediately prior to the pathSeparator. + * i.e., if the pathSeparator is "." and the escape char is '#' then "a#.b" + * produces a segment called "a.b", but "a##.b" produces a segment called "a#" + * with a child called "b" and "a###.b" produces a segment called "a#.b". + * Finally, "a#b" produces a segment called "a#b" - the escape processing is only used + * immediately prior to the path separator. + * + * Any escape character may be used. + * Backslash ('\\') is the most obvious candidate but be aware that the JDK Properties + * loader has its own rules for escape processing (documented in the Javadoc for + * Properties.load + * ) that will remove ALL duplicated backslash characters (and also carry out + * other escape handling) before the JavaPropsMapper gets to see them. + * + * @since 2.14 */ protected char _pathSeparatorEscapeChar = '\0'; @@ -223,11 +240,28 @@ public JavaPropsSchema withPathSeparator(String v) { /** * Mutant factory method for constructing a new instance with - * specified path separator escape; default being null ('\0') which - * should effectively disable escape processing. - * Any escape character may be used, backslash ('\\') is the most obvious candidate - * but be aware that the JDK Properties loader will dedupe all backslash characters - * before the JavaPropsMapper gets to see them. + * a different escape character to use for single character path separators + * , enabling the pathSeparator to be included in a segment. + * Note that this is only used if the path separator is a single character. + * + * The default value is NULL ('\0') which effectively disables escape processing. + * + * The escape character is only used for escaping either the pathSeparator character + * or a sequence of escape characters immediately prior to the pathSeparator. + * i.e., if the pathSeparator is "." and the escape char is '#' then "a#.b" + * produces a segment called "a.b", but "a##.b" produces a segment called "a#" + * with a child called "b" and "a###.b" produces a segment called "a#.b". + * Finally, "a#b" produces a segment called "a#b" - the escape processing is only used + * immediately prior to the path separator. + * + * Any escape character may be used. + * Backslash ('\\') is the most obvious candidate but be aware that the JDK Properties + * loader has its own rules for escape processing (documented in the Javadoc for + * Properties.load + * ) that will remove ALL duplicated backslash characters (and also carry out + * other escape handling) before the JavaPropsMapper gets to see them. + * + * @since 2.14 */ public JavaPropsSchema withPathSeparatorEscapeChar(char v) { if (_equals(v, _pathSeparator)) { @@ -423,10 +457,16 @@ public String pathSeparator() { return _pathSeparator; } + /** + * @since 2.14 + */ public char pathSeparatorEscapeChar() { return _pathSeparatorEscapeChar; } + /** + * @since 2.10 + */ public String prefix() { return _prefix; } diff --git a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java index 9a55bb29..2703e14f 100644 --- a/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java +++ b/properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java @@ -139,13 +139,13 @@ public JPropNode splitAndAdd(JPropNode parent, public static class CharPathOnlySplitter extends JPropPathSplitter { protected final char _pathSeparatorChar; - protected final char _escapeChar; + protected final char _pathSeparatorEscapeChar; - public CharPathOnlySplitter(char sepChar, char escapeChar, boolean useIndex) + public CharPathOnlySplitter(char sepChar, char pathSeparatorEscapeChar, boolean useIndex) { super(useIndex); _pathSeparatorChar = sepChar; - _escapeChar = escapeChar; + _pathSeparatorEscapeChar = pathSeparatorEscapeChar; } @Override @@ -159,7 +159,7 @@ public JPropNode splitAndAdd(JPropNode parent, while ((ix = key.indexOf(_pathSeparatorChar, start)) >= start) { if (ix > start) { // segment before separator - if (key.charAt(ix - 1) == _escapeChar) { //potentially escaped, so process slowly + if (key.charAt(ix - 1) == _pathSeparatorEscapeChar) { //potentially escaped, so process slowly return _continueWithEscapes(curr, key, start, value); } String segment = key.substring(start, ix); @@ -188,7 +188,7 @@ private JPropNode _continueWithEscapes(JPropNode parent, String key, int start, for (int ix = start; ix < keylen; ++ix) { int cc = key.charAt(ix); - if (cc ==_escapeChar) { + if (cc ==_pathSeparatorEscapeChar) { escCount++; } else if (cc == _pathSeparatorChar) { if (escCount > 0) { @@ -208,7 +208,7 @@ private JPropNode _continueWithEscapes(JPropNode parent, String key, int start, segment = new StringBuilder(); start = ix + 1; } - } else if (escCount > 0) { + } else { escCount = 0; } }