(path, options, fullExp)
| 11197 | } |
| 11198 | |
| 11199 | function getterFn(path, options, fullExp) { |
| 11200 | var expensiveChecks = options.expensiveChecks; |
| 11201 | var getterFnCache = (expensiveChecks ? getterFnCacheExpensive : getterFnCacheDefault); |
| 11202 | // Check whether the cache has this getter already. |
| 11203 | // We can use hasOwnProperty directly on the cache because we ensure, |
| 11204 | // see below, that the cache never stores a path called 'hasOwnProperty' |
| 11205 | if (getterFnCache.hasOwnProperty(path)) { |
| 11206 | return getterFnCache[path]; |
| 11207 | } |
| 11208 | |
| 11209 | var pathKeys = path.split('.'), |
| 11210 | pathKeysLength = pathKeys.length, |
| 11211 | fn; |
| 11212 | |
| 11213 | // http://jsperf.com/angularjs-parse-getter/6 |
| 11214 | if (options.csp) { |
| 11215 | if (pathKeysLength < 6) { |
| 11216 | fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, |
| 11217 | options); |
| 11218 | } else { |
| 11219 | fn = function(scope, locals) { |
| 11220 | var i = 0, val; |
| 11221 | do { |
| 11222 | val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], |
| 11223 | pathKeys[i++], fullExp, options)(scope, locals); |
| 11224 | |
| 11225 | locals = undefined; // clear after first iteration |
| 11226 | scope = val; |
| 11227 | } while (i < pathKeysLength); |
| 11228 | return val; |
| 11229 | }; |
| 11230 | } |
| 11231 | } else { |
| 11232 | var code = 'var p;\n'; |
| 11233 | if (expensiveChecks) { |
| 11234 | code += 's = eso(s, fe);\nl = eso(l, fe);\n'; |
| 11235 | } |
| 11236 | var needsEnsureSafeObject = expensiveChecks; |
| 11237 | forEach(pathKeys, function(key, index) { |
| 11238 | ensureSafeMemberName(key, fullExp); |
| 11239 | var lookupJs = (index |
| 11240 | // we simply dereference 's' on any .dot notation |
| 11241 | ? 's' |
| 11242 | // but if we are first then we check locals first, and if so read it first |
| 11243 | : '((l&&l.hasOwnProperty("' + key + '"))?l:s)') + '["' + key + '"]'; |
| 11244 | var wrapWithEso = expensiveChecks || isPossiblyDangerousMemberName(key); |
| 11245 | if (wrapWithEso) { |
| 11246 | lookupJs = 'eso(' + lookupJs + ', fe)'; |
| 11247 | needsEnsureSafeObject = true; |
| 11248 | } |
| 11249 | code += 'if(s == null) return undefined;\n' + |
| 11250 | 's=' + lookupJs + ';\n'; |
| 11251 | if (options.unwrapPromises) { |
| 11252 | code += 'if (s && s.then) {\n' + |
| 11253 | ' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' + |
| 11254 | ' if (!("$$v" in s)) {\n' + |
| 11255 | ' p=s;\n' + |
| 11256 | ' p.$$v = undefined;\n' + |
no test coverage detected