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