@@ -8,6 +8,8 @@ internal class TextParser
88 {
99 private static char NumberDecimalSeparator = '.' ;
1010
11+ private static char [ ] EscapeCharacters = new [ ] { '\\ ' , 'a' , 'b' , 'f' , 'n' , 'r' , 't' , 'v' } ;
12+
1113 // These aliases are supposed to simply the where clause and make it more human readable
1214 // As an addition it is compatible with the OData.Filter specification
1315 private static readonly Dictionary < string , TokenId > _predefinedAliases = new Dictionary < string , TokenId >
@@ -48,9 +50,21 @@ private void SetTextPos(int pos)
4850
4951 private void NextChar ( )
5052 {
51- if ( _textPos < _textLen ) _textPos ++ ;
53+ if ( _textPos < _textLen )
54+ {
55+ _textPos ++ ;
56+ }
5257 _ch = _textPos < _textLen ? _text [ _textPos ] : '\0 ' ;
5358 }
59+ public char PeekNextChar ( )
60+ {
61+ if ( _textPos + 1 < _textLen )
62+ {
63+ return _text [ _textPos + 1 ] ;
64+ }
65+
66+ return '\0 ' ;
67+ }
5468
5569 public void NextToken ( )
5670 {
@@ -252,29 +266,42 @@ public void NextToken()
252266
253267 case '"' :
254268 case '\' ' :
269+ bool balanced = false ;
255270 char quote = _ch ;
256- do
271+
272+ NextChar ( ) ;
273+
274+ while ( _textPos < _textLen && _ch != quote )
257275 {
258- bool escaped ;
276+ char next = PeekNextChar ( ) ;
259277
260- do
278+ if ( _ch == ' \\ ' )
261279 {
262- escaped = false ;
263- NextChar ( ) ;
280+ if ( EscapeCharacters . Contains ( next ) )
281+ {
282+ NextChar ( ) ;
283+ }
264284
265- if ( _ch == '\\ ' )
285+ if ( next == '" ' )
266286 {
267- escaped = true ;
268- if ( _textPos < _textLen ) NextChar ( ) ;
287+ NextChar ( ) ;
269288 }
270289 }
271- while ( _textPos < _textLen && ( _ch != quote || escaped ) ) ;
272-
273- if ( _textPos == _textLen )
274- throw ParseError ( _textPos , Res . UnterminatedStringLiteral ) ;
275290
276291 NextChar ( ) ;
277- } while ( _ch == quote ) ;
292+
293+ if ( _ch == quote )
294+ {
295+ balanced = ! balanced ;
296+ }
297+ }
298+
299+ if ( _textPos == _textLen && ! balanced )
300+ {
301+ throw ParseError ( _textPos , Res . UnterminatedStringLiteral ) ;
302+ }
303+
304+ NextChar ( ) ;
278305
279306 tokenId = TokenId . StringLiteral ;
280307 break ;
@@ -422,10 +449,9 @@ private static Exception ParseError(int pos, string format, params object[] args
422449 return new ParseException ( string . Format ( CultureInfo . CurrentCulture , format , args ) , pos ) ;
423450 }
424451
425- private static TokenId GetAliasedTokenId ( TokenId t , string alias )
452+ private static TokenId GetAliasedTokenId ( TokenId tokenId , string alias )
426453 {
427- TokenId id ;
428- return t == TokenId . Identifier && _predefinedAliases . TryGetValue ( alias , out id ) ? id : t ;
454+ return tokenId == TokenId . Identifier && _predefinedAliases . TryGetValue ( alias , out TokenId id ) ? id : tokenId ;
429455 }
430456
431457 private static bool IsHexChar ( char c )
0 commit comments