From 7efcbb6b407df77373ddb9bbd5f1dd7c81e3ce4f Mon Sep 17 00:00:00 2001 From: "Elf M. Sternberg" Date: Wed, 17 Apr 2013 22:05:15 -0700 Subject: [PATCH] Added check for maximum nesting depth. --- src/tumble.peg | 80 +++++++++++++++++++------------------ test/01_basics_mocha.coffee | 19 ++++++++- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/tumble.peg b/src/tumble.peg index 4319674..dc358a3 100644 --- a/src/tumble.peg +++ b/src/tumble.peg @@ -8,6 +8,7 @@ this.content = c this.stack = [c]; this.templates = {}; + this.depth = 0; } _.extend(Contexter.prototype, { @@ -35,6 +36,9 @@ once: function(obj, cb) { this.stack.unshift(obj); + if (this.stack.length > 10) { + throw new Error("Maxmimum nesting depth reached"); + } var r = cb(this); this.stack.shift(); return r; @@ -137,32 +141,6 @@ document } -document_part - = iterative / descendant / conditional / variable / text - - -text - = bs:(!tag c:. {return c})+ { - return text(bs); - } - - -variable "variable" - = t:tag_start rd { - return variable(t); - } - - -simple_part - = descendant / variable / conditional / text - - -conditional - = t:ifblock_tag_start ps:simple_part* n:ifblock_tag_end - &{ return (t == n) } - { return conditional(t, ps); } - - ifblock_tag_start "tag_start" = ld "if:" n:tagname rd { return n; } @@ -173,12 +151,6 @@ ifblock_tag_end { return n; } -descendant - = t:blockblock_tag_start ps:simple_part* n:blockblock_tag_end - &{ return (t == n) } - { return descendant(t, ps); } - - blockblock_tag_start = ld "block:" n:tagname rd { return n; } @@ -189,13 +161,6 @@ blockblock_tag_end { return n; } -iterative - = t:loopblock_tag_start ps:simple_part* n:loopblock_tag_end - &{ return (t == n) } - { - return iterative(t, ps); - } - loopblock_tag_start "tag_start" = ld "many:" n:tagname rd { return n; } @@ -234,6 +199,43 @@ eol / "\r" / "\u2028" / "\u2029" + + +text + = bs:(!tag c:. {return c})+ { + return text(bs); + } + + +variable "variable" + = t:tag_start rd { + return variable(t); + } +document_part + = iterative / descendant / conditional / variable / text + + +simple_part + = descendant / variable / conditional / text + + +conditional + = t:ifblock_tag_start ps:simple_part* n:ifblock_tag_end + &{ return (t == n) } + { return conditional(t, ps); } + + +descendant + = t:blockblock_tag_start ps:simple_part* n:blockblock_tag_end + &{ return (t == n) } + { return descendant(t, ps); } + + +iterative + = t:loopblock_tag_start ps:simple_part* n:loopblock_tag_end + &{ return (t == n) } + { return iterative(t, ps); } + diff --git a/test/01_basics_mocha.coffee b/test/01_basics_mocha.coffee index 512e9a8..01bc7ad 100644 --- a/test/01_basics_mocha.coffee +++ b/test/01_basics_mocha.coffee @@ -2,6 +2,7 @@ chai = require 'chai' assert = chai.assert expect = chai.expect should = chai.should() +util = require 'util' tumble = require('../lib/tumble').parse; @@ -90,5 +91,21 @@ describe "Basic Functionality", -> for data in test_data do (data) -> it "should work with #{data.description}", -> - r = tumble(data.input)(data.data) + r = tumble(data.input) + r = r(data.data) r.should.equal data.output + +describe "Check for recursion", -> + data = { + 'input': '{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{block:a}{a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}{/block:a}', + 'output': '', + 'data': {'a': {'a': {'a': {'a': {'a': {'a': {'a': {'a': {'a': {'a': {'a': {'a': 'b'}}}}}}}}}}}}, + 'description': "descent error" + } + do (data) -> + it "should catch an exception", -> + try + r = tumble(data.input)(data.data) + assert.ok false, "It did not throw the exception" + catch err + assert.ok true, "Recursion depth exeception thrown."