chaing result tree values which may be deallocated and must not be kept in
authorDaniel Veillard <veillard@src.gnome.org>
Sat, 16 Mar 2002 22:50:56 +0000 (22:50 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Sat, 16 Mar 2002 22:50:56 +0000 (22:50 +0000)
* 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
libexslt/common.c
libxslt/pattern.c
libxslt/transform.c
libxslt/variables.c

index ef4a0e8..77b4756 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Mar 16 23:48:21 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+       * 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 <daniel@veillard.com>
 
        * libxslt/*.h doc/* python/*: applied another cleanup comment
index fbc3787..e759a28 100644 (file)
@@ -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;
 
index 61c9b49..1f45de5 100644 (file)
@@ -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;
index 99f26f3..10d3b9c 100644 (file)
@@ -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);
 }
 
 
index 386af10..9c42687 100644 (file)
@@ -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) {