From fffb5a985f8ff7cd75f2c16b37b69f7ddd3ba9a0 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Wed, 23 Sep 2015 21:17:57 -0500 Subject: Fix iteration over undefined values Allow for iteration on undefined values, but special case undefined and null to prevent rendering errors when not running in strict mode. Fixes #1093 --- lib/handlebars/compiler/javascript-compiler.js | 5 +++-- lib/handlebars/helpers/each.js | 10 +++------- spec/regressions.js | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index d0f206c..bd48e9b 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -984,13 +984,14 @@ JavaScriptCompiler.prototype = { setupHelper: function(paramSize, name, blockHelper) { let params = [], paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); - let foundHelper = this.nameLookup('helpers', name, 'helper'); + let foundHelper = this.nameLookup('helpers', name, 'helper'), + callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : {}`); return { params: params, paramsInit: paramsInit, name: foundHelper, - callParams: [this.contextName(0)].concat(params) + callParams: [callContext].concat(params) }; }, diff --git a/lib/handlebars/helpers/each.js b/lib/handlebars/helpers/each.js index 9b1629b..fb11903 100644 --- a/lib/handlebars/helpers/each.js +++ b/lib/handlebars/helpers/each.js @@ -25,12 +25,6 @@ export default function(instance) { } function execIteration(field, index, last) { - // Don't iterate over undefined values since we can't execute blocks against them - // in non-strict (js) mode. - if (context[field] == null) { - return; - } - if (data) { data.key = field; data.index = index; @@ -51,7 +45,9 @@ export default function(instance) { if (context && typeof context === 'object') { if (isArray(context)) { for (let j = context.length; i < j; i++) { - execIteration(i, i, i === context.length - 1); + if (i in context) { + execIteration(i, i, i === context.length - 1); + } } } else { let priorKey; diff --git a/spec/regressions.js b/spec/regressions.js index cca126e..931fc4b 100644 --- a/spec/regressions.js +++ b/spec/regressions.js @@ -204,6 +204,24 @@ describe('Regressions', function() { shouldCompileTo('{{#each array}}{{@index}}{{.}}{{/each}}', {array: array}, '1foo3bar'); }); + it('GH-1093: Undefined helper context', function() { + var obj = {foo: undefined, bar: 'bat'}; + var helpers = { + helper: function() { + // It's valid to execute a block against an undefined context, but + // helpers can not do so, so we expect to have an empty object here; + for (var name in this) { + if (this.hasOwnProperty(name)) { + return 'found'; + } + } + return 'not'; + } + }; + + shouldCompileTo('{{#each obj}}{{{helper}}}{{.}}{{/each}}', [{obj: obj}, helpers], 'notfoundbat'); + }); + it('should support multiple levels of inline partials', function() { var string = '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}'; var partials = { -- cgit v1.1