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