@@ -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 ) {
2 commit comments
gkalpak commentedon Nov 7, 2014
I wonder if this should be documented as a breaking change.
I guess we neverwanted people to access DOM nodes or Window objects in the view, but I don't think it was mentioned anywhere as impossible.
caitp commentedon Nov 7, 2014
it should be documented, because every time we change this and add new restrictions people file bugs and get mad