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)