Bug #392
closedsaxon:evaluate with variables corrupts the caller's stack
0%
Description
SourceForge user: mhkay
When saxon:evaluate() is called to evaluate an
expression that contains local variables (possibly local
varaibles added to the expression by the optimizer), the
values of these variables corrupt variables on the stack
frame of the template or function from which
saxon:evaluate was called.
I've fixed the problem. In Evaluate.java, change line 152
to
return pexpr.expression.iterate(newContext(c));
and line 135 to
return pexpr.expression.evaluateItem(newContext(c));
and add the method:
private XPathContext newContext(XPathContext old)
{
old.getController().getBindery().openStackFrame();
return old.getController().newXPathContext();
}
Updated by Anonymous almost 21 years ago
SourceForge user: mhkay
Logged In: YES
user_id=251681
The above patch is incorrect. It creates a new stack frame
for the evaluated expression but doesn't reset the context
correctly on exit. Here's an improved version:
/**
* Evaluate in a general context
*/
public Item evaluateItem(XPathContext c) throws
XPathException {
PreparedExpression pexpr = prepareExpression(c);
if (operation == EXPRESSION) {
return new ObjectValue(pexpr);
} else {
for (int i=1; i<getNumberOfArguments(); i++) {
pexpr.variables[i-1].setXPathValue
(ExpressionTool.eagerEvaluate(argument[i],c));
}
c.getController().getBindery().openStackFrame();
XPathContext c2 = c.getController
().newXPathContext();
Item result = pexpr.expression.evaluateItem(c2);
c.getController().getBindery().closeStackFrame();
return result;
}
}
/**
* Iterate over the results of the function
*/
public SequenceIterator iterate(XPathContext c) throws
XPathException {
PreparedExpression pexpr = prepareExpression(c);
if (operation == EXPRESSION) {
return SingletonIterator.makeIterator(new
ObjectValue(pexpr));
} else {
for (int i=1; i<getNumberOfArguments(); i++) {
pexpr.variables[i-1].setXPathValue
(ExpressionTool.eagerEvaluate(argument[i],c));
}
c.getController().getBindery().openStackFrame();
XPathContext c2 = c.getController
().newXPathContext();
SequenceIterator result = pexpr.expression.iterate
(c2);
c.getController().getBindery().closeStackFrame();
return result;
}
}
Updated by Anonymous almost 21 years ago
SourceForge user: mhkay
Logged In: YES
user_id=251681
Further testing reveals that this fix still isn't quite right. In
both methods the line
XPathContext c2 = c.getController
().newXPathContext();
should be
XPathContext c2 = c.newContext();
Michael Kay
Please register to edit this issue