diff --git a/spec/security.js b/spec/security.js index 00eb1318..1261414b 100644 --- a/spec/security.js +++ b/spec/security.js @@ -167,6 +167,7 @@ describe('security issues', function() { TestClass.prototype.aMethod = function() { return 'returnValue'; }; + TestClass.prototype.nested = new TestClass(); beforeEach(function() { handlebarsEnv.resetLoggedPropertyAccesses(); @@ -177,17 +178,25 @@ describe('security issues', function() { }); describe('control access to prototype methods via "allowedProtoMethods"', function() { - checkProtoMethodAccess({}); + checkProtoMethodAccess('{{aMethod}}', {}); describe('in compat mode', function() { - checkProtoMethodAccess({ compat: true }); + checkProtoMethodAccess('{{aMethod}}', { compat: true }); }); - function checkProtoMethodAccess(compileOptions) { + describe('GH-1858: for nested object', function() { + checkProtoMethodAccess('{{nested.aMethod}}', {}); + + describe('in compat mode', function() { + checkProtoMethodAccess('{{nested.aMethod}}', { compat: true }); + }); + }); + + function checkProtoMethodAccess(template, compileOptions) { it('should be prohibited by default and log a warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); @@ -199,12 +208,12 @@ describe('security issues', function() { it('should only log the warning once', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); @@ -216,7 +225,7 @@ describe('security issues', function() { it('can be allowed, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -232,7 +241,7 @@ describe('security issues', function() { it('can be turned on by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -246,7 +255,7 @@ describe('security issues', function() { it('can be turned off by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -258,7 +267,7 @@ describe('security issues', function() { }); it('can be turned off, if turned on by default', function() { - expectTemplate('{{aMethod}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -292,21 +301,33 @@ describe('security issues', function() { }); describe('control access to prototype non-methods via "allowedProtoProperties" and "allowProtoPropertiesByDefault', function() { - checkProtoPropertyAccess({}); + checkProtoPropertyAccess('{{aProperty}}', {}); describe('in compat-mode', function() { - checkProtoPropertyAccess({ compat: true }); + checkProtoPropertyAccess('{{aProperty}}', { compat: true }); }); describe('in strict-mode', function() { - checkProtoPropertyAccess({ strict: true }); + checkProtoPropertyAccess('{{aProperty}}', { strict: true }); }); - function checkProtoPropertyAccess(compileOptions) { + describe('GH-1858: for nested object', function() { + checkProtoPropertyAccess('{{nested.aProperty}}', {}); + + describe('in compat-mode', function() { + checkProtoPropertyAccess('{{nested.aProperty}}', { compat: true }); + }); + + describe('in strict-mode', function() { + checkProtoPropertyAccess('{{nested.aProperty}}', { strict: true }); + }); + }); + + function checkProtoPropertyAccess(template, compileOptions) { it('should be prohibited by default and log a warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aProperty}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); @@ -318,7 +339,7 @@ describe('security issues', function() { it('can be explicitly prohibited by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aProperty}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -332,7 +353,7 @@ describe('security issues', function() { it('can be turned on, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aProperty}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -348,7 +369,7 @@ describe('security issues', function() { it('can be turned on by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); - expectTemplate('{{aProperty}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ @@ -360,7 +381,7 @@ describe('security issues', function() { }); it('can be turned off, if turned on by default', function() { - expectTemplate('{{aProperty}}') + expectTemplate(template) .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({