mmidy       00/11/10 08:12:25

  Modified:    src/org/apache/xalan/xslt XSLTEngineImpl.java
  Log:
  Catch circular use of variables and fix problem with top level params being 
processed twice in SAX context.
  
  Revision  Changes    Path
  1.81      +95 -2     xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java
  
  Index: XSLTEngineImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java,v
  retrieving revision 1.80
  retrieving revision 1.81
  diff -u -r1.80 -r1.81
  --- XSLTEngineImpl.java       2000/11/09 14:14:02     1.80
  +++ XSLTEngineImpl.java       2000/11/10 16:12:25     1.81
  @@ -260,6 +260,11 @@
      * doing queries.
      */
     private StackGuard m_stackGuard = new StackGuard();
  +     
  +     /**
  +   * Object to guard against circular use of variables.
  +   */
  +     private VariableGuard m_variableGuard;
   
     /**
      * The stack of Variable stacks.  A VariableStack will be
  @@ -436,6 +441,7 @@
       m_needToCheckForInfiniteLoops = false;
       m_variableStacks = new VariableStack();
       m_stackGuard = new StackGuard();
  +             m_variableGuard = null;
        m_topLevelParams = new Vector();
       m_parserLiaison.reset();
     }
  @@ -492,7 +498,19 @@
     StackGuard getStackGuard()
     {  
       return m_stackGuard;
  -  }  
  +  }
  +     
  +     /**
  +   * <meta name="usage" content="internal"/>
  +   * Get the object used to guard the variables stack from 
  +   * recursion.
  +   */
  +  VariableGuard getVariableGuard()
  +  {
  +             if (m_variableGuard == null)
  +                     m_variableGuard = new VariableGuard();
  +    return m_variableGuard;
  +  }
   
     // Guard against being serialized by mistake
     private void writeObject(ObjectOutputStream stream)
  @@ -3007,6 +3025,7 @@
                        if (obj instanceof XObject && (((XObject)obj).object() 
instanceof Arg))
                        {       
                                ElemVariable var 
=((Arg)(((XObject)obj).object())).m_elem;
  +                             getVariableGuard().push(var);
                                try
                                {
                                        //Save the current frame index then 
force us to look
  @@ -3019,7 +3038,8 @@
                                                                                
                                                                 
this.m_rootDoc, this.m_rootDoc);                                                
                               
                                        ((Arg)(((XObject)obj).object())).m_val 
= val;
                                        
getVarStack().setCurrentStackFrameIndex(savIndex);
  -                                     return val;                             
  +                                     getVariableGuard().pop();
  +                                     return val;                             
        
                                }
                                catch (Exception ex)
                                {
  @@ -3431,6 +3451,7 @@
       m_rootDoc = sourceTree;
       // StylesheetRoot stylesheet = m_stylesheetRoot;
       // reset();
  +             /*
       try
       {
         getVarStack().pushContextMarker();
  @@ -3440,6 +3461,7 @@
       {
         throw new SAXException(e.getMessage(), e);
       }
  +             */
       // m_stylesheetRoot = stylesheet;
       m_sourceTreeHandler.startDocument();
     }
  @@ -3765,6 +3787,77 @@
       }
     } // end StackGuard class
   
  +     /**
  +   * The VariableGuard class guard against the circular use of variables.
  +   */
  +  class VariableGuard
  +  {
  +    ElemVariable m_var;
  +    
  +    java.util.Stack stack = new java.util.Stack();
  +
  +    public VariableGuard()
  +    {
  +    }
  +
  +    public VariableGuard(ElemVariable var)
  +    {
  +      m_var = var;
  +    }
  +
  +    public boolean equals(Object obj)
  +    {
  +      if(((VariableGuard)obj).m_var.equals(m_var))
  +      {
  +        return true;
  +      }
  +      return false;
  +    }
  +
  +    public void print(PrintWriter pw)
  +    {
  +      // for the moment, these diagnostics are really bad...
  +      
  +        pw.println(m_var.m_qname.toString());
  +      
  +    }
  +
  +
  +    public void checkForInfiniteLoop(VariableGuard guard)
  +    {
  +      int nRules = stack.size();
  +                     for(int i = (nRules - 1); i >= 0; i--)
  +                     {
  +                             if(stack.elementAt(i).equals(guard))
  +                             {       
  +                                     // Print out really bad diagnostics.
  +                                     StringWriter sw = new StringWriter();
  +                                     PrintWriter pw = new PrintWriter(sw);
  +                                     pw.println("Infinite loop diagnosed!  
Stack trace:");
  +                                     
  +                                     pw.print("Circular variable name: ");
  +                                     VariableGuard guardOnStack = 
(VariableGuard)stack.elementAt(i);
  +                                     guardOnStack.print(pw);                 
                
  +                                     
  +                                     pw.println("End of infinite loop 
diagnosis.");
  +                                     diag(sw.getBuffer().toString());
  +                                     throw new XSLInfiniteLoopException();
  +                             }
  +                     }
  +    }
  +
  +    public void push(ElemVariable var) 
  +    {
  +      VariableGuard guard = new VariableGuard(var); 
  +      checkForInfiniteLoop(guard);
  +      stack.push(guard);
  +    }
  +
  +    public void pop()
  +    {
  +      stack.pop();
  +    }
  +  } // end VariableGuard class
   
     /**
      * Bottleneck addition of result tree attributes, so I can keep
  
  
  

Reply via email to