From 03475605eb02c510b4464e9e1f93c464b3b3b8d1 Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Tue, 7 Oct 2014 15:11:42 +0200 Subject: [PATCH] catch for bad characters in server URI parsing Change-Id: I8bff20757e4cb0060d7b613e8d79f9580fc3a267 Signed-off-by: Christian Amend --- .../olingo/server/core/uri/antlr/UriLexer.g4 | 47 ++++++++++--------- .../olingo/server/core/uri/antlr/UriParser.g4 | 14 +++--- .../core/uri/antlr/TestFullResourcePath.java | 3 ++ 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriLexer.g4 b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriLexer.g4 index eee648602..bec817cb1 100644 --- a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriLexer.g4 +++ b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriLexer.g4 @@ -19,9 +19,9 @@ lexer grammar UriLexer; //;============================================================================== -// Mode "DEFAULT_MODE": Processes everything bevor the first '?' char -// On '?' the next mode "MODE_QUERY" is used -// The percent encoding rules a defined in RFC3986 ABNF rule "path-rootless" apply +// Mode "DEFAULT_MODE": Processes everything before the first '?' char. +// On '?' the next mode "MODE_QUERY" is used. +// The percent encoding rules are defined in RFC3986; ABNF rule "path-rootless" applies. //;============================================================================== QM : '?' -> pushMode(MODE_QUERY); //first query parameter AMP : '&' -> pushMode(MODE_QUERY); //more query parameters @@ -99,7 +99,7 @@ fragment DAY : '0' '1'..'9' | ('1'|'2') DIGIT | '3' ('0'|'1'); fragment MONTH : '0' ONE_TO_NINE | '1' ( '0' | '1' | '2' ); fragment YEAR : ('-')? ( '0' DIGIT DIGIT DIGIT | ONE_TO_NINE DIGIT DIGIT DIGIT ); -//tags start with $ +//tags starting with $ BATCH : '$batch'; ENTITY : '$entity'; METADATA : '$metadata'; @@ -116,15 +116,13 @@ TOP_I : '$top' -> type(TOP); SKIP_I : '$skip' -> type(SKIP); FILTER_I : '$filter' -> type(FILTER); ORDERBY_I: '$orderby' -> type(ORDERBY); -SELECT_I: '$select' -> type(SELECT); -EXPAND_I: '$expand' -> type(EXPAND); -LEVELS_I: '$levels' -> type(LEVELS); +SELECT_I : '$select' -> type(SELECT); +EXPAND_I : '$expand' -> type(EXPAND); +LEVELS_I : '$levels' -> type(LEVELS); MAX: 'max'; ROOT : '$root/'; - - //rest NULLVALUE : 'null'; @@ -188,7 +186,7 @@ MINUS :'-'; IT : '$it'; ITSLASH : '$it/'; -LEVELS : '$levels'; +LEVELS : '$levels'; CONTAINS_WORD : 'contains('; STARTSWITH_WORD : 'startswith('; @@ -237,13 +235,15 @@ LINK : '$link'; DELETED_LINK : '$deletedLink'; DELTA : '$delta'; -//ODI -ODATAIDENTIFIER : ODI_LEADINGCHARACTER (ODI_CHARACTER)*; +ODATAIDENTIFIER : ODI_LEADINGCHARACTER (ODI_CHARACTER)*; + +//handle characters that failed to match any other token +ERROR_CHARACTER : .; //;============================================================================== -// Mode "QUERY": Processes everything between the first '?' and the '#' char -// On '?' the next mode "FRAGMENT" is used -// The percent encoding rules a defined in RFC3986 ABNF rule "query" apply +// Mode "QUERY": Processes everything between the first '?' and the '#' char. +// On '?' the next mode "FRAGMENT" is used. +// The percent encoding rules are defined in RFC3986; ABNF rule "query" applies. mode MODE_QUERY; //;============================================================================== @@ -270,6 +270,9 @@ AT_Q : '@' -> pushMode(DEFAULT_MODE); CUSTOMNAME : ~[&=@$] ~[&=]* -> pushMode(MODE_SYSTEM_QUERY_REST); +//handle characters that failed to match any other token +ERROR_CHARACTER_q : .; + //;============================================================================== mode MODE_SYSTEM_QUERY_PCHAR; //;============================================================================== @@ -287,18 +290,19 @@ fragment UNRESERVED_sqp : ALPHA_sqp | DIGIT_sqp | '-' |'.' | '_' | '~'; fragment PCHAR : UNRESERVED_sqp | PCT_ENCODED_sqp | SUB_DELIMS_sqp | ':' | '@'; fragment PCHARSTART : UNRESERVED_sqp | PCT_ENCODED_sqp | '$' | /*'&' |*/ '\'' | OTHER_DELIMS_sqp | ':' | '@'; - ATOM : [Aa][Tt][Oo][Mm]; JSON : [Jj][Ss][Oo][Nn]; XML : [Xx][Mm][Ll]; PCHARS : PCHARSTART PCHAR*; - SLASH_sqp : '/' -> type(SLASH); EQ_sqp : '=' -> type(EQ); FRAGMENT_sqp : '#' -> type(FRAGMENT), pushMode(MODE_FRAGMENT); +//handle characters that failed to match any other token +ERROR_CHARACTER_sqp : .; + //;============================================================================== mode MODE_FRAGMENT; // Read the remaining characters of a URI queryparameter up to an & or # @@ -336,19 +340,18 @@ QUOTATION_MARK_sqc : '\u0022' | '%22'; SEARCHWORD : ('a'..'z'|'A'..'Z')+; SEARCHPHRASE : QUOTATION_MARK_sqc ~["]* QUOTATION_MARK_sqc -> popMode; - //;============================================================================== mode MODE_STRING; -// Read the remaining characters up to an ' character. -// An "'" character inside a string are expressed as double '' +// Reads the remaining characters up to an ' character. +// Any "'" characters inside a string are expressed as double "''". //;============================================================================== STRING_s : ('\'\'' | ~[\u0027] )* '\'' -> type(STRING), popMode; //;============================================================================== mode MODE_JSON_STRING; -// Read the remaining characters up to an " character. -// An "'" character inside a string are expressed excaped \" +// Reads the remaining characters up to an " character. +// Any """ characters inside a string are escaped with "\". //;============================================================================== STRING_IN_JSON : ('\\"' | ~[\u0022] )* ('"' | '%22') -> popMode; 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 404c04fc5..77929b297 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 @@ -20,16 +20,16 @@ grammar UriParser; //------------------------------------------------------------------------------ -// This grammer refers to the "odata-abnf-construction-rules.txt" Revision 517. +// This grammar refers to the "odata-abnf-construction-rules.txt" Revision 517. // URL: https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-construction-rules.txt?rev=517 -// While contructing this grammer we tried to keep it close to the ABNF. However this is not really possible -// in order to support +// While contructing this grammar we tried to keep it close to the ABNF. +// However this is not really possible in order to support // - percent decoding // - operator precedence -// - have context free grammar ( without out java snipples to add context) -// - generate the parser in diffend target languages -// Currently not supported +// - having a context free grammar ( without java snipplets to add context) +// - generating the parser in different target languages +// Currently not supported are // - $search // - geometry data // - json data in url @@ -54,7 +54,7 @@ metadataEOF : METADATA EOF; //;------------------------------------------------------------------------------ //; 1. Resource Path //;------------------------------------------------------------------------------ - + //resourcePathEOF : vlPS=pathSegments EOF; crossjoinEOF : CROSSJOIN OPEN WSP? vlODI+=odataIdentifier WSP? ( COMMA WSP? vlODI+=odataIdentifier WSP?)* CLOSE EOF; 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 1b3a335a6..21082165a 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 @@ -2638,6 +2638,9 @@ public class TestFullResourcePath { testUri.runEx("$entity/olingo.odata.test1.ETKeyNav/$ref") .isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT); + testUri.runEx("$wrong").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + testUri.runEx("", "$wrong").isExSyntax(UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION); + testUri.run("ESKeyNav") .isKind(UriInfoKind.resource) .goPath().first()