Skip to content

Commit 3e2d147

Browse files
authored
fix: STRF-10175 Allow only strings passed to partial and block helpers (#226)
1 parent 6dd11cb commit 3e2d147

5 files changed

Lines changed: 64 additions & 11 deletions

File tree

helpers/block.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
'use strict';
22

3+
const utils = require('./3p/utils');
4+
const common = require('./lib/common.js');
5+
36
const factory = globals => {
47
return function(name) {
8+
name = common.unwrapIfSafeString(globals.handlebars, name);
9+
if (!utils.isString(name)) {
10+
globals.getLogger().info("Non-string passed to block helper");
11+
return '';
12+
}
513
const options = arguments[arguments.length - 1];
614

715
/* Look for partial by name. */

helpers/partial.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
'use strict';
22

3+
const utils = require('./3p/utils');
4+
const common = require('./lib/common.js');
5+
36
const factory = globals => {
47
return function(name) {
8+
name = common.unwrapIfSafeString(globals.handlebars, name);
9+
if (!utils.isString(name)) {
10+
globals.getLogger().info("Non-string passed to partial helper");
11+
return '';
12+
}
513
const options = arguments[arguments.length - 1];
614
globals.handlebars.registerPartial(name, options.fn);
715
};

index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class HandlebarsRenderer {
6565
getThemeSettings: this.getThemeSettings.bind(this),
6666
getTranslator: this.getTranslator.bind(this),
6767
getContent: this.getContent.bind(this),
68+
getLogger: this.getLogger.bind(this),
6869
storage: {}, // global storage used by helpers to keep state
6970
resourceHints: []
7071
};
@@ -168,6 +169,15 @@ class HandlebarsRenderer {
168169
return this._contentRegions;
169170
};
170171

172+
/**
173+
* Get logger provided to the library
174+
*
175+
* @param {Object} logger
176+
*/
177+
getLogger() {
178+
return this.logger;
179+
}
180+
171181
/**
172182
* Add templates to the active set of partials. The templates can either be raw
173183
* template strings, or the result coming from the preProcessor function.

spec/helpers/block.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const lab = exports.lab = Lab.script();
44
const describe = lab.experiment;
55
const expect = Code.expect;
66
const it = lab.it;
7-
const render = require('../spec-helpers').render;
7+
const { render } = require('../spec-helpers');
88

99
describe('partial and block helpers', function () {
1010
it('should insert partial into the corresponding block', function (done) {
@@ -46,4 +46,32 @@ describe('partial and block helpers', function () {
4646
done();
4747
});
4848
});
49+
50+
it('should successfully render template', function (done) {
51+
const templateContent = "some-content";
52+
const templates = {
53+
"layout/base": templateContent,
54+
template: `{{#JSONparse '{"layout/base":{}}'}}{{#partial this}}{{/partial}}{{/JSONparse}}{{>layout/base}}`,
55+
};
56+
render('template', {}, {}, {}, templates).then(result => {
57+
expect(result).to.be.equal(templateContent);
58+
done();
59+
});
60+
});
61+
62+
it('should successfully render template with context', function (done) {
63+
const templateContent = "Hello, world!";
64+
const templates = {
65+
template: `{{#partial "base"}}Hello, world!{{/partial}}{{#partial notPartials}}{{/partial}}{{> base}}`,
66+
};
67+
const context = {
68+
notPartials: {
69+
"base": {}
70+
}
71+
}
72+
render('template', context, {}, {}, templates).then(result => {
73+
expect(result).to.be.equal(templateContent);
74+
done();
75+
});
76+
});
4977
});

spec/helpers/getObject.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,15 @@ describe('getObject helper', function () {
3333
], done);
3434
});
3535

36-
// uncomment when 3rd-party version is replaced
37-
// it('does not access prototype props', function (done) {
38-
// context.obj.__proto__ = {x: 'yz'};
39-
// runTestCases([
40-
// {
41-
// input: `{{#with (getObject "x" obj)}}{{x}}{{/with}}`,
42-
// output: ``,
43-
// },
44-
// ], done);
45-
// });
36+
it('does not access prototype props', function (done) {
37+
context.obj.__proto__ = {x: 'yz'};
38+
runTestCases([
39+
{
40+
input: `{{#with (getObject "x" obj)}}{{x}}{{/with}}`,
41+
output: ``,
42+
},
43+
], done);
44+
});
4645

4746
it('accepts SafeString paths', (done) => {
4847
runTestCases([

0 commit comments

Comments
 (0)