From 0503357eba2199d1cad0d6fe209d141d97d1c9ee Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sat, 16 Mar 2002 22:50:56 +0000 Subject: [PATCH] chaing result tree values which may be deallocated and must not be kept in * libexslt/common.c libxslt/pattern.c libxslt/transform.c libxslt/variables.c: chaing result tree values which may be deallocated and must not be kept in the template pattern lookup cache. Thanks to Valgrin to allow finding the real problem in bug #74857 Daniel --- ChangeLog | 8 +++++ libexslt/common.c | 3 +- libxslt/pattern.c | 98 +++++++++++++++++++++++++++++++++++++++-------------- libxslt/transform.c | 7 ++-- libxslt/variables.c | 10 ++++++ 5 files changed, 96 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef4a0e8..77b4756 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat Mar 16 23:48:21 CET 2002 Daniel Veillard + + * libexslt/common.c libxslt/pattern.c libxslt/transform.c + libxslt/variables.c: chaing result tree values which may + be deallocated and must not be kept in the template + pattern lookup cache. Thanks to Valgrin to allow finding + the real problem in bug #74857 + Wed Mar 13 15:17:51 CET 2002 Daniel Veillard * libxslt/*.h doc/* python/*: applied another cleanup comment diff --git a/libexslt/common.c b/libexslt/common.c index fbc3787..e759a28 100644 --- a/libexslt/common.c +++ b/libexslt/common.c @@ -37,8 +37,7 @@ exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) { } strval = xmlXPathPopString (ctxt); - retNode = xmlNewDocText (xsltXPathGetTransformContext(ctxt)->output, - strval); + retNode = xmlNewDocText (NULL, strval); ret = xmlXPathNewValueTree (retNode); ret->type = XPATH_NODESET; diff --git a/libxslt/pattern.c b/libxslt/pattern.c index 61c9b49..1f45de5 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -648,7 +648,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, (node->type == XML_ELEMENT_NODE) && (node->parent != NULL)) { xmlNodePtr previous; - int index; + int index, nocache = 0; previous = (xmlNodePtr) XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra); @@ -691,12 +691,18 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } if (sibling != NULL) { pos = index + indx; - len = (int) - XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); - XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = - node; - XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = - (void *) pos; + /* + * If the node is in a Value Tree we cannot + * cache it ! + */ + if (node->doc != NULL) { + len = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); + XSLT_RUNTIME_EXTRA(ctxt, + select->previousExtra) = node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + } index = pos; } else pos = 0; @@ -705,6 +711,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, * recompute the index */ xmlNodePtr siblings = node->parent->children; + xmlNodePtr parent = node->parent; while (siblings != NULL) { if (siblings->type == XML_ELEMENT_NODE) { @@ -722,21 +729,37 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } siblings = siblings->next; } + if ((parent == NULL) || (node->doc == NULL)) + nocache = 1; + else { + while (parent->parent != NULL) + parent = parent->parent; + if (((parent->type != XML_DOCUMENT_NODE) && + (parent->type != XML_HTML_DOCUMENT_NODE)) || + (parent != (xmlNodePtr) node->doc)) + nocache = 1; + } } if (pos != 0) { ctxt->xpathCtxt->contextSize = len; ctxt->xpathCtxt->proximityPosition = pos; - XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = - node; - XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = - (void *) pos; - XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = - (void *) len; + /* + * If the node is in a Value Tree we cannot + * cache it ! + */ + if ((node->doc != NULL) && (nocache == 0)) { + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = + (void *) len; + } } } else if ((select != NULL) && (select->op == XSLT_OP_ALL) && (node->type == XML_ELEMENT_NODE)) { xmlNodePtr previous; - int index; + int index, nocache; previous = (xmlNodePtr) XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra); @@ -771,12 +794,18 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } if (sibling != NULL) { pos = index + indx; - len = (int) - XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); - XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = - node; - XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = - (void *) pos; + /* + * If the node is in a Value Tree we cannot + * cache it ! + */ + if (node->doc != NULL) { + len = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); + XSLT_RUNTIME_EXTRA(ctxt, + select->previousExtra) = node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + } } else pos = 0; } else { @@ -784,6 +813,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, * recompute the index */ xmlNodePtr siblings = node->parent->children; + xmlNodePtr parent = node->parent; while (siblings != NULL) { if (siblings->type == XML_ELEMENT_NODE) { @@ -794,16 +824,32 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } siblings = siblings->next; } + if ((parent == NULL) || (node->doc == NULL)) + nocache = 1; + else { + while (parent->parent != NULL) + parent = parent->parent; + if (((parent->type != XML_DOCUMENT_NODE) && + (parent->type != XML_HTML_DOCUMENT_NODE)) || + (parent != (xmlNodePtr) node->doc)) + nocache = 1; + } } if (pos != 0) { ctxt->xpathCtxt->contextSize = len; ctxt->xpathCtxt->proximityPosition = pos; - XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = - node; - XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = - (void *) pos; - XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = - (void *) len; + /* + * If the node is in a Value Tree we cannot + * cache it ! + */ + if ((node->doc != NULL) && (nocache == 0)) { + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = + (void *) len; + } } } oldNode = ctxt->node; diff --git a/libxslt/transform.c b/libxslt/transform.c index 99f26f3..10d3b9c 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -2863,10 +2863,13 @@ error: ctxt->node = oldNode; ctxt->mode = oldMode; ctxt->modeURI = oldModeURI; - if (res != NULL) - xmlXPathFreeObject(res); if (list != NULL) xmlXPathFreeNodeSet(list); + /* + * res must be deallocated after list + */ + if (res != NULL) + xmlXPathFreeObject(res); } diff --git a/libxslt/variables.c b/libxslt/variables.c index 386af10..9c42687 100644 --- a/libxslt/variables.c +++ b/libxslt/variables.c @@ -357,16 +357,21 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem, */ xmlNodePtr container; xmlNodePtr oldInsert; + xmlDocPtr oldoutput; container = xmlNewDocNode(ctxt->document->doc, NULL, (const xmlChar *) "fake node libxslt", NULL); if (container == NULL) return(NULL); + container->parent = NULL; + oldoutput = ctxt->output; + ctxt->output = NULL; oldInsert = ctxt->insert; ctxt->insert = container; xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL); ctxt->insert = oldInsert; + ctxt->output = oldoutput; result = xmlXPathNewValueTree(container); if (result == NULL) { @@ -483,16 +488,21 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt) { */ xmlNodePtr container; xmlNodePtr oldInsert; + xmlDocPtr oldoutput; container = xmlNewDocNode(ctxt->document->doc, NULL, (const xmlChar *) "fake node libxslt", NULL); if (container == NULL) return(NULL); + container->parent = NULL; + oldoutput = ctxt->output; + ctxt->output = NULL; oldInsert = ctxt->insert; ctxt->insert = container; xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL); ctxt->insert = oldInsert; + ctxt->output = oldoutput; result = xmlXPathNewValueTree(container); if (result == NULL) { -- 2.7.4