velocity-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nbu...@apache.org
Subject svn commit: r679861 - in /velocity/engine/trunk/src: java/org/apache/velocity/context/ java/org/apache/velocity/runtime/ java/org/apache/velocity/runtime/directive/ test/org/apache/velocity/test/
Date Fri, 25 Jul 2008 17:17:51 GMT
Author: nbubna
Date: Fri Jul 25 10:17:50 2008
New Revision: 679861

URL: http://svn.apache.org/viewvc?rev=679861&view=rev
Log:
VELOCITY-607 yank and replace badly broken max macro call depth guard

Modified:
    velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java
    velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
    velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java
    velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
    velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeServices.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
    velocity/engine/trunk/src/test/org/apache/velocity/test/VelocimacroTestCase.java

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java Fri Jul
25 10:17:50 2008
@@ -242,6 +242,46 @@
     }
 
     /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String)
+     */
+    public void pushCurrentMacroName( String s )
+    {
+        innerContext.pushCurrentMacroName( s );
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName()
+     */
+    public void popCurrentMacroName()
+    {
+        innerContext.popCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName()
+     */
+    public String getCurrentMacroName()
+    {
+        return innerContext.getCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth()
+     */
+    public int getCurrentMacroCallDepth()
+    {
+        return innerContext.getCurrentMacroCallDepth();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack()
+     */
+    public Object[] getMacroNameStack()
+    {
+        return innerContext.getMacroNameStack();
+    }
+
+    /**
      * @see org.apache.velocity.context.InternalHousekeepingContext#icacheGet(java.lang.Object)
      */
     public IntrospectionCacheData icacheGet( Object key )

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
Fri Jul 25 10:17:50 2008
@@ -146,6 +146,46 @@
     }
 
     /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String)
+     */
+    public void pushCurrentMacroName( String s )
+    {
+        icb.pushCurrentMacroName( s );
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName()
+     */
+    public void popCurrentMacroName()
+    {
+        icb.popCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName()
+     */
+    public String getCurrentMacroName()
+    {
+        return icb.getCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth()
+     */
+    public int getCurrentMacroCallDepth()
+    {
+        return icb.getCurrentMacroCallDepth();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack()
+     */
+    public Object[] getMacroNameStack()
+    {
+        return icb.getMacroNameStack();
+    }
+
+    /**
      * @see org.apache.velocity.context.InternalHousekeepingContext#icacheGet(java.lang.Object)
      */
     public IntrospectionCacheData icacheGet( Object key )

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java Fri
Jul 25 10:17:50 2008
@@ -60,6 +60,11 @@
     private Stack templateNameStack = new Stack();
 
     /**
+     *  Velocimacro name stack. The stack top contains the current macro name.
+     */
+    private Stack macroNameStack = new Stack();
+
+    /**
      *  EventCartridge we are to carry.  Set by application
      */
     private EventCartridge eventCartridge = null;
@@ -123,6 +128,61 @@
     }
 
     /**
+     *  set the current macro name on top of stack
+     *
+     *  @param s current macro name
+     */
+    public void pushCurrentMacroName( String s )
+    {
+        macroNameStack.push(s);
+    }
+
+    /**
+     *  remove the current macro name from stack
+     */
+    public void popCurrentMacroName()
+    {
+        macroNameStack.pop();
+    }
+
+    /**
+     *  get the current macro name
+     *
+     *  @return String current macro name
+     */
+    public String getCurrentMacroName()
+    {
+        if (macroNameStack.empty())
+        {
+            return "<undef>";
+        }
+        else
+        {
+            return (String) macroNameStack.peek();
+        }
+    }
+
+    /**
+     *  get the current macro call depth
+     *
+     *  @return int current macro call depth
+     */
+    public int getCurrentMacroCallDepth()
+    {
+        return macroNameStack.size();
+    }
+
+    /**
+     *  get the current macro name stack
+     *
+     *  @return Object[] with the macro name stack contents.
+     */
+    public Object[] getMacroNameStack()
+    {
+        return macroNameStack.toArray();
+    }
+
+    /**
      *  returns an IntrospectionCache Data (@see IntrospectionCacheData)
      *  object if exists for the key
      *

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
Fri Jul 25 10:17:50 2008
@@ -67,6 +67,39 @@
     Object[] getTemplateNameStack();
 
     /**
+     *  set the current macro name on top of stack
+     *
+     *  @param s current macro name
+     */
+    void pushCurrentMacroName( String s );
+
+    /**
+     *  remove the current macro name from stack
+     */
+    void popCurrentMacroName();
+
+    /**
+     *  get the current macro name
+     *
+     *  @return String current macro name
+     */
+    String getCurrentMacroName();
+
+    /**
+     *  get the current macro call depth
+     *
+     *  @return int current macro call depth
+     */
+    int getCurrentMacroCallDepth();
+
+    /**
+     *  Returns the macro name stack in form of an array.
+     *
+     *  @return Object[] with the macro name stack contents.
+     */
+    Object[] getMacroNameStack();
+
+    /**
      *  returns an IntrospectionCache Data (@see IntrospectionCacheData)
      *  object if exists for the key
      *

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java Fri Jul 25 10:17:50
2008
@@ -325,6 +325,46 @@
     }
 
     /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String)
+     */
+    public void pushCurrentMacroName( String s )
+    {
+        innerContext.pushCurrentMacroName( s );
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName()
+     */
+    public void popCurrentMacroName()
+    {
+        innerContext.popCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName()
+     */
+    public String getCurrentMacroName()
+    {
+        return innerContext.getCurrentMacroName();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth()
+     */
+    public int getCurrentMacroCallDepth()
+    {
+        return innerContext.getCurrentMacroCallDepth();
+    }
+
+    /**
+     * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack()
+     */
+    public Object[] getMacroNameStack()
+    {
+        return innerContext.getMacroNameStack();
+    }
+
+    /**
      * @see org.apache.velocity.context.InternalHousekeepingContext#icacheGet(java.lang.Object)
      */
     public IntrospectionCacheData icacheGet( Object key )

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java Fri Jul
25 10:17:50 2008
@@ -1677,31 +1677,4 @@
         return uberSpect;
     }
 
-    /**
-     * This method is called before a macro is rendered. This method
-     * checks whether a macro call is within the allowed calling depth.
-     * If the macro call exceeds the allowed calling depth it will throw
-     * an exception.
-     *
-     * @param macroName name of the macro
-     * @param templateName name of the template file containing the macro
-     * @throws MacroOverflowException if the number of macro calls 
-     * exceeds the specified value
-     */
-    public void startMacroRendering(String macroName, String templateName) throws MacroOverflowException
-    {
-        vmFactory.startMacroRendering(macroName, templateName);
-    }
-
-    /**
-     * This method is called after a macro rendering is finished. It cleasr
-     * all the state saved in the VelociMacroFactory about this particular
-     * macro.
-     * @param macroName name of the macro
-     * @param templateName template name that contains the macro
-     */
-    public void endMacroRendering(String macroName, String templateName)
-    {
-        vmFactory.endMacroRendering(macroName, templateName);
-    }
 }

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeServices.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeServices.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeServices.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeServices.java Fri Jul
25 10:17:50 2008
@@ -478,24 +478,4 @@
      */
     public Directive getDirective(String name);
 
-    /**
-     * This method is called before a macro is rendered. This method
-     * checks whether a macro call is within the allowed calling depth.
-     * If the macro call exceeds the allowed calling depth it will throw
-     * an exception.
-     *
-     * @param macroName name of the macro
-     * @param templateName name of the template file containing the macro
-     * @throws MacroOverflowException if the
-     * number of recursive macro calls exceeds the specified value
-     */
-    public void startMacroRendering(String macroName, String templateName)
-                throws MacroOverflowException;
-
-    /**
-     * This method is called after macro rendering is finished.
-     * @param macroName name of the macro
-     * @param templateName template name that contains the macro
-     */
-    public void endMacroRendering(String macroName, String templateName);
 }

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java Fri
Jul 25 10:17:50 2008
@@ -176,6 +176,46 @@
         }
 
         /**
+         * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String)
+         */
+        public void pushCurrentMacroName( String s )
+        {
+            innerContext.pushCurrentMacroName( s );
+        }
+
+        /**
+         * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName()
+         */
+        public void popCurrentMacroName()
+        {
+            innerContext.popCurrentMacroName();
+        }
+
+        /**
+         * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName()
+         */
+        public String getCurrentMacroName()
+        {
+            return innerContext.getCurrentMacroName();
+        }
+
+        /**
+         * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth()
+         */
+        public int getCurrentMacroCallDepth()
+        {
+            return innerContext.getCurrentMacroCallDepth();
+        }
+
+        /**
+         * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack()
+         */
+        public Object[] getMacroNameStack()
+        {
+            return innerContext.getMacroNameStack();
+        }
+
+        /**
          * @see org.apache.velocity.context.InternalContextAdapter#icacheGet(java.lang.Object
key)
          */
         public IntrospectionCacheData icacheGet(Object key)

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
Fri Jul 25 10:17:50 2008
@@ -65,6 +65,7 @@
     private HashMap proxyArgHash = new HashMap();
 
     private boolean strictArguments;
+    private int maxCallDepth;
     
     /**
      * Return name of this Velocimacro.
@@ -195,16 +196,46 @@
                 }
 
                 /*
-                 Inform that we are about to rendering
-                */
-                rsvc.startMacroRendering(macroName,
-                        vmc.getCurrentTemplateName());
+                 * check that we aren't already at the max call depth
+                 */
+                if (maxCallDepth > 0 && maxCallDepth == vmc.getCurrentMacroCallDepth())
+                {
+                    String templateName = vmc.getCurrentTemplateName();
+                    Object[] stack = vmc.getMacroNameStack();
+
+                    String message = "Max calling depth of "+maxCallDepth+
+                        " was exceeded in Template:" + templateName +
+                        " and Macro:" + macroName + " with Call Stack:";
+                    for (int i = 0; i < stack.length; i++)
+                    {
+                        if (i != 0)
+                        {
+                            message += "->";
+                        }
+                        message += stack[i];
+                    }
+                    rsvc.getLog().error(message);
+
+                    try
+                    {
+                        throw new MacroOverflowException(message);
+                    }
+                    finally
+                    {
+                        // clean out the macro stack, since we just broke it
+                        while (vmc.getCurrentMacroCallDepth() > 0)
+                        {
+                            vmc.popCurrentMacroName();
+                        }
+                    }
+                }
+
                 /*
                  *  now render the VM
                  */
-                 nodeTree.render( vmc, writer );
-
-                 rsvc.endMacroRendering(macroName, vmc.getCurrentTemplateName());
+                vmc.pushCurrentMacroName(macroName);
+                nodeTree.render( vmc, writer );
+                vmc.popCurrentMacroName();
             }
             else
             {
@@ -256,6 +287,11 @@
          * Throw exception for invalid number of arguments?
          */
         strictArguments = rs.getConfiguration().getBoolean(RuntimeConstants.VM_ARGUMENTS_STRICT,false);
+
+        /*
+         * get the macro call depth limit
+         */
+        maxCallDepth = rsvc.getInt(RuntimeConstants.VM_MAX_DEPTH);
         
         /*
          *  how many args did we get?

Modified: velocity/engine/trunk/src/test/org/apache/velocity/test/VelocimacroTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/VelocimacroTestCase.java?rev=679861&r1=679860&r2=679861&view=diff
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/VelocimacroTestCase.java (original)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/VelocimacroTestCase.java Fri Jul
25 10:17:50 2008
@@ -38,11 +38,11 @@
  */
 public class VelocimacroTestCase extends TestCase
 {
-    private String template1 = "#macro(foo $a)$a#end #macro(bar $b)#foo($b)#end #foreach($i
in [1..3])#bar($i)#end";
-    private String template2 = "#macro(foo1 $a)#set($a = $a + 1)$a#foo1($a)#end#foo1(0)";
-    private String template3 = "#macro(foo1 $a)#set($a = $a + 1)$a#inner($a)#end#macro(inner
$b)#foo1($b)#end#foo1(0)";
-    private String template4 = "#macro(foo1 $a)#set($a = $a + 1)$a#inner($a)#end#macro(inner
$b)#innerInner($b)#end#macro(innerInner $c)#foo1($c)#end#foo1(0)";
+    private String template1 = "#macro(foo $a)$a#end #macro(bar $b)#foo($b)#end #foreach($i
in [1..3])#if($i == 3)#foo($i)#else#bar($i)#end#end";
     private String result1 = "  123";
+    private String template2 = "#macro(bar $a)#set($a = $a + 1)$a#bar($a)#end#bar(0)";
+    private String template3 = "#macro(baz $a)#set($a = $a + 1)$a#inner($a)#end#macro(inner
$b)#baz($b)#end#baz(0)";
+    private String template4 = "#macro(bad $a)#set($a = $a + 1)$a#inside($a)#end#macro(inside
$b)#loop($b)#end#macro(loop $c)#bad($c)#end#bad(0)";
 
     public VelocimacroTestCase(String name)
     {
@@ -98,37 +98,37 @@
         try
         {
             Velocity.evaluate(context, writer, "vm_chain2", template2);
+            fail("Did not exceed max macro call depth as expected");
         }
         catch (MacroOverflowException e)
         {
-            /*
-             Check the exception message
-             */
-            assertEquals(e.getMessage(),
-                    "Exceed maximum 5 macro calls. Call Stack:foo1->" +
-                            "foo1->foo1->foo1->foo1");
+            assertEquals("Max calling depth of 5 was exceeded in Template:vm_chain2"+
+                            " and Macro:bar with Call Stack:bar->bar->bar->bar->bar",
+                         e.getMessage());
         }
 
         try
         {
             Velocity.evaluate(context, writer, "vm_chain3", template3);
+            fail("Did not exceed max macro call depth as expected");
         }
         catch (MacroOverflowException e)
         {
-            assertEquals(e.getMessage(),
-                    "Exceed maximum 5 macro calls. Call Stack:foo1->inner->" +
-                            "foo1->inner->foo1");
+            assertEquals("Max calling depth of 5 was exceeded in Template:vm_chain3"+
+                            " and Macro:inner with Call Stack:baz->inner->baz->inner->baz",
+                         e.getMessage());
         }
 
         try
         {
             Velocity.evaluate(context, writer, "vm_chain4", template4);
+            fail("Did not exceed max macro call depth as expected");
         }
         catch (MacroOverflowException e)
         {
-            assertEquals(e.getMessage(),
-                    "Exceed maximum 5 macro calls. Call Stack:foo1->inner->" +
-                            "innerInner->foo1->inner");
+            assertEquals("Max calling depth of 5 was exceeded in Template:vm_chain4"+
+                            " and Macro:loop with Call Stack:bad->inside->loop->bad->inside",
+                         e.getMessage());
         }
     }
 }



Mime
View raw message