From 569e544a1028745927205585836eff7feb14b934 Mon Sep 17 00:00:00 2001 From: Kalle Stenflo Date: Wed, 9 Dec 2015 17:20:20 +0100 Subject: [PATCH 1/2] Tests covering issue #166 --- .../com/jayway/jsonpath/DeepScanTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/json-path/src/test/java/com/jayway/jsonpath/DeepScanTest.java b/json-path/src/test/java/com/jayway/jsonpath/DeepScanTest.java index e98ee62f..17994b11 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/DeepScanTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/DeepScanTest.java @@ -304,4 +304,34 @@ public class DeepScanTest extends BaseTest { assertThat(result).hasSize(1); } + @Test + public void deepScanPathDefault() { + executeScanPath(); + } + + @Test + public void deepScanPathRequireProperties() { + executeScanPath(Option.REQUIRE_PROPERTIES); + } + + private void executeScanPath(Option... options) { + String json = "{'index': 'index', 'data': {'array': [{ 'object1': { 'name': 'robert'} }]}}"; + Map expected = new HashMap() {{ + put("object1", new HashMap() {{ + put("name", "robert"); + }}); + }}; + + Configuration configuration = Configuration + .builder() + .options(options) + .build(); + + List> result = JsonPath + .using(configuration) + .parse(json) + .read("$..array[0]"); + assertThat(result.get(0)).isEqualTo(expected); + } + } From ac83feea14f6b994b2a2afd6dc1b54e5d2f97404 Mon Sep 17 00:00:00 2001 From: Kalle Stenflo Date: Thu, 10 Dec 2015 21:28:25 +0100 Subject: [PATCH 2/2] Improved escape handling and fixed JsonValueNode issue. --- .../jsonpath/internal/CharacterIndex.java | 70 ++++++------------- .../com/jayway/jsonpath/internal/PathRef.java | 2 - .../jsonpath/internal/filter/ValueNode.java | 4 +- .../jsonpath/internal/path/PathCompiler.java | 1 - .../spi/json/TapestryJsonProvider.java | 9 ++- .../spi/mapper/TapestryMappingProvider.java | 4 +- .../jayway/jsonpath/FilterCompilerTest.java | 2 +- .../com/jayway/jsonpath/InlineFilterTest.java | 21 ++++++ 8 files changed, 50 insertions(+), 63 deletions(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java b/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java index bd35ba6a..503c1dde 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java @@ -77,51 +77,22 @@ public class CharacterIndex { int readPosition = startPosition + 1; while (inBounds(readPosition)) { if (skipStrings) { - if (charAt(readPosition) == SINGLE_QUOTE) { - boolean escaped = false; - while (inBounds(readPosition)) { - readPosition++; - if (escaped) { - escaped = false; - continue; - } - if (charAt(readPosition) == ESCAPE) { - escaped = true; - continue; - } - if (charAt(readPosition) == SINGLE_QUOTE) { - readPosition++; - break; - } - } - } else if (charAt(readPosition) == DOUBLE_QUOTE) { - boolean escaped = false; - while (inBounds(readPosition)) { - readPosition++; - if (escaped) { - escaped = false; - continue; - } - if (charAt(readPosition) == ESCAPE) { - escaped = true; - continue; - } - if (charAt(readPosition) == DOUBLE_QUOTE) { - readPosition++; - break; - } + char quoteChar = charAt(readPosition); + if (quoteChar == SINGLE_QUOTE || quoteChar == DOUBLE_QUOTE){ + readPosition = nextIndexOfUnescaped(readPosition, quoteChar); + if(readPosition == -1){ + throw new InvalidPathException("Could not find matching close quote for " + quoteChar + " when parsing : " + charSequence); } + readPosition++; } } if (skipRegex) { if (charAt(readPosition) == REGEX) { - while (inBounds(readPosition)) { - readPosition++; - if (charAt(readPosition) == REGEX) { - readPosition++; - break; - } + readPosition = nextIndexOfUnescaped(readPosition, REGEX); + if(readPosition == -1){ + throw new InvalidPathException("Could not find matching close for " + REGEX + " when parsing regex in : " + charSequence); } + readPosition++; } } if (charAt(readPosition) == openChar) { @@ -174,23 +145,22 @@ public class CharacterIndex { } public int nextIndexOfUnescaped(char c) { - return nextIndexOfUnescaped(position + 1, c); + return nextIndexOfUnescaped(position, c); } public int nextIndexOfUnescaped(int startPosition, char c) { - int readPosition = startPosition; - char prev1; - char prev2; - while (!isOutOfBounds(readPosition)) { - prev1 = charAtOr(readPosition - 1, ' '); - prev2 = charAtOr(readPosition - 2, ' '); - boolean ignore = (prev1 == '\\' && prev2 == '\\'); - boolean escaped = (prev1 == '\\' && !ignore); - if (charAt(readPosition) == c && !escaped) { + int readPosition = startPosition + 1; + boolean inEscape = false; + while (!isOutOfBounds(readPosition)) { + if(inEscape){ + inEscape = false; + } else if('\\' == charAt(readPosition)){ + inEscape = true; + } else if (c == charAt(readPosition) && !inEscape){ return readPosition; } - readPosition++; + readPosition ++; } return -1; } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java b/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java index 0ca3eaaf..1b42be31 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java @@ -218,8 +218,6 @@ public abstract class PathRef implements Comparable { } } - - private static class ObjectPropertyPathRef extends PathRef { private String property; diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index 7352fa04..ffbe0241 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -174,8 +174,8 @@ public abstract class ValueNode { if(o instanceof ValueNode) return (ValueNode)o; if(o instanceof Class) return createClassNode((Class)o); else if(isPath(o)) return new PathNode(o.toString(), false, false); - else if(isJson(o)) return createStringNode(o.toString(), false); - else if(o instanceof String) return createStringNode(o.toString(), false); + else if(isJson(o)) return createJsonNode(o.toString()); + else if(o instanceof String) return createStringNode(o.toString(), true); else if(o instanceof Character) return createStringNode(o.toString(), false); else if(o instanceof Number) return createNumberNode(o.toString()); else if(o instanceof Boolean) return createBooleanNode(o.toString()); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java index eccd1189..4a8af920 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java @@ -256,7 +256,6 @@ public class PathCompiler { Predicate predicate = FilterCompiler.compile(criteria); - //Predicate predicate = Filter.parse(criteria); appender.appendPathToken(PathTokenFactory.createPredicatePathToken(predicate)); path.setPosition(closeStatementBracketIndex + 1); diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/TapestryJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/TapestryJsonProvider.java index 55563c88..92cd1ef8 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/TapestryJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/TapestryJsonProvider.java @@ -1,14 +1,13 @@ package com.jayway.jsonpath.spi.json; -import java.io.InputStream; -import java.util.Collection; -import java.util.Scanner; - +import com.jayway.jsonpath.InvalidJsonException; import org.apache.tapestry5.json.JSONArray; import org.apache.tapestry5.json.JSONCollection; import org.apache.tapestry5.json.JSONObject; -import com.jayway.jsonpath.InvalidJsonException; +import java.io.InputStream; +import java.util.Collection; +import java.util.Scanner; public class TapestryJsonProvider extends AbstractJsonProvider { diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/mapper/TapestryMappingProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/mapper/TapestryMappingProvider.java index 7c284cfb..41ff4ffe 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/mapper/TapestryMappingProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/mapper/TapestryMappingProvider.java @@ -14,11 +14,11 @@ */ package com.jayway.jsonpath.spi.mapper; -import java.util.ArrayList; - import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.TypeRef; +import java.util.ArrayList; + public class TapestryMappingProvider implements MappingProvider { @Override diff --git a/json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java b/json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java index 104ddd08..ce744e38 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java @@ -81,7 +81,7 @@ public class FilterCompilerTest { compile(filter); throw new AssertionError("Expected " + filter + " to throw InvalidPathException"); } catch (InvalidPathException e){ - e.printStackTrace(); + //e.printStackTrace(); } } } diff --git a/json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java b/json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java index 28d9674a..5f19a8df 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java @@ -186,6 +186,27 @@ public class InlineFilterTest extends BaseTest { assertHasOneResult("[{\"value\":5.1}]", "$[?(@.value<7)]", conf); assertHasNoResults("[{\"value\":7.1}]", "$[?(@.value<5)]", conf); + } + @Test + public void escaped_literals() { + if(conf.jsonProvider().getClass().getSimpleName().startsWith("Jackson")){ + return; + } + assertHasOneResult("[\"\\'foo\"]", "$[?(@ == '\\'foo')]", conf); + } + + @Test + public void escaped_literals2() { + if(conf.jsonProvider().getClass().getSimpleName().startsWith("Jackson")){ + return; + } + assertHasOneResult("[\"\\\\'foo\"]", "$[?(@ == \"\\\\'foo\")]", conf); + } + + + @Test + public void escape_pattern() { + assertHasOneResult("[\"x\"]", "$[?(@ =~ /\\/|x/)]", conf); } }