Added check for maximum nesting depth.
This commit is contained in:
parent
dd332e3354
commit
7efcbb6b40
|
@ -8,6 +8,7 @@
|
||||||
this.content = c
|
this.content = c
|
||||||
this.stack = [c];
|
this.stack = [c];
|
||||||
this.templates = {};
|
this.templates = {};
|
||||||
|
this.depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_.extend(Contexter.prototype, {
|
_.extend(Contexter.prototype, {
|
||||||
|
@ -35,6 +36,9 @@
|
||||||
|
|
||||||
once: function(obj, cb) {
|
once: function(obj, cb) {
|
||||||
this.stack.unshift(obj);
|
this.stack.unshift(obj);
|
||||||
|
if (this.stack.length > 10) {
|
||||||
|
throw new Error("Maxmimum nesting depth reached");
|
||||||
|
}
|
||||||
var r = cb(this);
|
var r = cb(this);
|
||||||
this.stack.shift();
|
this.stack.shift();
|
||||||
return r;
|
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"
|
ifblock_tag_start "tag_start"
|
||||||
= ld "if:" n:tagname rd
|
= ld "if:" n:tagname rd
|
||||||
{ return n; }
|
{ return n; }
|
||||||
|
@ -173,12 +151,6 @@ ifblock_tag_end
|
||||||
{ return n; }
|
{ return n; }
|
||||||
|
|
||||||
|
|
||||||
descendant
|
|
||||||
= t:blockblock_tag_start ps:simple_part* n:blockblock_tag_end
|
|
||||||
&{ return (t == n) }
|
|
||||||
{ return descendant(t, ps); }
|
|
||||||
|
|
||||||
|
|
||||||
blockblock_tag_start
|
blockblock_tag_start
|
||||||
= ld "block:" n:tagname rd
|
= ld "block:" n:tagname rd
|
||||||
{ return n; }
|
{ return n; }
|
||||||
|
@ -189,13 +161,6 @@ blockblock_tag_end
|
||||||
{ return n; }
|
{ 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"
|
loopblock_tag_start "tag_start"
|
||||||
= ld "many:" n:tagname rd
|
= ld "many:" n:tagname rd
|
||||||
{ return n; }
|
{ return n; }
|
||||||
|
@ -234,6 +199,43 @@ eol
|
||||||
/ "\r"
|
/ "\r"
|
||||||
/ "\u2028"
|
/ "\u2028"
|
||||||
/ "\u2029"
|
/ "\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); }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ chai = require 'chai'
|
||||||
assert = chai.assert
|
assert = chai.assert
|
||||||
expect = chai.expect
|
expect = chai.expect
|
||||||
should = chai.should()
|
should = chai.should()
|
||||||
|
util = require 'util'
|
||||||
|
|
||||||
tumble = require('../lib/tumble').parse;
|
tumble = require('../lib/tumble').parse;
|
||||||
|
|
||||||
|
@ -90,5 +91,21 @@ describe "Basic Functionality", ->
|
||||||
for data in test_data
|
for data in test_data
|
||||||
do (data) ->
|
do (data) ->
|
||||||
it "should work with #{data.description}", ->
|
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
|
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."
|
||||||
|
|
Loading…
Reference in New Issue