diff --git a/modules/@angular/compiler/src/expression_parser/parser.ts b/modules/@angular/compiler/src/expression_parser/parser.ts index 4bbc4a400e..cc1c7888a9 100644 --- a/modules/@angular/compiler/src/expression_parser/parser.ts +++ b/modules/@angular/compiler/src/expression_parser/parser.ts @@ -43,8 +43,8 @@ export class Parser { input: string, location: any, interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG): ASTWithSource { this._checkNoInterpolation(input, location, interpolationConfig); - var tokens = this._lexer.tokenize(this._stripComments(input)); - var ast = new _ParseAST(input, location, tokens, true, this.errors).parseChain(); + const tokens = this._lexer.tokenize(this._stripComments(input)); + const ast = new _ParseAST(input, location, tokens, true, this.errors).parseChain(); return new ASTWithSource(ast, input, location, this.errors); } @@ -155,15 +155,15 @@ export class Parser { } private _stripComments(input: string): string { - let i = this._commentStart(input); + const i = this._commentStart(input); return isPresent(i) ? input.substring(0, i).trim() : input; } private _commentStart(input: string): number { var outerQuote: number = null; - for (var i = 0; i < input.length - 1; i++) { - let char = StringWrapper.charCodeAt(input, i); - let nextChar = StringWrapper.charCodeAt(input, i + 1); + for (let i = 0; i < input.length - 1; i++) { + const char = StringWrapper.charCodeAt(input, i); + const nextChar = StringWrapper.charCodeAt(input, i + 1); if (char === chars.$SLASH && nextChar == chars.$SLASH && isBlank(outerQuote)) return i; diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts index 31223f9767..8e4ed27b43 100644 --- a/modules/@angular/compiler/src/template_parser/template_parser.ts +++ b/modules/@angular/compiler/src/template_parser/template_parser.ts @@ -12,7 +12,7 @@ import {Console, MAX_INTERPOLATION_VALUES} from '../../core_private'; import {ListWrapper, StringMapWrapper, SetWrapper,} from '../facade/collection'; import {RegExpWrapper, isPresent, isBlank} from '../facade/lang'; import {BaseException} from '../facade/exceptions'; -import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from '../expression_parser/ast'; +import {EmptyExpr, AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from '../expression_parser/ast'; import {Parser} from '../expression_parser/parser'; import {CompileDirectiveMetadata, CompilePipeMetadata, CompileTokenMetadata, removeIdentifierDuplicates,} from '../compile_metadata'; import {HtmlParser, ParseTreeResult} from '../html_parser/html_parser'; @@ -209,7 +209,7 @@ class TemplateParseVisitor implements html.Visitor { } private _reportParserErors(errors: ParserError[], sourceSpan: ParseSourceSpan) { - for (let error of errors) { + for (const error of errors) { this._reportError(error.message, sourceSpan); } } @@ -234,9 +234,16 @@ class TemplateParseVisitor implements html.Visitor { private _parseAction(value: string, sourceSpan: ParseSourceSpan): ASTWithSource { const sourceInfo = sourceSpan.start.toString(); + try { const ast = this._exprParser.parseAction(value, sourceInfo, this._interpolationConfig); - if (ast) this._reportParserErors(ast.errors, sourceSpan); + if (ast) { + this._reportParserErors(ast.errors, sourceSpan); + } + if (!ast || ast.ast instanceof EmptyExpr) { + this._reportError(`Empty expressions are not allowed`, sourceSpan); + return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo); + } this._checkPipes(ast, sourceSpan); return ast; } catch (e) { diff --git a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts index 0075ee7f9c..7e4be2c9a9 100644 --- a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts +++ b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts @@ -328,8 +328,18 @@ export function main() { describe('events', () => { it('should parse bound events with a target', () => { - expect(humanizeTplAst(parse('