Infinite recursion in param resolve
Hi there,
you are most likely aware of this, but I'm filing this as an issue anyway. As you point out in the wiki (https://github.com/linkedin/dustjs/wiki/Dust-Tutorial#Parameter_rules) params will overlay the context with their own "namespace" for resolving themselves if their values are template strings.
This can lead to infinite recursion if a param value string references a context element with the same name as the param key.
Less words, more code: https://gist.github.com/darkspotinthecorner/6564b77cc2e4165a935a
I know, it's a bit contrieve, but maybe it's worth fixing. ;)
PS: Great work here, I really enjoy working with dustjs!
Thanks for reporting and for the simplified real world use case. I would love your thoughts and what is expected. See also #310 which has a complicated example and #356 which is a similar issue but with blocks explicitly calling itself.
FWIW, this works:
{#users xxx=xxx}{.name} ( {xxx} ){/users}
I believe the expectation from the gist is to get
Fred (something)
Wilma (something)
Barney (something)
I believe there are a few options:
- when dereferencing the values inside a parameter, don't look in the parameter again. This removes the ability to have a parameter reference another parameter. We could just check our parameter name but then circular dependencies are possible. Also, not sure how this affects nested partials.
- when evaluating the parameter value, do it as a copy (pass by value instead of by reference, sorta) and do it before entering the block. Unfortunately, this would force us to always evaluate the parameters even if they aren't used. If the params are pointing to functions, we might get side effects before we expect them (when the param gets called).
alternatively, we could keep the infinite loop and catch it in a more usable way. not sure what this means at the moment. It also doesn't really address the issue.
Yes, I also tested with circular references. Same problem here.
How about not putting the params on the context of the current param value evaluations at all. I was a bit surprised to see this is possible, tbh. It may be useful in some cases, yes. But as far as I can tell, there is nothing that can't be done with adding another section and doing another round of param evaluation to prevent self- and circular references.
Like here:
{#section param1=var1}
{#. var1="<span>{param1}</span>"}
{sectionval1} {var1}
{/.}
{/section}
This way, all function calls introduced by params must bubble up the stack and can't stay inside.
At last, I hope so. My experience with dust is limited. :)