robfig / soy

Go implementation for Soy templates (Google Closure templates)
MIT License
172 stars 41 forks source link

Calling soy template recursively causes stackoverflow #43

Closed pcj closed 6 years ago

pcj commented 8 years ago

This was a stupid error on my part, but it took a few minutes to figure out what I had done wrong. Would be nice to track which methods have been called and report a 'recursive template invocation' message to the user. Example is simplified.

/**
 * @param title
 */
{template .body}

{call .body}
{param title: 'Foo' /}
{/call}

{/template}
goroutine 16 [stack growth]:
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eba40, 0x22083707f8, 0x2083ee9c0)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:63 fp=0x26845e668 sp=0x26845e660
github.com/robfig/soy/soyhtml.(*state).evalPrint(0x20b8eba40, 0x2083ee9f0)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:290 +0x6c fp=0x26845e868 sp=0x26845e668
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eba40, 0x2208370918, 0x2083ee9f0)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:83 +0x52d5 fp=0x26845efd8 sp=0x26845e868
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eba40, 0x2208370948, 0x2083fda80)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:78 +0x1f00 fp=0x26845f748 sp=0x26845efd8
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eba40, 0x2208370888, 0x2083eee40)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:75 +0x1b4 fp=0x26845feb8 sp=0x26845f748
github.com/robfig/soy/soyhtml.(*state).evalCall(0x20b8eb980, 0x208379450)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:382 +0x703 fp=0x268460150 sp=0x26845feb8
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eb980, 0x2208370858, 0x208379450)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:146 +0xd72 fp=0x2684608c0 sp=0x268460150
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eb980, 0x2208370948, 0x2083fda80)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:78 +0x1f00 fp=0x268461030 sp=0x2684608c0
github.com/robfig/soy/soyhtml.(*state).walk(0x20b8eb980, 0x2208370888, 0x2083eee40)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:75 +0x1b4 fp=0x2684617a0 sp=0x268461030
github.com/robfig/soy/soyhtml.(*state).evalCall(0x20b8eb8c0, 0x208379450)
    /Users/pcj/gocode/src/github.com/robfig/soy/soyhtml/exec.go:382 +0x703 fp=0x268461a38 sp=0x2684617a0
mhupman commented 8 years ago

I've used recursive templates on purpose a few times (traversing a tree structure with some terminal conditions), so I don't think we'd want to prevent that functionality outright. I did attempt to add a "stack trace" style error reporting to rendering errors in #35 which might make it obvious when a situation like this occurs that wasn't intended.

robfig commented 6 years ago

We could do something like keep track of how many times the same template appears in the call chain and deliberately crash with a helpful message when it's more than e.g. 100, but that doesn't seem super easy so I doubt that I'll get to it at any point. Contributions welcome