Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit c90ad96

Browse files
jbedardlgalfaso
authored andcommitted
fix($parse): a chain of field accessors should use a single getterFn
1 parent 69f69db commit c90ad96

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

src/ng/parse.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ Parser.prototype = {
362362
primary = this.arrayDeclaration();
363363
} else if (this.expect('{')) {
364364
primary = this.object();
365+
} else if (this.peek().identifier && this.peek().text in CONSTANTS) {
366+
primary = CONSTANTS[this.consume().text];
365367
} else if (this.peek().identifier) {
366368
primary = this.identifier();
367369
} else if (this.peek().constant) {
@@ -464,7 +466,7 @@ Parser.prototype = {
464466
id += this.consume().text + this.consume().text;
465467
}
466468

467-
return CONSTANTS[id] || getterFn(id, this.options, this.text);
469+
return getterFn(id, this.options, this.text);
468470
},
469471

470472
constant: function() {
@@ -654,17 +656,16 @@ Parser.prototype = {
654656
},
655657

656658
fieldAccess: function(object) {
657-
var expression = this.text;
658-
var field = this.consume().text;
659-
var getter = getterFn(field, this.options, expression);
659+
var getter = this.identifier();
660660

661661
return extend(function $parseFieldAccess(scope, locals, self) {
662-
return getter(self || object(scope, locals));
662+
var o = self || object(scope, locals);
663+
return (o == null) ? undefined : getter(o);
663664
}, {
664665
assign: function(scope, value, locals) {
665666
var o = object(scope, locals);
666667
if (!o) object.assign(scope, o = {});
667-
return setter(o, field, value, expression);
668+
return getter.assign(o, value);
668669
}
669670
});
670671
},

test/ng/parseSpec.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ describe('parser', function() {
771771
scope.$eval('{}.toString.constructor.a = 1');
772772
}).toThrowMinErr(
773773
'$parse', 'isecfn','Referencing Function in Angular expressions is disallowed! ' +
774-
'Expression: {}.toString.constructor.a = 1');
774+
'Expression: toString.constructor.a');
775775

776776
expect(function() {
777777
scope.$eval('{}.toString["constructor"]["constructor"] = 1');
@@ -1835,6 +1835,19 @@ describe('parser', function() {
18351835
$rootScope.fn = function() {};
18361836
expect($rootScope.$eval('foo + "bar" + fn()')).toBe('bar');
18371837
}));
1838+
1839+
it('should treat properties named null/undefined as normal properties', inject(function($rootScope) {
1840+
expect($rootScope.$eval("a.null.undefined.b", {a:{null:{undefined:{b: 1}}}})).toBe(1);
1841+
}));
1842+
1843+
it('should not allow overriding null/undefined keywords', inject(function($rootScope) {
1844+
expect($rootScope.$eval('null.a', {null: {a: 42}})).toBeUndefined();
1845+
}));
1846+
1847+
it('should allow accessing null/undefined properties on `this`', inject(function($rootScope) {
1848+
$rootScope.null = {a: 42};
1849+
expect($rootScope.$eval('this.null.a')).toBe(42);
1850+
}));
18381851
});
18391852
});
18401853
});

0 commit comments

Comments
 (0)