From 5bcea6492f6d0fd39ba316fa3b241c50bb94de8d Mon Sep 17 00:00:00 2001 From: Pavel Jbanov Date: Wed, 5 Feb 2014 15:27:11 -0500 Subject: [PATCH] fix(parser): disallow filters in a chain and inside expressions --- bin/parser_generator_for_spec.dart | 4 +++- lib/core/parser/dynamic_parser_impl.dart | 18 ++++++++++++++---- test/core/parser/parser_spec.dart | 15 +++++++++------ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/bin/parser_generator_for_spec.dart b/bin/parser_generator_for_spec.dart index 5a3e612a8..dfa436cb7 100644 --- a/bin/parser_generator_for_spec.dart +++ b/bin/parser_generator_for_spec.dart @@ -225,6 +225,8 @@ main(arguments) { "1|nonexistent", "publicField", "_privateField", - "'World'|hello" + "'World'|hello", + "1;'World'|hello", + "'World'|hello;1" ]); } diff --git a/lib/core/parser/dynamic_parser_impl.dart b/lib/core/parser/dynamic_parser_impl.dart index 7657af40e..0b893ddcf 100644 --- a/lib/core/parser/dynamic_parser_impl.dart +++ b/lib/core/parser/dynamic_parser_impl.dart @@ -2,6 +2,7 @@ library angular.core.parser.dynamic_parser_impl; import 'package:angular/core/parser/parser.dart' show ParserBackend; import 'package:angular/core/parser/lexer.dart'; +import 'package:angular/core/parser/syntax.dart'; class DynamicParserImpl { static Token EOF = new Token(-1, null); @@ -18,14 +19,23 @@ class DynamicParserImpl { } parseChain() { - while (optional(';')); + bool isChain = false; + while (optional(';')) { + isChain = true; + } List expressions = []; while (index < tokens.length) { if (peek.text == ')' || peek.text == '}' || peek.text == ']') { error('Unconsumed token ${peek.text}'); } - expressions.add(parseFilter()); - while (optional(';')); + var expr = parseFilter(); + expressions.add(expr); + while (optional(';')) { + isChain = true; + } + if (isChain && expr is Filter) { + error('cannot have a filter in a chain'); + } } return (expressions.length == 1) ? expressions.first @@ -203,7 +213,7 @@ class DynamicParserImpl { parsePrimary() { if (optional('(')) { - var result = parseFilter(); + var result = parseExpression(); expect(')'); return result; } else if (optional('null') || optional('undefined')) { diff --git a/test/core/parser/parser_spec.dart b/test/core/parser/parser_spec.dart index 1763b7b96..e2db3e2fc 100644 --- a/test/core/parser/parser_spec.dart +++ b/test/core/parser/parser_spec.dart @@ -897,12 +897,6 @@ main() { expect(eval("1|increment:2", filters)).toEqual(3); }); - it('should evaluate grouped filters', () { - scope.name = 'MISKO'; - expect(scope.$eval('n = (name|lowercase)')).toEqual('misko'); - expect(scope.$eval('n')).toEqual('misko'); - }); - it('should parse filters', () { expect(() { scope.$eval("1|nonexistent"); @@ -930,6 +924,15 @@ main() { expect(expression.eval({}, newFilters)).toEqual('Hello, World!'); })); + + it('should not allow filters in a chain', () { + expect(() { + parser("1;'World'|hello"); + }).toThrow('cannot have a filter in a chain the end of the expression [1;\'World\'|hello]'); + expect(() { + parser("'World'|hello;1"); + }).toThrow('cannot have a filter in a chain at column 15 in [\'World\'|hello;1]'); + }); }); }); }