@@ -852,7 +852,8 @@ function setter(obj, path, setValue, fullExp) {
852
852
return setValue ;
853
853
}
854
854
855
- var getterFnCache = createMap ( ) ;
855
+ var getterFnCacheDefault = createMap ( ) ;
856
+ var getterFnCacheExpensive = createMap ( ) ;
856
857
857
858
function isPossiblyDangerousMemberName ( name ) {
858
859
return name == 'constructor' ;
@@ -863,7 +864,7 @@ function isPossiblyDangerousMemberName(name) {
863
864
* - http://jsperf.com/angularjs-parse-getter/4
864
865
* - http://jsperf.com/path-evaluation-simplified/7
865
866
*/
866
- function cspSafeGetterFn ( key0 , key1 , key2 , key3 , key4 , fullExp ) {
867
+ function cspSafeGetterFn ( key0 , key1 , key2 , key3 , key4 , fullExp , expensiveChecks ) {
867
868
ensureSafeMemberName ( key0 , fullExp ) ;
868
869
ensureSafeMemberName ( key1 , fullExp ) ;
869
870
ensureSafeMemberName ( key2 , fullExp ) ;
@@ -872,11 +873,11 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp) {
872
873
var eso = function ( o ) {
873
874
return ensureSafeObject ( o , fullExp ) ;
874
875
} ;
875
- var eso0 = isPossiblyDangerousMemberName ( key0 ) ? eso : identity ;
876
- var eso1 = isPossiblyDangerousMemberName ( key1 ) ? eso : identity ;
877
- var eso2 = isPossiblyDangerousMemberName ( key2 ) ? eso : identity ;
878
- var eso3 = isPossiblyDangerousMemberName ( key3 ) ? eso : identity ;
879
- var eso4 = isPossiblyDangerousMemberName ( key4 ) ? eso : identity ;
876
+ var eso0 = ( expensiveChecks || isPossiblyDangerousMemberName ( key0 ) ) ? eso : identity ;
877
+ var eso1 = ( expensiveChecks || isPossiblyDangerousMemberName ( key1 ) ) ? eso : identity ;
878
+ var eso2 = ( expensiveChecks || isPossiblyDangerousMemberName ( key2 ) ) ? eso : identity ;
879
+ var eso3 = ( expensiveChecks || isPossiblyDangerousMemberName ( key3 ) ) ? eso : identity ;
880
+ var eso4 = ( expensiveChecks || isPossiblyDangerousMemberName ( key4 ) ) ? eso : identity ;
880
881
881
882
return function cspSafeGetter ( scope , locals ) {
882
883
var pathVal = ( locals && locals . hasOwnProperty ( key0 ) ) ? locals : scope ;
@@ -911,23 +912,25 @@ function getterFnWithEnsureSafeObject(fn, fullExpression) {
911
912
}
912
913
913
914
function getterFn ( path , options , fullExp ) {
915
+ var expensiveChecks = options . expensiveChecks ;
916
+ var getterFnCache = ( expensiveChecks ? getterFnCacheExpensive : getterFnCacheDefault ) ;
914
917
var fn = getterFnCache [ path ] ;
915
-
916
918
if ( fn ) return fn ;
917
919
920
+
918
921
var pathKeys = path . split ( '.' ) ,
919
922
pathKeysLength = pathKeys . length ;
920
923
921
924
// http://jsperf.com/angularjs-parse-getter/6
922
925
if ( options . csp ) {
923
926
if ( pathKeysLength < 6 ) {
924
- fn = cspSafeGetterFn ( pathKeys [ 0 ] , pathKeys [ 1 ] , pathKeys [ 2 ] , pathKeys [ 3 ] , pathKeys [ 4 ] , fullExp ) ;
927
+ fn = cspSafeGetterFn ( pathKeys [ 0 ] , pathKeys [ 1 ] , pathKeys [ 2 ] , pathKeys [ 3 ] , pathKeys [ 4 ] , fullExp , expensiveChecks ) ;
925
928
} else {
926
929
fn = function cspSafeGetter ( scope , locals ) {
927
930
var i = 0 , val ;
928
931
do {
929
932
val = cspSafeGetterFn ( pathKeys [ i ++ ] , pathKeys [ i ++ ] , pathKeys [ i ++ ] , pathKeys [ i ++ ] ,
930
- pathKeys [ i ++ ] , fullExp ) ( scope , locals ) ;
933
+ pathKeys [ i ++ ] , fullExp , expensiveChecks ) ( scope , locals ) ;
931
934
932
935
locals = undefined ; // clear after first iteration
933
936
scope = val ;
@@ -937,15 +940,18 @@ function getterFn(path, options, fullExp) {
937
940
}
938
941
} else {
939
942
var code = '' ;
940
- var needsEnsureSafeObject = false ;
943
+ if ( expensiveChecks ) {
944
+ code += 's = eso(s, fe);\nl = eso(l, fe);\n' ;
945
+ }
946
+ var needsEnsureSafeObject = expensiveChecks ;
941
947
forEach ( pathKeys , function ( key , index ) {
942
948
ensureSafeMemberName ( key , fullExp ) ;
943
949
var lookupJs = ( index
944
950
// we simply dereference 's' on any .dot notation
945
951
? 's'
946
952
// but if we are first then we check locals first, and if so read it first
947
953
: '((l&&l.hasOwnProperty("' + key + '"))?l:s)' ) + '.' + key ;
948
- if ( isPossiblyDangerousMemberName ( key ) ) {
954
+ if ( expensiveChecks || isPossiblyDangerousMemberName ( key ) ) {
949
955
lookupJs = 'eso(' + lookupJs + ', fe)' ;
950
956
needsEnsureSafeObject = true ;
951
957
}
@@ -1030,15 +1036,20 @@ function getValueOf(value) {
1030
1036
* service.
1031
1037
*/
1032
1038
function $ParseProvider ( ) {
1033
- var cache = createMap ( ) ;
1039
+ var cacheDefault = createMap ( ) ;
1040
+ var cacheExpensive = createMap ( ) ;
1034
1041
1035
- var $parseOptions = {
1036
- csp : false
1037
- } ;
1038
1042
1039
1043
1040
1044
this . $get = [ '$filter' , '$sniffer' , function ( $filter , $sniffer ) {
1041
- $parseOptions . csp = $sniffer . csp ;
1045
+ var $parseOptions = {
1046
+ csp : $sniffer . csp ,
1047
+ expensiveChecks : false
1048
+ } ,
1049
+ $parseOptionsExpensive = {
1050
+ csp : $sniffer . csp ,
1051
+ expensiveChecks : true
1052
+ } ;
1042
1053
1043
1054
function wrapSharedExpression ( exp ) {
1044
1055
var wrapped = exp ;
@@ -1055,13 +1066,14 @@ function $ParseProvider() {
1055
1066
return wrapped ;
1056
1067
}
1057
1068
1058
- return function $parse ( exp , interceptorFn ) {
1069
+ return function $parse ( exp , interceptorFn , expensiveChecks ) {
1059
1070
var parsedExpression , oneTime , cacheKey ;
1060
1071
1061
1072
switch ( typeof exp ) {
1062
1073
case 'string' :
1063
1074
cacheKey = exp = exp . trim ( ) ;
1064
1075
1076
+ var cache = ( expensiveChecks ? cacheExpensive : cacheDefault ) ;
1065
1077
parsedExpression = cache [ cacheKey ] ;
1066
1078
1067
1079
if ( ! parsedExpression ) {
@@ -1070,8 +1082,9 @@ function $ParseProvider() {
1070
1082
exp = exp . substring ( 2 ) ;
1071
1083
}
1072
1084
1073
- var lexer = new Lexer ( $parseOptions ) ;
1074
- var parser = new Parser ( lexer , $filter , $parseOptions ) ;
1085
+ var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions ;
1086
+ var lexer = new Lexer ( parseOptions ) ;
1087
+ var parser = new Parser ( lexer , $filter , parseOptions ) ;
1075
1088
parsedExpression = parser . parse ( exp ) ;
1076
1089
1077
1090
if ( parsedExpression . constant ) {
0 commit comments