1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-08 11:02:18 +03:00

Fixed variable scope problem

This commit is contained in:
William M. Brack
2001-07-07 09:11:11 +00:00
parent d237fa7915
commit 22de9c0838
4 changed files with 72 additions and 37 deletions

View File

@@ -1,3 +1,8 @@
Sat Jul 7 17:05:00 HKT 2001 Wiliam Brack <wbrack@mmm.com.hk>
* xsltInternals.h variables.c transform.c:
fixed problem with variable scope within templates
Fri Jul 6 17:42:06 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr> Fri Jul 6 17:42:06 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* doc/extensions.html doc/internals.html doc/xslt.html: * doc/extensions.html doc/internals.html doc/xslt.html:

View File

@@ -1,6 +1,6 @@
/* /*
* transform.c: Implemetation of the XSL Transformation 1.0 engine * transform.c: Implemetation of the XSL Transformation 1.0 engine
* transform part, i.e. applying a Stylesheet to a document * transform part, i.e. applying a Stylesheet to a document
* *
* References: * References:
* http://www.w3.org/TR/1999/REC-xslt-19991116 * http://www.w3.org/TR/1999/REC-xslt-19991116
@@ -139,7 +139,7 @@ xsltGetXIncludeDefault(void) {
/************************************************************************ /************************************************************************
* * * *
* handling of transformation contexts * * Handling of Transformation Contexts *
* * * *
************************************************************************/ ************************************************************************/
@@ -195,6 +195,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->varsNr = 0; cur->varsNr = 0;
cur->varsMax = 5; cur->varsMax = 5;
cur->vars = NULL; cur->vars = NULL;
cur->varsBase = 0;
cur->style = style; cur->style = style;
xmlXPathInit(); xmlXPathInit();
@@ -415,10 +416,10 @@ xsltCopyProp(xsltTransformContextPtr ctxt, xmlNodePtr target,
/** /**
* xsltCopyPropList: * xsltCopyPropList:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @target: the element where the attributes will be grafted * @target: the element where the properties will be grafted
* @cur: the first attribute * @cur: the first property
* *
* Do a copy of an attribute list. * Do a copy of a properties list.
* *
* Returns: a new xmlAttrPtr, or NULL in case of error. * Returns: a new xmlAttrPtr, or NULL in case of error.
*/ */
@@ -494,11 +495,11 @@ xsltCopyNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
/** /**
* xsltCopyTreeList: * xsltCopyTreeList:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @list: the list of element node in the source tree. * @list: the list of element nodes in the source tree.
* @insert: the parent in the result tree. * @insert: the parent in the result tree.
* *
* Make a copy of the full list of tree @list * Make a copy of the full list of tree @list
* and insert them as last children of @insert * and insert it as last children of @insert
* *
* Returns a pointer to the new list, or NULL in case of error * Returns a pointer to the new list, or NULL in case of error
*/ */
@@ -617,7 +618,7 @@ void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node);
* <xsl:value-of select="."/> * <xsl:value-of select="."/>
* </xsl:template> * </xsl:template>
* *
* Note also that namespaces declarations are copied directly: * Note also that namespace declarations are copied directly:
* *
* the built-in template rule is the only template rule that is applied * the built-in template rule is the only template rule that is applied
* for namespace nodes. * for namespace nodes.
@@ -630,6 +631,7 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
int strip_spaces = -1; int strip_spaces = -1;
int nbchild = 0, oldSize; int nbchild = 0, oldSize;
int childno = 0, oldPos; int childno = 0, oldPos;
int oldBase;
xsltTemplatePtr template; xsltTemplatePtr template;
CHECK_STOPPED; CHECK_STOPPED;
@@ -760,8 +762,11 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
oldNode = ctxt->node; oldNode = ctxt->node;
ctxt->node = node; ctxt->node = node;
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, node, template->content, 1); xsltApplyOneTemplate(ctxt, node, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
ctxt->node = oldNode; ctxt->node = oldNode;
} }
attrs = attrs->next; attrs = attrs->next;
@@ -794,8 +799,11 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
oldNode = ctxt->node; oldNode = ctxt->node;
ctxt->node = node; ctxt->node = node;
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, node, template->content, 1); xsltApplyOneTemplate(ctxt, node, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
ctxt->node = oldNode; ctxt->node = oldNode;
} else /* if (ctxt->mode == NULL) */ { } else /* if (ctxt->mode == NULL) */ {
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
@@ -827,8 +835,11 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
ctxt->xpathCtxt->contextSize = nbchild; ctxt->xpathCtxt->contextSize = nbchild;
ctxt->xpathCtxt->proximityPosition = childno; ctxt->xpathCtxt->proximityPosition = childno;
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, cur, template->content, 1); xsltApplyOneTemplate(ctxt, cur, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
ctxt->node = oldNode; ctxt->node = oldNode;
} else /* if (ctxt->mode == NULL) */ { } else /* if (ctxt->mode == NULL) */ {
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
@@ -869,8 +880,11 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
ctxt->xpathCtxt->contextSize = nbchild; ctxt->xpathCtxt->contextSize = nbchild;
ctxt->xpathCtxt->proximityPosition = childno; ctxt->xpathCtxt->proximityPosition = childno;
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, cur, template->content, 1); xsltApplyOneTemplate(ctxt, cur, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
ctxt->node = oldNode; ctxt->node = oldNode;
} }
break; break;
@@ -894,6 +908,7 @@ void
xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
xsltTemplatePtr template; xsltTemplatePtr template;
xmlNodePtr oldNode; xmlNodePtr oldNode;
int oldBase;
/* /*
* Cleanup children empty nodes if asked for * Cleanup children empty nodes if asked for
@@ -953,8 +968,11 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
template->match, node->name); template->match, node->name);
#endif #endif
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, node, template->content, 1); xsltApplyOneTemplate(ctxt, node, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
} else { } else {
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
if (node->type == XML_DOCUMENT_NODE) if (node->type == XML_DOCUMENT_NODE)
@@ -969,8 +987,11 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
oldNode = ctxt->node; oldNode = ctxt->node;
ctxt->node = node; ctxt->node = node;
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
xsltApplyOneTemplate(ctxt, node, template->content, 1); xsltApplyOneTemplate(ctxt, node, template->content, 1);
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
ctxt->node = oldNode; ctxt->node = oldNode;
} }
} }
@@ -1116,7 +1137,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
cur->name); cur->name);
#endif #endif
/* /*
* Search if there is fallbacks * Search if there are fallbacks
*/ */
child = cur->children; child = cur->children;
while (child != NULL) { while (child != NULL) {
@@ -1211,7 +1232,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: an XSLT processing context * @ctxt: an XSLT processing context
* @node: The current node * @node: The current node
* @inst: the instruction in the stylesheet * @inst: the instruction in the stylesheet
* @comp: precomputed informations * @comp: precomputed information
* *
* Process an XSLT-1.1 document element * Process an XSLT-1.1 document element
*/ */
@@ -1527,7 +1548,7 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltFreeStackElemList(varsPop(ctxt)); xsltFreeStackElemList(varsPop(ctxt));
/* /*
* Save the res * Save the result
*/ */
ret = xsltSaveResultToFilename((const char *) filename, ret = xsltSaveResultToFilename((const char *) filename,
res, style, 0); res, style, 0);
@@ -1570,7 +1591,7 @@ void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node);
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt sort node * @inst: the xslt sort node
* @comp: precomputed informations * @comp: precomputed information
* *
* function attached to xsl:sort nodes, but this should not be * function attached to xsl:sort nodes, but this should not be
* called directly * called directly
@@ -1593,7 +1614,7 @@ xsltSort(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt copy node * @inst: the xslt copy node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt copy node on the source node * Process the xslt copy node on the source node
*/ */
@@ -1706,7 +1727,7 @@ xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt text node * @inst: the xslt text node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt text node on the source node * Process the xslt text node on the source node
*/ */
@@ -1744,7 +1765,7 @@ xsltText(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt element node * @inst: the xslt element node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt element node on the source node * Process the xslt element node on the source node
*/ */
@@ -1868,7 +1889,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt attribute node * @inst: the xslt attribute node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt attribute node on the source node * Process the xslt attribute node on the source node
*/ */
@@ -1898,7 +1919,7 @@ xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
if (ctxt->insert->children != NULL) { if (ctxt->insert->children != NULL) {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsl:attribute : node has already children\n"); "xsl:attribute : node already has children\n");
return; return;
} }
if (comp->name == NULL) { if (comp->name == NULL) {
@@ -1982,7 +2003,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt comment node * @inst: the xslt comment node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt comment node on the source node * Process the xslt comment node on the source node
*/ */
@@ -2016,7 +2037,7 @@ xsltComment(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt processing-instruction node * @inst: the xslt processing-instruction node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt processing-instruction node on the source node * Process the xslt processing-instruction node on the source node
*/ */
@@ -2073,7 +2094,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt copy-of node * @inst: the xslt copy-of node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt copy-of node on the source node * Process the xslt copy-of node on the source node
*/ */
@@ -2172,7 +2193,7 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt value-of node * @inst: the xslt value-of node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt value-of node on the source node * Process the xslt value-of node on the source node
*/ */
@@ -2241,7 +2262,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt number node * @inst: the xslt number node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt number node on the source node * Process the xslt number node on the source node
*/ */
@@ -2269,7 +2290,7 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt apply-imports node * @inst: the xslt apply-imports node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt apply-imports node on the source node * Process the xslt apply-imports node on the source node
*/ */
@@ -2277,6 +2298,7 @@ void
xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst ATTRIBUTE_UNUSED, xsltStylePreCompPtr comp ATTRIBUTE_UNUSED) { xmlNodePtr inst ATTRIBUTE_UNUSED, xsltStylePreCompPtr comp ATTRIBUTE_UNUSED) {
xsltTemplatePtr template; xsltTemplatePtr template;
int oldBase;
if ((ctxt->templ == NULL) || (ctxt->templ->style == NULL)) { if ((ctxt->templ == NULL) || (ctxt->templ->style == NULL)) {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
@@ -2286,10 +2308,13 @@ xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node,
template = xsltGetTemplate(ctxt, node, ctxt->templ->style); template = xsltGetTemplate(ctxt, node, ctxt->templ->style);
if (template != NULL) { if (template != NULL) {
templPush(ctxt, template); templPush(ctxt, template);
oldBase = ctxt->varsBase;
ctxt->varsBase = ctxt->varsNr - 1;
varsPush(ctxt, NULL); varsPush(ctxt, NULL);
xsltApplyOneTemplate(ctxt, node, template->content, 1); xsltApplyOneTemplate(ctxt, node, template->content, 1);
xsltFreeStackElemList(varsPop(ctxt)); xsltFreeStackElemList(varsPop(ctxt));
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase;
} }
} }
@@ -2298,7 +2323,7 @@ xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt call-template node * @inst: the xslt call-template node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt call-template node on the source node * Process the xslt call-template node on the source node
*/ */
@@ -2307,7 +2332,7 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) { xmlNodePtr inst, xsltStylePreCompPtr comp) {
xmlNodePtr cur = NULL; xmlNodePtr cur = NULL;
xsltStackElemPtr params = NULL, param; xsltStackElemPtr params = NULL, param;
int oldBase;
if (ctxt->insert == NULL) if (ctxt->insert == NULL)
return; return;
@@ -2329,10 +2354,6 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
} }
/*
* Create a new frame but block access to variables
*/
templPush(ctxt, comp->templ);
cur = inst->children; cur = inst->children;
while (cur != NULL) { while (cur != NULL) {
if (ctxt->state == XSLT_STATE_STOPPED) break; if (ctxt->state == XSLT_STATE_STOPPED) break;
@@ -2353,10 +2374,17 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
cur = cur->next; cur = cur->next;
} }
/*
* Create a new frame but block access to variables
*/
templPush(ctxt, comp->templ);
oldBase = ctxt->varsBase; /* Save the original variable base */
varsPush(ctxt, params); varsPush(ctxt, params);
ctxt->varsBase = ctxt->varsNr - 1; /* Reset base to be new templ params */
xsltApplyOneTemplate(ctxt, node, comp->templ->content, 1); xsltApplyOneTemplate(ctxt, node, comp->templ->content, 1);
xsltFreeStackElemList(varsPop(ctxt)); xsltFreeStackElemList(varsPop(ctxt));
templPop(ctxt); templPop(ctxt);
ctxt->varsBase = oldBase; /* Restore the original variable base */
} }
/** /**
@@ -2364,7 +2392,7 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the apply-templates node * @inst: the apply-templates node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the apply-templates node on the source node * Process the apply-templates node on the source node
*/ */
@@ -2618,7 +2646,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt choose node * @inst: the xslt choose node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt choose node on the source node * Process the xslt choose node on the source node
*/ */
@@ -2734,7 +2762,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt if node * @inst: the xslt if node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt if node on the source node * Process the xslt if node on the source node
*/ */
@@ -2806,7 +2834,7 @@ error:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @inst: the xslt for-each node * @inst: the xslt for-each node
* @comp: precomputed informations * @comp: precomputed information
* *
* Process the xslt for-each node on the source node * Process the xslt for-each node on the source node
*/ */
@@ -3098,6 +3126,7 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
ctxt->node = (xmlNodePtr) doc; ctxt->node = (xmlNodePtr) doc;
xsltInitCtxtExts(ctxt); xsltInitCtxtExts(ctxt);
varsPush(ctxt, NULL); varsPush(ctxt, NULL);
ctxt->varsBase = ctxt->varsNr - 1;
xsltProcessOneNode(ctxt, ctxt->node); xsltProcessOneNode(ctxt, ctxt->node);
xsltFreeStackElemList(varsPop(ctxt)); xsltFreeStackElemList(varsPop(ctxt));
xsltShutdownCtxtExts(ctxt); xsltShutdownCtxtExts(ctxt);

View File

@@ -230,17 +230,17 @@ xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
int i; int i;
xsltStackElemPtr cur; xsltStackElemPtr cur;
if ((ctxt == NULL) || (name == NULL)) if ((ctxt == NULL) || (name == NULL) || (ctxt->varsNr == 0))
return(NULL); return(NULL);
/* /*
* Do the lookup from the top of the stack, but * Do the lookup from the top of the stack, but
* don't use params being computed in a call-param * don't use params being computed in a call-param
*/ */
i = ctxt->varsNr - 1; ;
for (;i >= 0;i--) { for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
cur = ctxt->varsTab[i]; cur = ctxt->varsTab[i-1];
while (cur != NULL) { while (cur != NULL) {
if (xmlStrEqual(cur->name, name)) { if (xmlStrEqual(cur->name, name)) {
if (nameURI == NULL) { if (nameURI == NULL) {

View File

@@ -344,6 +344,7 @@ struct _xsltTransformContext {
int varsNr; /* Nb of variable list in the stack */ int varsNr; /* Nb of variable list in the stack */
int varsMax; /* Size of the variable list stack */ int varsMax; /* Size of the variable list stack */
xsltStackElemPtr *varsTab; /* the variable list stack */ xsltStackElemPtr *varsTab; /* the variable list stack */
int varsBase; /* the var base for current templ */
/* /*
* Extensions * Extensions