fix($parse): a chain of field accessors should use a single getterFn

This commit is contained in:
Jason Bedard
2014-12-05 22:00:11 -08:00
committed by Lucas Galfaso
parent 69f69db1e0
commit c90ad96808
2 changed files with 21 additions and 7 deletions

View File

@@ -362,6 +362,8 @@ Parser.prototype = {
primary = this.arrayDeclaration();
} else if (this.expect('{')) {
primary = this.object();
} else if (this.peek().identifier && this.peek().text in CONSTANTS) {
primary = CONSTANTS[this.consume().text];
} else if (this.peek().identifier) {
primary = this.identifier();
} else if (this.peek().constant) {
@@ -464,7 +466,7 @@ Parser.prototype = {
id += this.consume().text + this.consume().text;
}
return CONSTANTS[id] || getterFn(id, this.options, this.text);
return getterFn(id, this.options, this.text);
},
constant: function() {
@@ -654,17 +656,16 @@ Parser.prototype = {
},
fieldAccess: function(object) {
var expression = this.text;
var field = this.consume().text;
var getter = getterFn(field, this.options, expression);
var getter = this.identifier();
return extend(function $parseFieldAccess(scope, locals, self) {
return getter(self || object(scope, locals));
var o = self || object(scope, locals);
return (o == null) ? undefined : getter(o);
}, {
assign: function(scope, value, locals) {
var o = object(scope, locals);
if (!o) object.assign(scope, o = {});
return setter(o, field, value, expression);
return getter.assign(o, value);
}
});
},

View File

@@ -771,7 +771,7 @@ describe('parser', function() {
scope.$eval('{}.toString.constructor.a = 1');
}).toThrowMinErr(
'$parse', 'isecfn','Referencing Function in Angular expressions is disallowed! ' +
'Expression: {}.toString.constructor.a = 1');
'Expression: toString.constructor.a');
expect(function() {
scope.$eval('{}.toString["constructor"]["constructor"] = 1');
@@ -1835,6 +1835,19 @@ describe('parser', function() {
$rootScope.fn = function() {};
expect($rootScope.$eval('foo + "bar" + fn()')).toBe('bar');
}));
it('should treat properties named null/undefined as normal properties', inject(function($rootScope) {
expect($rootScope.$eval("a.null.undefined.b", {a:{null:{undefined:{b: 1}}}})).toBe(1);
}));
it('should not allow overriding null/undefined keywords', inject(function($rootScope) {
expect($rootScope.$eval('null.a', {null: {a: 42}})).toBeUndefined();
}));
it('should allow accessing null/undefined properties on `this`', inject(function($rootScope) {
$rootScope.null = {a: 42};
expect($rootScope.$eval('this.null.a')).toBe(42);
}));
});
});
});