mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($parse): fix CSP nested property evaluation, and issue that prevented its tests from failing
cspSafeGetterFn incorrectly returned undefined if any of its key parameters were undefined. This wasn't caught by the $parse unit tests because of a timing problem where $ParseProvider was reading the CSP flag before the tests manually set it, so the CSP property evaluation tests never ran. Add test that verifies evaluation of nested properties of multiple lengths. Closes #5591 Closes #5592
This commit is contained in:
parent
9569778f2f
commit
3b1a4fe0c8
2 changed files with 74 additions and 13 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue