Skip to content

Commit b375010

Browse files
committed
fix($parse): Allow property names that collide with native object properties
I.e. constructor, toString, or watch on FF (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch) + optimize parser a bit to not create getter function for operators
1 parent b348347 commit b375010

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

src/service/parse.js

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ function lex(text){
146146
function readIdent() {
147147
var ident = "",
148148
start = index,
149-
fn, lastDot, peekIndex, methodName, getter;
149+
lastDot, peekIndex, methodName;
150150

151151
while (index < text.length) {
152152
var ch = text.charAt(index);
@@ -178,23 +178,26 @@ function lex(text){
178178
}
179179
}
180180

181-
fn = OPERATORS[ident];
182-
getter = getterFn(ident);
183-
tokens.push({
181+
182+
var token = {
184183
index:start,
185-
text:ident,
186-
json: fn,
187-
fn:fn||extend(
188-
function(self, locals) {
189-
return (getter(self, locals));
190-
},
191-
{
192-
assign:function(self, value){
193-
return setter(self, ident, value);
194-
}
195-
}
196-
)
197-
});
184+
text:ident
185+
};
186+
187+
if (OPERATORS.hasOwnProperty(ident)) {
188+
token.fn = token.json = OPERATORS[ident];
189+
} else {
190+
var getter = getterFn(ident);
191+
token.fn = extend(function(self, locals) {
192+
return (getter(self, locals));
193+
}, {
194+
assign: function(self, value) {
195+
return setter(self, ident, value);
196+
}
197+
});
198+
}
199+
200+
tokens.push(token);
198201

199202
if (methodName) {
200203
tokens.push({
@@ -701,10 +704,11 @@ function getter(obj, path, bindFnToScope) {
701704
var getterFnCache = {};
702705

703706
function getterFn(path) {
704-
var fn = getterFnCache[path];
705-
if (fn) return fn;
707+
if (getterFnCache.hasOwnProperty(path)) {
708+
return getterFnCache[path];
709+
}
706710

707-
var code = 'var l, fn, p;\n';
711+
var fn, code = 'var l, fn, p;\n';
708712
forEach(path.split('.'), function(key, index) {
709713
code += 'if(!s) return s;\n' +
710714
'l=s;\n' +

test/service/parseSpec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,17 @@ describe('parser', function() {
227227
expect(scope.$eval("x.y.z", scope)).not.toBeDefined();
228228
});
229229

230+
it('should support property names that colide with native object properties', function() {
231+
// regression
232+
scope.watch = 1;
233+
scope.constructor = 2;
234+
scope.toString = 3;
235+
236+
expect(scope.$eval('watch', scope)).toBe(1);
237+
expect(scope.$eval('constructor', scope)).toBe(2);
238+
expect(scope.$eval('toString', scope)).toBe(3);
239+
});
240+
230241
it('should evaluate grouped expressions', function() {
231242
expect(scope.$eval("(1+2)*3")).toEqual((1+2)*3);
232243
});

0 commit comments

Comments
 (0)