Re: Infinite loop with CountDirective

Keats Kirsch <[email protected]> Tue, 28 Mar 2006 18:47:32 -0500
Newsgroups gmane.comp.java.webmacro.user
Message-ID <[email protected]>
OK, I've committed a fixed version along with a new unit test.  Please 
check it out and let me know if you find any problems.

Keats

Keats Kirsch wrote:

> 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