@@ -8,6 +8,8 @@ internal class TextParser
8
8
{
9
9
private static char NumberDecimalSeparator = '.' ;
10
10
11
+ private static char [ ] EscapeCharacters = new [ ] { '\\ ' , 'a' , 'b' , 'f' , 'n' , 'r' , 't' , 'v' } ;
12
+
11
13
// These aliases are supposed to simply the where clause and make it more human readable
12
14
// As an addition it is compatible with the OData.Filter specification
13
15
private static readonly Dictionary < string , TokenId > _predefinedAliases = new Dictionary < string , TokenId >
@@ -48,9 +50,21 @@ private void SetTextPos(int pos)
48
50
49
51
private void NextChar ( )
50
52
{
51
- if ( _textPos < _textLen ) _textPos ++ ;
53
+ if ( _textPos < _textLen )
54
+ {
55
+ _textPos ++ ;
56
+ }
52
57
_ch = _textPos < _textLen ? _text [ _textPos ] : '\0 ' ;
53
58
}
59
+ public char PeekNextChar ( )
60
+ {
61
+ if ( _textPos + 1 < _textLen )
62
+ {
63
+ return _text [ _textPos + 1 ] ;
64
+ }
65
+
66
+ return '\0 ' ;
67
+ }
54
68
55
69
public void NextToken ( )
56
70
{
@@ -252,29 +266,42 @@ public void NextToken()
252
266
253
267
case '"' :
254
268
case '\' ' :
269
+ bool balanced = false ;
255
270
char quote = _ch ;
256
- do
271
+
272
+ NextChar ( ) ;
273
+
274
+ while ( _textPos < _textLen && _ch != quote )
257
275
{
258
- bool escaped ;
276
+ char next = PeekNextChar ( ) ;
259
277
260
- do
278
+ if ( _ch == ' \\ ' )
261
279
{
262
- escaped = false ;
263
- NextChar ( ) ;
280
+ if ( EscapeCharacters . Contains ( next ) )
281
+ {
282
+ NextChar ( ) ;
283
+ }
264
284
265
- if ( _ch == '\\ ' )
285
+ if ( next == '" ' )
266
286
{
267
- escaped = true ;
268
- if ( _textPos < _textLen ) NextChar ( ) ;
287
+ NextChar ( ) ;
269
288
}
270
289
}
271
- while ( _textPos < _textLen && ( _ch != quote || escaped ) ) ;
272
-
273
- if ( _textPos == _textLen )
274
- throw ParseError ( _textPos , Res . UnterminatedStringLiteral ) ;
275
290
276
291
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 ( ) ;
278
305
279
306
tokenId = TokenId . StringLiteral ;
280
307
break ;
@@ -422,10 +449,9 @@ private static Exception ParseError(int pos, string format, params object[] args
422
449
return new ParseException ( string . Format ( CultureInfo . CurrentCulture , format , args ) , pos ) ;
423
450
}
424
451
425
- private static TokenId GetAliasedTokenId ( TokenId t , string alias )
452
+ private static TokenId GetAliasedTokenId ( TokenId tokenId , string alias )
426
453
{
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 ;
429
455
}
430
456
431
457
private static bool IsHexChar ( char c )
0 commit comments