backup
This commit is contained in:
+1
-1
@@ -60,7 +60,7 @@ module.exports = {
|
||||
},
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 6,
|
||||
ecmaVersion: 2018,
|
||||
ecmaFeatures: {}
|
||||
}
|
||||
};
|
||||
|
||||
+27
-4
@@ -165,6 +165,29 @@ module.exports = function(grunt) {
|
||||
}
|
||||
}
|
||||
},
|
||||
karma: {
|
||||
options: {
|
||||
configFile: 'karma.conf.js'
|
||||
},
|
||||
saucelabs: {
|
||||
build: process.env.TRAVIS_JOB_ID || 'non-travis',
|
||||
configFile: 'karma-setup/default/karma.conf.js',
|
||||
...require('./karma-setup/shared/saucelabs'),
|
||||
singleRun: true
|
||||
},
|
||||
default: {
|
||||
browsers: [],
|
||||
configFile: 'karma-setup/default/karma.conf.js',
|
||||
singleRun: false,
|
||||
autoWatch: true
|
||||
},
|
||||
amd: {
|
||||
configFile: 'karma-setup/requirejs/karma.conf.js',
|
||||
browsers: [],
|
||||
singleRun: false,
|
||||
autoWatch: true
|
||||
}
|
||||
},
|
||||
'saucelabs-mocha': {
|
||||
all: {
|
||||
options: {
|
||||
@@ -178,8 +201,8 @@ module.exports = function(grunt) {
|
||||
browsers: [
|
||||
{ browserName: 'chrome' },
|
||||
{ browserName: 'firefox', platform: 'Linux' },
|
||||
// {browserName: 'safari', version: 9, platform: 'OS X 10.11'},
|
||||
// {browserName: 'safari', version: 8, platform: 'OS X 10.10'},
|
||||
{ browserName: 'safari', version: 9, platform: 'OS X 10.11' },
|
||||
{ browserName: 'safari', version: 8, platform: 'OS X 10.10' },
|
||||
{
|
||||
browserName: 'internet explorer',
|
||||
version: 11,
|
||||
@@ -238,7 +261,7 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-babel');
|
||||
grunt.loadNpmTasks('grunt-bg-shell');
|
||||
grunt.loadNpmTasks('@knappi/grunt-saucelabs');
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
grunt.loadNpmTasks('grunt-webpack');
|
||||
|
||||
grunt.task.loadTasks('tasks');
|
||||
@@ -268,7 +291,7 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('bench', ['metrics']);
|
||||
|
||||
if (process.env.SAUCE_ACCESS_KEY) {
|
||||
grunt.registerTask('sauce', ['concat:tests', 'connect', 'saucelabs-mocha']);
|
||||
grunt.registerTask('sauce', ['karma:saucelabs']);
|
||||
} else {
|
||||
grunt.registerTask('sauce', []);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
const files = require('../shared/default-files');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
...require('../shared/default-config'),
|
||||
files: [...files('dist/handlebars.js'), 'spec/*.js']
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
...require('../shared/default-config'),
|
||||
...require('../shared/saucelabs'),
|
||||
files: [
|
||||
'../../node_modules/sinon/pkg/sinon.js',
|
||||
'../../node_modules/chai/chai.js',
|
||||
'../../node_modules/dirty-chai/lib/dirty-chai.js',
|
||||
'../../node_modules/mocha/mocha.js',
|
||||
'../../spec/karma-includes/browser-context.js',
|
||||
'../../spec/karma-includes/mocha.js',
|
||||
'../../spec/vendor/json2.js',
|
||||
'../../spec/env/common.js',
|
||||
{ pattern: '../../spec/*.js', included: false }
|
||||
]
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
frameworks: ['mocha'],
|
||||
// concurrency: we have no concurrency set, because this seems to let Karma hang after the first batch
|
||||
// of browsers have finished their tests.
|
||||
reporters: ['dots']
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = function files(...additionalFiles) {
|
||||
return [
|
||||
'node_modules/sinon/pkg/sinon.js',
|
||||
'node_modules/chai/chai.js',
|
||||
'node_modules/dirty-chai/lib/dirty-chai.js',
|
||||
'node_modules/mocha/mocha.js',
|
||||
...additionalFiles,
|
||||
'spec/browser-setup/browser-context.js',
|
||||
'spec/browser-setup/mocha.js',
|
||||
'spec/vendor/json2.js',
|
||||
'spec/env/common.js'
|
||||
];
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
// Example set of browsers to run on Sauce Labs
|
||||
// Check out https://saucelabs.com/platforms for all browser/platform combos
|
||||
const customLaunchers = {
|
||||
sl_chrome: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'chrome'
|
||||
},
|
||||
sl_firefox: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'firefox',
|
||||
platform: 'Linux'
|
||||
},
|
||||
sl_safari_9: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'safari',
|
||||
version: 9,
|
||||
platform: 'OS X 10.11'
|
||||
},
|
||||
sl_safari_8: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'safari',
|
||||
version: 8,
|
||||
platform: 'OS X 10.10'
|
||||
},
|
||||
sl_ie_10: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'internet explorer',
|
||||
version: 10,
|
||||
platform: 'Windows 8'
|
||||
},
|
||||
sl_ie_11: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'internet explorer',
|
||||
platform: 'Windows 8.1',
|
||||
version: '11'
|
||||
}
|
||||
};
|
||||
|
||||
const browsers = Object.keys(customLaunchers);
|
||||
|
||||
module.exports = {
|
||||
customLaunchers,
|
||||
browsers,
|
||||
sauceLabs: {
|
||||
testName: 'handlebars-unit-tests'
|
||||
}
|
||||
};
|
||||
Generated
+905
-626
File diff suppressed because it is too large
Load Diff
@@ -58,9 +58,13 @@
|
||||
"grunt-contrib-requirejs": "^1",
|
||||
"grunt-contrib-uglify": "^1",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
"grunt-karma": "^4.0.0",
|
||||
"grunt-webpack": "^1.0.8",
|
||||
"husky": "^3.1.0",
|
||||
"jison": "~0.3.0",
|
||||
"karma": "^5.0.5",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-sauce-launcher": "^4.1.4",
|
||||
"lint-staged": "^9.5.0",
|
||||
"mocha": "^5",
|
||||
"mock-stdin": "^0.3.0",
|
||||
|
||||
+1
-2
@@ -112,8 +112,7 @@
|
||||
failedTests.push({
|
||||
name: test.title,
|
||||
result: false,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
message: err.message, stack: err.stack,
|
||||
titles: flattenTitles(test)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
window.CompilerContext = {
|
||||
compile: function(template, options) {
|
||||
var templateSpec = handlebarsEnv.precompile(template, options);
|
||||
return handlebarsEnv.template(safeEval(templateSpec));
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
return handlebarsEnv.compile(template, options);
|
||||
}
|
||||
};
|
||||
|
||||
function safeEval(templateSpec) {
|
||||
try {
|
||||
var ret;
|
||||
// eslint-disable-next-line no-eval
|
||||
eval('ret = ' + templateSpec);
|
||||
return ret;
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(templateSpec);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
window.expect = chai.expect;
|
||||
mocha.setup('bdd');
|
||||
@@ -0,0 +1,21 @@
|
||||
/* global requirejs */
|
||||
|
||||
var tests = [];
|
||||
|
||||
requirejs.config({
|
||||
// Karma serves files from '/base'
|
||||
baseUrl: '/base/src',
|
||||
|
||||
paths: {
|
||||
handlebars: '/dist/handlebars.amd',
|
||||
tests: '/tmp/tests'
|
||||
},
|
||||
|
||||
shim: {},
|
||||
|
||||
// ask Require.js to load these files (all our tests)
|
||||
deps: ['handlebars', tests],
|
||||
|
||||
// start test run, once Require.js is done
|
||||
callback: window.__karma__.start
|
||||
});
|
||||
+32
-35
@@ -1,4 +1,15 @@
|
||||
describe('security issues', function() {
|
||||
var consoleErrorFake = null;
|
||||
|
||||
beforeEach(function() {
|
||||
consoleErrorFake = sinon.fake();
|
||||
sinon.replace(console, 'error', consoleErrorFake);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
|
||||
it('should not allow constructors to be accessed', function() {
|
||||
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
||||
@@ -88,17 +99,15 @@ describe('security issues', function() {
|
||||
});
|
||||
|
||||
it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
||||
var functionCalls = [];
|
||||
var fakeFunction = sinon.fake();
|
||||
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
||||
template(
|
||||
{
|
||||
fn: function() {
|
||||
functionCalls.push('called');
|
||||
}
|
||||
fn: fakeFunction
|
||||
},
|
||||
{ allowCallsToHelperMissing: true }
|
||||
);
|
||||
equals(functionCalls.length, 1);
|
||||
expect(fakeFunction.calledOnce).to.be.true();
|
||||
});
|
||||
|
||||
it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
|
||||
@@ -185,20 +194,18 @@ describe('security issues', function() {
|
||||
|
||||
function checkProtoMethodAccess(compileOptions) {
|
||||
it('should be prohibited by default and log a warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.toCompileTo('');
|
||||
|
||||
expect(spy.calledOnce).to.be.true();
|
||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||
expect(consoleErrorFake.calledOnce).to.be.true();
|
||||
expect(consoleErrorFake.args[0][0]).to.match(
|
||||
/Handlebars: Access has been denied/
|
||||
);
|
||||
});
|
||||
|
||||
it('should only log the warning once', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -209,13 +216,13 @@ describe('security issues', function() {
|
||||
.withCompileOptions(compileOptions)
|
||||
.toCompileTo('');
|
||||
|
||||
expect(spy.calledOnce).to.be.true();
|
||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||
expect(consoleErrorFake.calledOnce).to.be.true();
|
||||
expect(consoleErrorFake.args[0][0]).to.match(
|
||||
/Handlebars: Access has been denied/
|
||||
);
|
||||
});
|
||||
|
||||
it('can be allowed, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -226,12 +233,10 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned on by default, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -240,12 +245,10 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned off by default, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -254,7 +257,7 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned off, if turned on by default', function() {
|
||||
@@ -300,20 +303,18 @@ describe('security issues', function() {
|
||||
|
||||
function checkProtoPropertyAccess(compileOptions) {
|
||||
it('should be prohibited by default and log a warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
.toCompileTo('');
|
||||
|
||||
expect(spy.calledOnce).to.be.true();
|
||||
expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
|
||||
expect(consoleErrorFake.calledOnce).to.be.true();
|
||||
expect(consoleErrorFake.args[0][0]).to.match(
|
||||
/Handlebars: Access has been denied/
|
||||
);
|
||||
});
|
||||
|
||||
it('can be explicitly prohibited by default, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -322,12 +323,10 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned on, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -338,12 +337,10 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned on by default, which disables the warning', function() {
|
||||
var spy = sinon.spy(console, 'error');
|
||||
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions(compileOptions)
|
||||
@@ -352,7 +349,7 @@ describe('security issues', function() {
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
|
||||
expect(spy.callCount).to.equal(0);
|
||||
expect(consoleErrorFake.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
it('can be turned off, if turned on by default', function() {
|
||||
|
||||
Reference in New Issue
Block a user