fix($parse): validate assignment lval in parser phase
The parser always threw an error in the case of an invalid left-value assignment but it was an unhelpful: ``` Cannot set property 'undefined' of undefined ``` This commit provides a more meaningful error message, so it is not a breaking change. Closes #15234
This commit is contained in:
committed by
Peter Bacon Darwin
parent
faf0c3e4c1
commit
a02c8863f9
+4
-3
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user