mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-06 09:01:31 +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(), {
|
var OPERATORS = extend(createMap(), {
|
||||||
/* jshint bitwise : false */
|
/* jshint bitwise : false */
|
||||||
'null':function(){return null;},
|
|
||||||
'true':function(){return true;},
|
|
||||||
'false':function(){return false;},
|
|
||||||
undefined:noop,
|
|
||||||
'+':function(self, locals, a,b){
|
'+':function(self, locals, a,b){
|
||||||
a=a(self, locals); b=b(self, locals);
|
a=a(self, locals); b=b(self, locals);
|
||||||
if (isDefined(a)) {
|
if (isDefined(a)) {
|
||||||
@@ -305,30 +314,11 @@ Lexer.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.tokens.push({
|
||||||
var token = {
|
|
||||||
index: start,
|
index: start,
|
||||||
text: ident
|
text: ident,
|
||||||
};
|
fn: CONSTANTS[ident] || getterFn(ident, this.options, expression)
|
||||||
|
});
|
||||||
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);
|
|
||||||
|
|
||||||
if (methodName) {
|
if (methodName) {
|
||||||
this.tokens.push({
|
this.tokens.push({
|
||||||
@@ -397,6 +387,7 @@ var Parser = function (lexer, $filter, options) {
|
|||||||
Parser.ZERO = extend(function () {
|
Parser.ZERO = extend(function () {
|
||||||
return 0;
|
return 0;
|
||||||
}, {
|
}, {
|
||||||
|
sharedGetter: true,
|
||||||
constant: true
|
constant: true
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -935,9 +926,14 @@ function getterFn(path, options, fullExp) {
|
|||||||
var evaledFnGetter = new Function('s', 'l', code); // s=scope, l=locals
|
var evaledFnGetter = new Function('s', 'l', code); // s=scope, l=locals
|
||||||
/* jshint +W054 */
|
/* jshint +W054 */
|
||||||
evaledFnGetter.toString = valueFn(code);
|
evaledFnGetter.toString = valueFn(code);
|
||||||
|
evaledFnGetter.assign = function(self, value) {
|
||||||
|
return setter(self, path, value, path);
|
||||||
|
};
|
||||||
|
|
||||||
fn = evaledFnGetter;
|
fn = evaledFnGetter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn.sharedGetter = true;
|
||||||
getterFnCache[path] = fn;
|
getterFnCache[path] = fn;
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
@@ -1004,6 +1000,21 @@ function $ParseProvider() {
|
|||||||
this.$get = ['$filter', '$sniffer', function($filter, $sniffer) {
|
this.$get = ['$filter', '$sniffer', function($filter, $sniffer) {
|
||||||
$parseOptions.csp = $sniffer.csp;
|
$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) {
|
return function $parse(exp, interceptorFn) {
|
||||||
var parsedExpression, oneTime, cacheKey;
|
var parsedExpression, oneTime, cacheKey;
|
||||||
|
|
||||||
@@ -1026,6 +1037,9 @@ function $ParseProvider() {
|
|||||||
if (parsedExpression.constant) {
|
if (parsedExpression.constant) {
|
||||||
parsedExpression.$$watchDelegate = constantWatchDelegate;
|
parsedExpression.$$watchDelegate = constantWatchDelegate;
|
||||||
} else if (oneTime) {
|
} 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 ?
|
parsedExpression.$$watchDelegate = parsedExpression.literal ?
|
||||||
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
|
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ describe('parser', function() {
|
|||||||
scope.$eval('a.toString.constructor = 1', scope);
|
scope.$eval('a.toString.constructor = 1', scope);
|
||||||
}).toThrowMinErr(
|
}).toThrowMinErr(
|
||||||
'$parse', 'isecfn', 'Referencing Function in Angular expressions is disallowed! ' +
|
'$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() {
|
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');
|
scope.$eval('hasOwnProperty.constructor.prototype.valueOf = 1');
|
||||||
}).toThrowMinErr(
|
}).toThrowMinErr(
|
||||||
'$parse', 'isecfn', 'Referencing Function in Angular expressions is disallowed! ' +
|
'$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() {
|
it('should disallow passing the Function object as a parameter: E03', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user