Skip to content

Commit 30956c2

Browse files
committed
fix($compile): get $$observe listeners array as own property
Prevent accidentally treating a builtin function from Object.prototype as the binding object, and thus preventing the compiler from throwing when using attribute binding names which match a property of the Object prototype. Closes angular#9343
1 parent a1648a7 commit 30956c2

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/ng/compile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
929929
*/
930930
$observe: function(key, fn) {
931931
var attrs = this,
932-
$$observers = (attrs.$$observers || (attrs.$$observers = {})),
932+
$$observers = (attrs.$$observers || (attrs.$$observers = Object.create(null))),
933933
listeners = ($$observers[key] || ($$observers[key] = []));
934934

935935
listeners.push(fn);

test/ng/compileSpec.js

+28
Original file line numberDiff line numberDiff line change
@@ -3124,6 +3124,34 @@ describe('$compile', function() {
31243124
}));
31253125

31263126

3127+
it('should be able to bind attribute names which are present in Object.prototype', function() {
3128+
module(function() {
3129+
directive('inProtoAttr', valueFn({
3130+
scope: {
3131+
'constructor': '@',
3132+
// Spidermonkey extension, may be obsolete in the future
3133+
'watch': '=',
3134+
'unwatch': '&'
3135+
}
3136+
}));
3137+
});
3138+
inject(function($rootScope) {
3139+
expect(function() {
3140+
compile('<div in-proto-attr constructor="hello, world" watch="[]" ' +
3141+
'unwatch="value = !value"></div>');
3142+
}).not.toThrow();
3143+
var isolateScope = element.isolateScope();
3144+
3145+
expect(typeof isolateScope.constructor).toBe('string');
3146+
expect(isArray(isolateScope.watch)).toBe(true);
3147+
expect(typeof isolateScope.unwatch).toBe('function');
3148+
expect($rootScope.value).toBeUndefined();
3149+
isolateScope.unwatch();
3150+
expect($rootScope.value).toBe(true);
3151+
});
3152+
});
3153+
3154+
31273155
describe('bind-once', function () {
31283156

31293157
function countWatches(scope) {

0 commit comments

Comments
 (0)