diff --git a/lib/handlebars.js b/lib/handlebars.js index b6408bd3..5878fcad 100644 --- a/lib/handlebars.js +++ b/lib/handlebars.js @@ -20,6 +20,10 @@ Handlebars.Compiler = function(string) { this.comment = false; } +Handlebars.ParseError = function(message) { + this.message = message; +} + Handlebars.helperMissing = function(object, fn) { var ret = ""; @@ -88,13 +92,26 @@ Handlebars.Compiler.prototype = { return "context"; } - var parts = param.split("../"); - param = parts[parts.length - 1]; - depth = parts.length - 1; - parts = param.split("/"); + var parts = param.split("/"); + var readDepth = false; + var depth = 0; var paramExpr = ""; for (var i = 0; i < parts.length; i++) { - paramExpr += "['" + parts[i] + "']"; + switch(parts[i]) { + case "..": + if (readDepth) { + throw new Handlebars.ParseError("Cannot jump out of context after moving into a context."); + } else { + depth += 1; + } + break; + case ".": + throw new HandleBars.ParseError("'.' is not supported in path expressions.") + break; + default: + readDepth = true; + paramExpr += "['" + parts[i] + "']"; + } } if (depth > 0) { diff --git a/test/handlebars.js b/test/handlebars.js index 8e4c6c44..9cd6db13 100644 --- a/test/handlebars.js +++ b/test/handlebars.js @@ -31,6 +31,19 @@ test("nested paths", function() { "Goodbye beautiful world!", "Nested paths access nested objects"); }); +test("dumb nested paths", function() { + var string = "{{#goodbyes}}{{../name/../name}}{{/goodbyes}}"; + var caught = false; + try { + Handlebars.compile("{{#goodbyes}}{{../name/../name}}{{/goodbyes}}"); + } catch (e) { + if (e instanceof Handlebars.ParseError) { + caught = true; + } + } + equals(caught, true, "Jumping out of context (..) doesn't work after moving into context."); +}); + module("blocks"); test("array", function() {