mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-04 08:58:16 +08:00
@@ -80,12 +80,21 @@ function ensureSafeFunction(obj, fullExpression) {
|
||||
}
|
||||
}
|
||||
|
||||
//Keyword constants
|
||||
var CONSTANTS = createMap();
|
||||
forEach({
|
||||
'null': function() { return null; },
|
||||
'true': function() { return true; },
|
||||
'false': function() { return false; },
|
||||
'undefined': function() {}
|
||||
}, function(constantGetter, name) {
|
||||
constantGetter.constant = constantGetter.literal = constantGetter.sharedGetter = true;
|
||||
CONSTANTS[name] = constantGetter;
|
||||
});
|
||||
|
||||
//Operators - will be wrapped by binaryFn/unaryFn/assignment/filter
|
||||
var OPERATORS = extend(createMap(), {
|
||||
/* jshint bitwise : false */
|
||||
'null':function(){return null;},
|
||||
'true':function(){return true;},
|
||||
'false':function(){return false;},
|
||||
undefined:noop,
|
||||
'+':function(self, locals, a,b){
|
||||
a=a(self, locals); b=b(self, locals);
|
||||
if (isDefined(a)) {
|
||||
@@ -305,30 +314,11 @@ Lexer.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var token = {
|
||||
this.tokens.push({
|
||||
index: start,
|
||||
text: ident
|
||||
};
|
||||
|
||||
var fn = OPERATORS[ident];
|
||||
|
||||
if (fn) {
|
||||
token.fn = fn;
|
||||
token.constant = true;
|
||||
} else {
|
||||
var getter = getterFn(ident, this.options, expression);
|
||||
// TODO(perf): consider exposing the getter reference
|
||||
token.fn = extend(function $parsePathGetter(self, locals) {
|
||||
return getter(self, locals);
|
||||
}, {
|
||||
assign: function(self, value) {
|
||||
return setter(self, ident, value, expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.tokens.push(token);
|
||||
text: ident,
|
||||
fn: CONSTANTS[ident] || getterFn(ident, this.options, expression)
|
||||
});
|
||||
|
||||
if (methodName) {
|
||||
this.tokens.push({
|
||||
@@ -397,6 +387,7 @@ var Parser = function (lexer, $filter, options) {
|
||||
Parser.ZERO = extend(function () {
|
||||
return 0;
|
||||
}, {
|
||||
sharedGetter: true,
|
||||
constant: true
|
||||
});
|
||||
|
||||
@@ -935,9 +926,14 @@ function getterFn(path, options, fullExp) {
|
||||
var evaledFnGetter = new Function('s', 'l', code); // s=scope, l=locals
|
||||
/* jshint +W054 */
|
||||
evaledFnGetter.toString = valueFn(code);
|
||||
evaledFnGetter.assign = function(self, value) {
|
||||
return setter(self, path, value, path);
|
||||
};
|
||||
|
||||
fn = evaledFnGetter;
|
||||
}
|
||||
|
||||
fn.sharedGetter = true;
|
||||
getterFnCache[path] = fn;
|
||||
return fn;
|
||||
}
|
||||
@@ -1004,6 +1000,21 @@ function $ParseProvider() {
|
||||
this.$get = ['$filter', '$sniffer', function($filter, $sniffer) {
|
||||
$parseOptions.csp = $sniffer.csp;
|
||||
|
||||
function wrapSharedExpression(exp) {
|
||||
var wrapped = exp;
|
||||
|
||||
if (exp.sharedGetter) {
|
||||
wrapped = function $parseWrapper(self, locals) {
|
||||
return exp(self, locals);
|
||||
};
|
||||
wrapped.literal = exp.literal;
|
||||
wrapped.constant = exp.constant;
|
||||
wrapped.assign = exp.assign;
|
||||
}
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
return function $parse(exp, interceptorFn) {
|
||||
var parsedExpression, oneTime, cacheKey;
|
||||
|
||||
@@ -1026,6 +1037,9 @@ function $ParseProvider() {
|
||||
if (parsedExpression.constant) {
|
||||
parsedExpression.$$watchDelegate = constantWatchDelegate;
|
||||
} else if (oneTime) {
|
||||
//oneTime is not part of the exp passed to the Parser so we may have to
|
||||
//wrap the parsedExpression before adding a $$watchDelegate
|
||||
parsedExpression = wrapSharedExpression(parsedExpression);
|
||||
parsedExpression.$$watchDelegate = parsedExpression.literal ?
|
||||
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ describe('parser', function() {
|
||||
scope.$eval('a.toString.constructor = 1', scope);
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecfn', 'Referencing Function in Angular expressions is disallowed! ' +
|
||||
'Expression: a.toString.constructor = 1');
|
||||
'Expression: a.toString.constructor');
|
||||
});
|
||||
|
||||
it('should disallow traversing the Function object in a setter: E02', function() {
|
||||
@@ -733,7 +733,7 @@ describe('parser', function() {
|
||||
scope.$eval('hasOwnProperty.constructor.prototype.valueOf = 1');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecfn', 'Referencing Function in Angular expressions is disallowed! ' +
|
||||
'Expression: hasOwnProperty.constructor.prototype.valueOf = 1');
|
||||
'Expression: hasOwnProperty.constructor.prototype.valueOf');
|
||||
});
|
||||
|
||||
it('should disallow passing the Function object as a parameter: E03', function() {
|
||||
|
||||
Reference in New Issue
Block a user