From 41baceeece265b500df9b100f24b77654dcd7b50 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Sun, 9 Oct 2016 13:13:50 -0700 Subject: [PATCH] fix($parse): validate assignment lval in parser phase --- src/ng/parse.js | 7 ++++--- test/ng/parseSpec.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ng/parse.js b/src/ng/parse.js index b400ae964459..12682eaff889 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -338,6 +338,10 @@ AST.prototype = { assignment: function() { var result = this.ternary(); if (this.expect('=')) { + if (!isAssignable(result)) { + throw $parseMinErr('lval', 'Trying to assign a value to a non l-value'); + } + result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='}; } return result; @@ -1024,9 +1028,6 @@ ASTCompiler.prototype = { case AST.AssignmentExpression: right = this.nextId(); left = {}; - if (!isAssignable(ast.left)) { - throw $parseMinErr('lval', 'Trying to assign a value to a non l-value'); - } this.recurse(ast.left, undefined, left, function() { self.if_(self.notNull(left.context), function() { self.recurse(ast.right, right); diff --git a/test/ng/parseSpec.js b/test/ng/parseSpec.js index 79d49340da46..aca11301b177 100644 --- a/test/ng/parseSpec.js +++ b/test/ng/parseSpec.js @@ -2129,6 +2129,20 @@ describe('parser', function() { expect(scope.b).toEqual(234); }); + it('should throw with invalid left-val in assignments', function() { + expect(function() { scope.$eval("1 = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("{} = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("[] = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("true = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("(a=b) = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("(1<2) = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("(1+2) = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("!v = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("this = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("+v = 1"); }).toThrowMinErr('$parse', 'lval'); + expect(function() { scope.$eval("(1?v1:v2) = 1"); }).toThrowMinErr('$parse', 'lval'); + }); + it('should evaluate assignments in ternary operator', function() { scope.$eval('a = 1 ? 2 : 3'); expect(scope.a).toBe(2);