Skip to content

Commit

Permalink
Fix context-stack when calling block-helpers on null values
Browse files Browse the repository at this point in the history
Fixes #1319

Original behaviour:
- When a block-helper was called on a null-context, an empty object was used
  as context instead. (#1093)
- The runtime verifies that whether the current context equals the
  last context and adds the current context to the stack, if it is not.
  This is done, so that inside a block-helper, the ".." path can be used
  to go back to the parent element.
- If the helper is called on a "null" element, the context was added, even
  though it shouldn't be, because the "null != {}"

Fix:
- The commit replaces "null" by the identifiable "container.nullContext"
  instead of "{}". "nullContext" is a sealed empty object.
- An additional check in the runtime verifies that the context is
  only added to the stack, if it is not the nullContext.
  • Loading branch information
nknapp committed Mar 9, 2017
1 parent b617375 commit 2468864
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/handlebars/compiler/javascript-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ JavaScriptCompiler.prototype = {
let params = [],
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
let foundHelper = this.nameLookup('helpers', name, 'helper'),
callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : {}`);
callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : container.nullContext`);

return {
params: params,
Expand Down
4 changes: 3 additions & 1 deletion lib/handlebars/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ export function template(templateSpec, env) {

return obj;
},
// An empty object to use as replacement for null-contexts
nullContext: Object.seal({}),

noop: env.VM.noop,
compilerInfo: templateSpec.compiler
Expand Down Expand Up @@ -187,7 +189,7 @@ export function template(templateSpec, env) {
export function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
function prog(context, options = {}) {
let currentDepths = depths;
if (depths && context != depths[0]) {
if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
currentDepths = [context].concat(depths);
}

Expand Down
16 changes: 16 additions & 0 deletions spec/regressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,20 @@ describe('Regressions', function() {

shouldCompileTo(string, { listOne: ['a'], listTwo: ['b']}, 'ab', '');
});

it('should allow hash with protected array names', function() {
var obj = {array: [1], name: 'John'};
var helpers = {
helpa: function(options) {
return options.hash.length;
}
};

shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo');
});

it('GH-1319: "unless" breaks when "each" value equals "null"', function() {
var string = '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}';
shouldCompileTo(string, { value: 'parent', list: [ null, 'a'] }, 'parent=parent parent=parent ', '');
});
});

0 comments on commit 2468864

Please sign in to comment.