Skip to content
Snippets Groups Projects
Commit b8f266a389d6 authored by William M. Brack's avatar William M. Brack
Browse files

changed handling of function params to fix bug #381319 exposed

* libexslt/functions.c: changed handling of function params
  to fix bug #381319
* libxslt/transform.[ch]: exposed xsltLocalVariablePush and
  xsltLocalVariablePop as global entries so that they could
  be used from within libexslt/functions.c
* tests/exslt/functions/function.9.[xsl,xml,out] added to
  regression tests
parent 9115e00b241d
Branches
No related tags found
No related merge requests found
Sat Dec 9 15:22:34 PST 2006 William Brack <wbrack@mmm.com.hk>
* libexslt/functions.c: changed handling of function params
to fix bug #381319
* libxslt/transform.[ch]: exposed xsltLocalVariablePush and
xsltLocalVariablePop as global entries so that they could
be used from within libexslt/functions.c
* tests/exslt/functions/function.9.[xsl,xml,out] added to
regression tests
Tue Dec 5 10:45:04 CET 2006 Daniel Veillard <daniel@veillard.com>
* libxslt/extensions.c: applied patch from Marcus Meissner removing
......
......@@ -281,7 +281,7 @@
int oldBase;
xsltStackElemPtr params = NULL, param;
xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
int i;
int i, notSet;;
/*
* retrieve func:function template
......@@ -317,6 +317,6 @@
return;
}
/*
* Process xsl:param instructions which were not set by the
* invoking function call.
* In order to give the function params and variables a new 'scope'
* we change varsBase in the context.
*/
......@@ -322,3 +322,7 @@
*/
for (i = func->nargs; (i > nargs) && (paramNode != NULL); i--) {
oldBase = tctxt->varsBase;
tctxt->varsBase = tctxt->varsNr;
/* If there are any parameters */
if (paramNode != NULL) {
/*
......@@ -324,4 +328,6 @@
/*
* Those are the xsl:param instructions, which were not
* set by the calling function.
* We need to process params which have been set by the invoking
* function call before those which were not (in case the set values
* are used within non-set 'select' default values), so we position
* to the beginning of the params.
*/
......@@ -327,7 +333,7 @@
*/
param = xsltParseStylesheetCallerParam (tctxt, paramNode);
param->next = params;
params = param;
for (i = 1; i <= func->nargs; i++) {
if (paramNode->prev == NULL)
break;
paramNode = paramNode->prev;
}
/*
......@@ -331,6 +337,6 @@
paramNode = paramNode->prev;
}
/*
* Process xsl:param instructions which are set by the
* invoking function call.
* i has total # params found, nargs is number which are present
* as arguments from the caller
*/
......@@ -336,3 +342,5 @@
*/
while ((i-- > 0) && (paramNode != NULL)) {
notSet = func->nargs - nargs;
for (; i > 0; i--) {
if (i > notSet) /* if parameter value set */
obj = valuePop(ctxt);
......@@ -338,12 +346,2 @@
obj = valuePop(ctxt);
/*
* TODO: Using xsltParseStylesheetCallerParam() is actually
* not correct, since we are processing an xsl:param; but
* using xsltParseStylesheetParam() won't work, as it puts
* the param on the varible stack and does not give access to
* the created xsltStackElemPtr.
* It's also not correct, as xsltParseStylesheetCallerParam()
* will report error messages indicating an "xsl:with-param" and
* not the actual "xsl:param".
*/
param = xsltParseStylesheetCallerParam (tctxt, paramNode);
......@@ -349,5 +347,6 @@
param = xsltParseStylesheetCallerParam (tctxt, paramNode);
if (i > notSet) { /* if parameter value set */
param->computed = 1;
if (param->value != NULL)
xmlXPathFreeObject(param->value);
param->value = obj;
......@@ -350,6 +349,8 @@
param->computed = 1;
if (param->value != NULL)
xmlXPathFreeObject(param->value);
param->value = obj;
}
xsltLocalVariablePush(tctxt, param, -1);
param->next = params;
params = param;
......@@ -354,4 +355,4 @@
param->next = params;
params = param;
paramNode = paramNode->prev;
paramNode = paramNode->next;
}
......@@ -357,5 +358,5 @@
}
}
/*
* actual processing
*/
......@@ -363,10 +364,4 @@
(const xmlChar *)"fake", NULL);
oldInsert = tctxt->insert;
tctxt->insert = fake;
/*
* In order to give the function variables a new 'scope' we
* change varsBase in the context.
*/
oldBase = tctxt->varsBase;
tctxt->varsBase = tctxt->varsNr;
xsltApplyOneTemplate (tctxt, xmlXPathGetContextNode(ctxt),
......@@ -372,5 +367,6 @@
xsltApplyOneTemplate (tctxt, xmlXPathGetContextNode(ctxt),
func->content, NULL, params);
func->content, NULL, NULL);
xsltLocalVariablePop(tctxt, tctxt->varsBase, -2);
tctxt->insert = oldInsert;
tctxt->varsBase = oldBase; /* restore original scope */
if (params != NULL)
......
......@@ -173,8 +173,10 @@
* Pops all variable values at the given @depth from the stack.
*
* Returns the stored variable value
*/
static void
* **NOTE:**
* This is an internal routine and should not be called by users!
*/
void
xsltLocalVariablePop(xsltTransformContextPtr ctxt, int limitNr, int level)
{
xsltStackElemPtr variable;
......@@ -2067,7 +2069,19 @@
return(debugedNode);
}
static int
/**
* xsltVariablePush:
* @ctxt: the transformation context
* @variable: variable to be pushed to the variable stack
* @level: new value for variable's level
*
* Places the variable onto the local variable stack
*
* Returns: 0 for success, -1 for any error
* **NOTE:**
* This is an internal routine and should not be called by users!
*/
int
xsltLocalVariablePush(xsltTransformContextPtr ctxt,
xsltStackElemPtr variable,
int level)
......@@ -3132,6 +3146,11 @@
CHECK_STOPPED;
if (params) {
/*
* This code should be obsolete - was previously used
* by libexslt/functions.c, but due to bug 381319 the
* logic there was changed.
*/
int oldVarsNr = ctxt->varsNr;
/*
......
......@@ -176,6 +176,16 @@
xmlNodePtr target,
const xmlChar *string,
int noescape);
/* Following 2 functions needed for libexslt/functions.c */
XSLTPUBFUN void XSLTCALL
xsltLocalVariablePop (xsltTransformContextPtr ctxt,
int limitNr,
int level);
XSLTPUBFUN int XSLTCALL
xsltLocalVariablePush (xsltTransformContextPtr ctxt,
xsltStackElemPtr variable,
int level);
/*
* Hook for the debugger if activated.
*/
......
......@@ -11,7 +11,8 @@
function.5.out function.5.xml function.5.xsl \
function.6.out function.6.xml function.6.xsl \
function.7.out function.7.xml function.7.xsl \
function.8.out function.8.xml function.8.xsl
function.8.out function.8.xml function.8.xsl \
function.9.out function.9.xml function.9.xsl
all:
......
<?xml version="1.0"?>
a
<?xml version="1.0" encoding="UTF-8"?>
<root>
<table>
<tr>
<td align="center">a</td>
</tr>
</table>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:func="http://exslt.org/functions"
xmlns:math="http://exslt.org/math"
xmlns:mg="mg"
extension-element-prefixes="exsl func">
<xsl:template match="table">
<xsl:variable name="cols" select="mg:function(.)"/>
<xsl:value-of select="$cols"/>
</xsl:template>
<func:function name="mg:function">
<xsl:param name="table"/>
<xsl:param name="tr" select="$table/tr[1]"/>
<func:result select="$tr"/>
</func:function>
</xsl:stylesheet>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment