You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/08/11 07:55:02 UTC
git commit: [OLINGO-396] Added stricter check for $format in uri
Repository: olingo-odata4
Updated Branches:
refs/heads/master e3d3bde6e -> 5f4d0507e
[OLINGO-396] Added stricter check for $format in uri
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/5f4d0507
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/5f4d0507
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/5f4d0507
Branch: refs/heads/master
Commit: 5f4d0507e8d509d51b52bf062a04bca64b651fb9
Parents: e3d3bde
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Aug 8 10:49:58 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Aug 11 07:54:42 2014 +0200
----------------------------------------------------------------------
.../olingo/server/core/uri/antlr/UriParser.g4 | 2 +-
.../olingo/server/core/uri/parser/Parser.java | 84 ++++++++++++--------
.../core/uri/antlr/TestFullResourcePath.java | 28 ++++++-
.../core/uri/validator/UriValidatorTest.java | 4 +-
4 files changed, 79 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5f4d0507/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4 b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
index 3c36782..404c04f 100644
--- a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
+++ b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
@@ -146,7 +146,7 @@ orderByItem : vC=commonExpr ( WSP ( vA=ASC | vD=DESC ) )?;
skip : SKIP EQ INT;
top : TOP EQ INT;
-//format : FORMAT EQ ( ATOM | JSON | XML | PCHARS ( SLASH PCHARS)?);
+//format : FORMAT EQ ( ATOM | JSON | XML | PCHARS SLASH PCHARS);
inlinecount : COUNT EQ booleanNonCase;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5f4d0507/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index 1136811..374c108 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -27,10 +27,12 @@ import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.atn.PredictionMode;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
import org.apache.olingo.server.core.uri.UriInfoImpl;
import org.apache.olingo.server.core.uri.antlr.UriLexer;
import org.apache.olingo.server.core.uri.antlr.UriParserParser;
@@ -165,7 +167,7 @@ public class Parser {
customOption.setName(option.name);
customOption.setText(option.value);
context.contextUriInfo.addCustomQueryOption(customOption);
- } else if (option.name.equals("$filter")) {
+ } else if (option.name.equals(SystemQueryOptionKind.FILTER.toString())) {
FilterExpressionEOFContext ctxFilterExpression =
(FilterExpressionEOFContext) parseRule(option.value, ParserEntryRules.FilterExpression);
@@ -174,14 +176,22 @@ public class Parser {
context.contextUriInfo.setSystemQueryOption(filterOption);
- } else if (option.name.equals("$format")) {
+ } else if (option.name.equals(SystemQueryOptionKind.FORMAT.toString())) {
FormatOptionImpl formatOption = new FormatOptionImpl();
formatOption.setName(option.name);
formatOption.setText(option.value);
- formatOption.setFormat(option.value);
+ if (option.value.equalsIgnoreCase(ODataFormat.JSON.name())
+ || option.value.equalsIgnoreCase(ODataFormat.XML.name())
+ || option.value.equalsIgnoreCase(ODataFormat.ATOM.name())
+ || isFormatSyntaxValid(option)) {
+ formatOption.setFormat(option.value);
+ } else {
+ throw new UriParserSemanticException("Illegal value of $format option!",
+ UriParserSemanticException.MessageKeys.TEST);
+ }
context.contextUriInfo.setSystemQueryOption(formatOption);
- } else if (option.name.equals("$expand")) {
+ } else if (option.name.equals(SystemQueryOptionKind.EXPAND.toString())) {
ExpandItemsEOFContext ctxExpandItems =
(ExpandItemsEOFContext) parseRule(option.value, ParserEntryRules.ExpandItems);
@@ -190,60 +200,62 @@ public class Parser {
context.contextUriInfo.setSystemQueryOption(expandOption);
- } else if (option.name.equals("$id")) {
+ } else if (option.name.equals(SystemQueryOptionKind.ID.toString())) {
IdOptionImpl idOption = new IdOptionImpl();
idOption.setName(option.name);
idOption.setText(option.value);
idOption.setValue(option.value);
context.contextUriInfo.setSystemQueryOption(idOption);
- } else if (option.name.equals("$orderby")) {
+ } else if (option.name.equals(SystemQueryOptionKind.LEVELS.toString())) {
+ throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
+ UriParserSyntaxException.MessageKeys.TEST);
+ } else if (option.name.equals(SystemQueryOptionKind.ORDERBY.toString())) {
OrderByEOFContext ctxFilterExpression =
(OrderByEOFContext) parseRule(option.value, ParserEntryRules.Orderby);
- OrderByOptionImpl filterOption =
+ OrderByOptionImpl orderByOption =
(OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxFilterExpression);
- context.contextUriInfo.setSystemQueryOption(filterOption);
- } else if (option.name.equals("$search")) {
+ context.contextUriInfo.setSystemQueryOption(orderByOption);
+ } else if (option.name.equals(SystemQueryOptionKind.SEARCH.toString())) {
throw new RuntimeException("System query option '$search' not implemented!");
- } else if (option.name.equals("$select")) {
+ } else if (option.name.equals(SystemQueryOptionKind.SELECT.toString())) {
SelectEOFContext ctxSelectEOF =
(SelectEOFContext) parseRule(option.value, ParserEntryRules.Select);
- SelectOptionImpl expandOption =
+ SelectOptionImpl selectOption =
(SelectOptionImpl) uriParseTreeVisitor.visitSelectEOF(ctxSelectEOF);
- context.contextUriInfo.setSystemQueryOption(expandOption);
- } else if (option.name.equals("$skip")) {
- SkipOptionImpl inlineCountOption = new SkipOptionImpl();
- inlineCountOption.setName(option.name);
- inlineCountOption.setText(option.value);
+ context.contextUriInfo.setSystemQueryOption(selectOption);
+ } else if (option.name.equals(SystemQueryOptionKind.SKIP.toString())) {
+ SkipOptionImpl skipOption = new SkipOptionImpl();
+ skipOption.setName(option.name);
+ skipOption.setText(option.value);
try {
- inlineCountOption.setValue(Integer.parseInt(option.value));
+ skipOption.setValue(Integer.parseInt(option.value));
} catch (final NumberFormatException e) {
throw new UriParserSemanticException("Illegal value of $skip option!", e,
UriParserSemanticException.MessageKeys.TEST);
}
- context.contextUriInfo.setSystemQueryOption(inlineCountOption);
- } else if (option.name.equals("$skiptoken")) {
- SkipTokenOptionImpl inlineCountOption = new SkipTokenOptionImpl();
- inlineCountOption.setName(option.name);
- inlineCountOption.setText(option.value);
- inlineCountOption.setValue(option.value);
- context.contextUriInfo.setSystemQueryOption(inlineCountOption);
- } else if (option.name.equals("$top")) {
- TopOptionImpl inlineCountOption = new TopOptionImpl();
- inlineCountOption.setName(option.name);
- inlineCountOption.setText(option.value);
+ context.contextUriInfo.setSystemQueryOption(skipOption);
+ } else if (option.name.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) {
+ SkipTokenOptionImpl skipTokenOption = new SkipTokenOptionImpl();
+ skipTokenOption.setName(option.name);
+ skipTokenOption.setText(option.value);
+ skipTokenOption.setValue(option.value);
+ context.contextUriInfo.setSystemQueryOption(skipTokenOption);
+ } else if (option.name.equals(SystemQueryOptionKind.TOP.toString())) {
+ TopOptionImpl topOption = new TopOptionImpl();
+ topOption.setName(option.name);
+ topOption.setText(option.value);
try {
- inlineCountOption.setValue(Integer.parseInt(option.value));
+ topOption.setValue(Integer.parseInt(option.value));
} catch (final NumberFormatException e) {
throw new UriParserSemanticException("Illegal value of $top option!", e,
UriParserSemanticException.MessageKeys.TEST);
}
- context.contextUriInfo.setSystemQueryOption(inlineCountOption);
- } else if (option.name.equals("$count")) {
- // todo create CountOption
+ context.contextUriInfo.setSystemQueryOption(topOption);
+ } else if (option.name.equals(SystemQueryOptionKind.COUNT.toString())) {
CountOptionImpl inlineCountOption = new CountOptionImpl();
inlineCountOption.setName(option.name);
inlineCountOption.setText(option.value);
@@ -254,6 +266,9 @@ public class Parser {
UriParserSemanticException.MessageKeys.TEST);
}
context.contextUriInfo.setSystemQueryOption(inlineCountOption);
+ } else {
+ throw new UriParserSyntaxException("Unknown system query option!",
+ UriParserSyntaxException.MessageKeys.TEST);
}
}
}
@@ -272,6 +287,11 @@ public class Parser {
return null;
}
+ private boolean isFormatSyntaxValid(RawUri.QueryOption option) {
+ final int index = option.value.indexOf('/');
+ return index > 0 && index < option.value.length() - 1 && index == option.value.lastIndexOf('/');
+ }
+
private ParserRuleContext parseRule(final String input, final ParserEntryRules entryPoint)
throws UriParserSyntaxException {
UriParserParser parser = null;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5f4d0507/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
index 0238a20..423c685 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
@@ -19,6 +19,7 @@
package org.apache.olingo.server.core.uri.antlr;
import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.core.Encoder;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfoKind;
@@ -1106,13 +1107,13 @@ public class TestFullResourcePath {
public void runEsNameKeyCast() throws Exception {
/*
* testUri.runEx("ESTwoPrim(1)/com.sap.odata.test1.ETBase(1)")
- * .isExSemantic(0);
+ * .isExSemantic(UriParserSemanticException.MessageKeys.TEST);
*
* testUri.runEx("ESTwoPrim/com.sap.odata.test1.ETBase(1)/com.sap.odata.test1.ETTwoBase(1)")
- * .isExSemantic(0);
+ * .isExSemantic(UriParserSemanticException.MessageKeys.TEST);
*
* testUri.runEx("ESBase/com.sap.odata.test1.ETTwoPrim(1)")
- * .isExSemantic(0);
+ * .isExSemantic(UriParserSemanticException.MessageKeys.TEST);
*/
testUri.run("ESTwoPrim(1)/com.sap.odata.test1.ETBase")
@@ -2513,6 +2514,9 @@ public class TestFullResourcePath {
.isKind(UriInfoKind.resource).goPath()
.isEntitySet("ESKeyNav")
.isTopText("-3");
+
+ testUri.runEx("ESKeyNav?$top=undefined").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESKeyNav?$top=").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
}
@Test
@@ -2533,6 +2537,14 @@ public class TestFullResourcePath {
testUri.run("ESKeyNav(1)?$format=Test_all_valid_signsSpecified_for_format_signs%26-._~$@%27/Aa123%26-._~$@%27")
.isKind(UriInfoKind.resource).goPath()
.isFormatText("Test_all_valid_signsSpecified_for_format_signs&-._~$@'/Aa123&-._~$@'");
+ testUri.run("ESKeyNav(1)?$format=" + HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8)
+ .isKind(UriInfoKind.resource).goPath()
+ .isFormatText(HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8);
+ testUri.runEx("ESKeyNav(1)?$format=noSlash").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESKeyNav(1)?$format=slashAtEnd/").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESKeyNav(1)?$format=/startsWithSlash").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESKeyNav(1)?$format=two/Slashes/tooMuch").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESKeyNav(1)?$format=").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
}
@Test
@@ -2544,6 +2556,8 @@ public class TestFullResourcePath {
testUri.run("ESAllPrim?$count=false")
.isKind(UriInfoKind.resource).goPath()
.isInlineCountText("false");
+ testUri.runEx("ESAllPrim?$count=undefined").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESAllPrim?$count=").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
}
@Test
@@ -2558,17 +2572,23 @@ public class TestFullResourcePath {
testUri.run("ESAllPrim?$skip=-3")
.isKind(UriInfoKind.resource).goPath()
.isSkipText("-3");
+ testUri.runEx("ESAllPrim?$skip=F").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
+ testUri.runEx("ESAllPrim?$skip=").isExSemantic(UriParserSemanticException.MessageKeys.TEST);
}
@Test
public void skiptoken() throws Exception {
-
testUri.run("ESAllPrim?$skiptoken=foo")
.isKind(UriInfoKind.resource).goPath()
.isSkipTokenText("foo");
}
@Test
+ public void notExistingSystemQueryOption() throws Exception {
+ testUri.runEx("ESAllPrim?$wrong=error").isExSyntax(UriParserSyntaxException.MessageKeys.TEST);
+ }
+
+ @Test
public void misc() throws Exception {
testUri.run("")
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5f4d0507/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
index 3b8ccb9..eff346f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
@@ -62,7 +62,7 @@ public class UriValidatorTest {
private static final String URI_NAV_ENTITY_SET = "/ESKeyNav/NavPropertyETKeyNavMany";
private static final String QO_FILTER = "$filter='1' eq '1'";
- private static final String QO_FORMAT = "$format=bla";
+ private static final String QO_FORMAT = "$format=bla/bla";
private static final String QO_EXPAND = "$expand=*";
private static final String QO_ID = "$id=Products(0)";
private static final String QO_COUNT = "$count=true";
@@ -381,7 +381,7 @@ public class UriValidatorTest {
}
uris.add(uri);
}
- return uris.toArray(new String[0]);
+ return uris.toArray(new String[uris.size()]);
}
private void parseAndValidate(final String uri, final HttpMethod method)