diff --git a/src/ng/parse.js b/src/ng/parse.js index 28abe69e9a1d..1bd9b0e4d6db 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -894,16 +894,20 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { if (pathVal == null) return pathVal; pathVal = pathVal[key0]; - if (pathVal == null) return key1 ? undefined : pathVal; + if (!key1) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key1]; - if (pathVal == null) return key2 ? undefined : pathVal; + if (!key2) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key2]; - if (pathVal == null) return key3 ? undefined : pathVal; + if (!key3) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key3]; - if (pathVal == null) return key4 ? undefined : pathVal; + if (!key4) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key4]; return pathVal; @@ -924,8 +928,9 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { } pathVal = pathVal.$$v; } - if (pathVal == null) return key1 ? undefined : pathVal; + if (!key1) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key1]; if (pathVal && pathVal.then) { promiseWarning(fullExp); @@ -936,8 +941,9 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { } pathVal = pathVal.$$v; } - if (pathVal == null) return key2 ? undefined : pathVal; + if (!key2) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key2]; if (pathVal && pathVal.then) { promiseWarning(fullExp); @@ -948,8 +954,9 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { } pathVal = pathVal.$$v; } - if (pathVal == null) return key3 ? undefined : pathVal; + if (!key3) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key3]; if (pathVal && pathVal.then) { promiseWarning(fullExp); @@ -960,8 +967,9 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { } pathVal = pathVal.$$v; } - if (pathVal == null) return key4 ? undefined : pathVal; + if (!key4) return pathVal; + if (pathVal == null) return undefined; pathVal = pathVal[key4]; if (pathVal && pathVal.then) { promiseWarning(fullExp); diff --git a/test/ng/parseSpec.js b/test/ng/parseSpec.js index 4599c0330fd6..7d4642d1f960 100644 --- a/test/ng/parseSpec.js +++ b/test/ng/parseSpec.js @@ -204,13 +204,24 @@ describe('parser', function() { describe('csp: ' + cspEnabled + ", unwrapPromises: " + unwrapPromisesEnabled, function() { - beforeEach(module(function ($parseProvider) { + var originalSecurityPolicy; + + + beforeEach(function() { + originalSecurityPolicy = window.document.securityPolicy; + window.document.securityPolicy = {isActive : cspEnabled}; + }); + + afterEach(function() { + window.document.securityPolicy = originalSecurityPolicy; + }); + + beforeEach(module(function ($parseProvider, $provide) { $parseProvider.unwrapPromises(unwrapPromisesEnabled); })); - beforeEach(inject(function ($rootScope, $sniffer) { + beforeEach(inject(function ($rootScope) { scope = $rootScope; - $sniffer.csp = cspEnabled; })); it('should parse expressions', function() { @@ -344,6 +355,25 @@ describe('parser', function() { expect(scope.$eval("a.b.c.d.e.f.g.h.i.j.k.l.m.n", scope)).toBe('nooo!'); }); + forEach([2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 42, 99], function(pathLength) { + it('should resolve nested paths of length ' + pathLength, function() { + // Create a nested object {x2: {x3: {x4: ... {x[n]: 42} ... }}}. + var obj = 42; + for (var i = pathLength; i >= 2; i--) { + var newObj = {}; + newObj['x' + i] = obj; + obj = newObj; + } + // Assign to x1 and build path 'x1.x2.x3. ... .x[n]' to access the final value. + scope.x1 = obj; + var path = 'x1'; + for (var i = 2; i <= pathLength; i++) { + path += '.x' + i; + } + expect(scope.$eval(path)).toBe(42); + }); + }); + it('should be forgiving', function() { scope.a = {b: 23}; expect(scope.$eval('b')).toBeUndefined(); @@ -1069,6 +1099,17 @@ describe('parser', function() { var $log; var PROMISE_WARNING_REGEXP = /\[\$parse\] Promise found in the expression `[^`]+`. Automatic unwrapping of promises in Angular expressions is deprecated\./; + var originalSecurityPolicy; + + + beforeEach(function() { + originalSecurityPolicy = window.document.securityPolicy; + window.document.securityPolicy = {isActive : cspEnabled}; + }); + + afterEach(function() { + window.document.securityPolicy = originalSecurityPolicy; + }); beforeEach(module(function($parseProvider) { $parseProvider.unwrapPromises(true); @@ -1142,15 +1183,27 @@ describe('parser', function() { describe('csp ' + cspEnabled, function() { + var originalSecurityPolicy; + + + beforeEach(function() { + originalSecurityPolicy = window.document.securityPolicy; + window.document.securityPolicy = {isActive : cspEnabled}; + }); + + afterEach(function() { + window.document.securityPolicy = originalSecurityPolicy; + }); + + beforeEach(module(function($parseProvider) { $parseProvider.unwrapPromises(true); $parseProvider.logPromiseWarnings(false); })); - beforeEach(inject(function($rootScope, $sniffer, $q) { + beforeEach(inject(function($rootScope, $q) { scope = $rootScope; - $sniffer.csp = cspEnabled; q = $q; deferred = q.defer();