summaryrefslogtreecommitdiff
path: root/libexslt
diff options
context:
space:
mode:
authorWilliam M. Brack <wbrack@src.gnome.org>2006-12-09 23:18:21 +0000
committerWilliam M. Brack <wbrack@src.gnome.org>2006-12-09 23:18:21 +0000
commit79068441851f5fc363d75906a722c6482be0377a (patch)
treecbbb9ab3fecc1613fdcb945cf86e85a5df3d0eff /libexslt
parentb9ab5c35b5edd8c11777888246c8f64634c5fcd2 (diff)
downloadlibxslt-79068441851f5fc363d75906a722c6482be0377a.tar.gz
libxslt-79068441851f5fc363d75906a722c6482be0377a.tar.bz2
libxslt-79068441851f5fc363d75906a722c6482be0377a.zip
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
Diffstat (limited to 'libexslt')
-rw-r--r--libexslt/functions.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/libexslt/functions.c b/libexslt/functions.c
index bbeb182a..58bd71e4 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -281,7 +281,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
int oldBase;
xsltStackElemPtr params = NULL, param;
xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
- int i;
+ int i, notSet;;
/*
* retrieve func:function template
@@ -316,46 +316,47 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
"param == NULL\n");
return;
}
- /*
- * Process xsl:param instructions which were not set by the
- * invoking function call.
- */
- for (i = func->nargs; (i > nargs) && (paramNode != NULL); i--) {
+ /*
+ * In order to give the function params and variables a new 'scope'
+ * we change varsBase in the context.
+ */
+ oldBase = tctxt->varsBase;
+ tctxt->varsBase = tctxt->varsNr;
+
+ /* If there are any parameters */
+ if (paramNode != NULL) {
/*
- * Those are the xsl:param instructions, which were not
- * set by the calling function.
- */
- param = xsltParseStylesheetCallerParam (tctxt, paramNode);
- param->next = params;
- params = param;
- paramNode = paramNode->prev;
- }
- /*
- * Process xsl:param instructions which are set by the
- * invoking function call.
- */
- while ((i-- > 0) && (paramNode != NULL)) {
- obj = valuePop(ctxt);
+ * 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.
+ */
+ for (i = 1; i <= func->nargs; i++) {
+ if (paramNode->prev == NULL)
+ break;
+ paramNode = paramNode->prev;
+ }
/*
- * 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);
- param->computed = 1;
- if (param->value != NULL)
- xmlXPathFreeObject(param->value);
- param->value = obj;
- param->next = params;
- params = param;
- paramNode = paramNode->prev;
+ * i has total # params found, nargs is number which are present
+ * as arguments from the caller
+ */
+ notSet = func->nargs - nargs;
+ for (; i > 0; i--) {
+ if (i > notSet) /* if parameter value set */
+ obj = valuePop(ctxt);
+ param = xsltParseStylesheetCallerParam (tctxt, paramNode);
+ if (i > notSet) { /* if parameter value set */
+ param->computed = 1;
+ if (param->value != NULL)
+ xmlXPathFreeObject(param->value);
+ param->value = obj;
+ }
+ xsltLocalVariablePush(tctxt, param, -1);
+ param->next = params;
+ params = param;
+ paramNode = paramNode->next;
+ }
}
-
/*
* actual processing
*/
@@ -363,14 +364,9 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
(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),
- 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)