From c3bef2ca79290c0fb09cc9d4633accf8a552ff83 Mon Sep 17 00:00:00 2001 From: David Greenspan Date: Tue, 12 May 2015 15:14:30 -0700 Subject: [PATCH] Better #each argument validation And another failing test for #let (argument validation) --- packages/spacebars-compiler/codegen.js | 12 ++++++++++-- packages/spacebars-compiler/compile_tests.js | 8 ++++++++ packages/spacebars-compiler/templatetag.js | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/spacebars-compiler/codegen.js b/packages/spacebars-compiler/codegen.js index b9ef9909a3..894e72f929 100644 --- a/packages/spacebars-compiler/codegen.js +++ b/packages/spacebars-compiler/codegen.js @@ -104,11 +104,19 @@ _.extend(CodeGen.prototype, { } if (args.length === 3) { // checks for {{#each person in people}} case - if (args[1][0] !== "PATH" || args[1][1][0] !== "in") { + var inArg = args[1]; + if (! (inArg[0] === "PATH" && inArg[1].length === 1 && + inArg[1][0] === 'in')) { + // inArg doesn't look like ['PATH',['in']] throw new Error("Missing 'in' operator of #each. " + eachUsage); } // split out the variable name and sequence arguments - var variable = args[0][1][0];// XXX take name as a string ignoring tag + var variableArg = args[0]; + if (! (variableArg[0] === "PATH" && variableArg[1].length === 1 && + variableArg[1][0].replace(/\./g, ''))) { + throw new Error("Bad variable name in #each"); + } + var variable = variableArg[1][0]; dataCode = 'function () { return { _sequence: Spacebars.call(' + self.codeGenPath(args[2][1]) + '), _variable: "' + variable + '" }; }'; diff --git a/packages/spacebars-compiler/compile_tests.js b/packages/spacebars-compiler/compile_tests.js index 9acf1c915e..fb1d661498 100644 --- a/packages/spacebars-compiler/compile_tests.js +++ b/packages/spacebars-compiler/compile_tests.js @@ -57,6 +57,7 @@ Tinytest.add("spacebars-compiler - compiler errors", function (test) { return e.message; } test.fail("Didn't throw an error: " + input); + return ''; }; var assertStartsWith = function (a, b) { @@ -92,4 +93,11 @@ Tinytest.add("spacebars-compiler - compiler errors", function (test) { 'asdf', '{{!foo}}', '{{!foo}} '], function (badFrag) { isError(badFrag, "Unexpected HTML close tag"); }); + + isError("{{#let myHelper}}{{/let}}", "Incorrect form of #let"); + isError("{{#each foo on bar}}{{/each}}", "Missing 'in' operator"); + isError("{{#each foo in.in bar}}{{/each}}", "Missing 'in' operator"); + isError("{{#each foo.bar in baz}}{{/each}}", "Bad variable name in #each"); + isError("{{#each ../foo in baz}}{{/each}}", "Bad variable name in #each"); + isError("{{#each 3 in baz}}{{/each}}", "Bad variable name in #each"); }); diff --git a/packages/spacebars-compiler/templatetag.js b/packages/spacebars-compiler/templatetag.js index 05278a5306..bd27ec7298 100644 --- a/packages/spacebars-compiler/templatetag.js +++ b/packages/spacebars-compiler/templatetag.js @@ -462,7 +462,8 @@ var validateTag = function (ttag, scanner) { if (ttag.type === 'INCLUSION' || ttag.type === 'BLOCKOPEN') { var args = ttag.args; - if (args.length > 1 && args[0].length === 2 && args[0][0] !== 'PATH') { + if (args.length > 1 && args[0].length === 2 && args[0][0] !== 'PATH' && + ttag.path[0] !== 'each') { // we have a positional argument that is not a PATH followed by // other arguments scanner.fatal("First argument must be a function, to be called on the rest of the arguments; found " + args[0][0]);