Re: Infinite loop with CountDirective

Keats Kirsch <[email protected]> Tue, 28 Mar 2006 09:42:30 -0500
Newsgroups gmane.comp.java.webmacro.user
Message-ID <[email protected]>
This certainly looks like a bug.  Thanks for doing such an excellent job 
of documenting it.  I'll try to commit a patch (and maybe a unit test to 
go with it) in the next day or so.

I'm pretty sure that the count directive was written before we added the 
UndefinedMacro, and this edge case was apparently not tested.

Keats

Sven Schliesing wrote:

> Hi,
>
> I think I just encountered an infinite loop with the CountDirective.
>
> I cut the template down to this snippet to verify the error:
> #count $i from 1 to $pages {
> }
>
> $pages is not set in the context, so we count from "1 to unknown"
>
> In the CountDirective this snippet is responsible for the handling of 
> the end-value:
>
> CountDirective.java
> -------------
> 162 if ((tmp = _objEnd) != null)
> 163        {
> 164            while (tmp instanceof Macro)
> 164                tmp = ((Macro) tmp).evaluate(context);
> ...
> 173        }
> -------------
> I added line numbers for better understanding.
> Cause _objEnd (and therefore tmp) is a SimplePropertyVariable 
> (implements Macro), the statement on line 164 gets true and so 
> evaluate(context) (member of Variable) is called.
>
> Variable.java
> -------------
> 153 final public Object evaluate (Context context) throws 
> PropertyException
> 154    {
> 155        try
> 156        {
> 157            Object val = getValue(context);
> 158            if (val instanceof Macro)
> 159            {
> 160                val = ((Macro) val).evaluate(context); // recurse
> 161            }
> 162            return val;
> 163        }
> ...
> ------------
> getValue(context) on line 157 returns "UndefinedMacro", cause the 
> value ($pages) is not set. Line 158 evaluates to true, and so evaluate 
> (context) (member of UndefinedMacro) is called and returns the class' 
> _singleton (new UndefinedMacro()).
> So we get back to the beginning in CountDirective. tmp in line 164 
> gets a new value (singleton of UndefinedMacro).
> Now we enter the infinite loop: Because UndefinedMacro is a Macro, 
> too, we call evaluate(context) on it again (line 164) and get 
> returned: the _singleton of UndefinedMacro. So no change here. tmp 
> will never change it's value from UndefinedMacro to something else. It 
> will never ever evaluate to a value that exits our loop.
>
> So is it me? Am I getting something totally wrong? An unset 
> end-variable should result in an error-message, not in an infinite 
> loop, shouldn't it?
>
> Greets,
>
> Sven
>




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642