fix bug #110577 namespace in copy-of don't obbey the same rules as for
authorDaniel Veillard <veillard@src.gnome.org>
Wed, 23 Apr 2003 12:30:07 +0000 (12:30 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Wed, 23 Apr 2003 12:30:07 +0000 (12:30 +0000)
* libxslt/transform.c: fix bug #110577 namespace in copy-of
  don't obbey the same rules as for literal reusl elements.
* tests/docs/Makefile.am tests/docs/bug-118.*
  tests/general/Makefile.am tests/general/bug-118*: added the
  example in the regression tests for that bug.
* libxslt/variables.c: fixed a bug introduced in fixing #110020
* tests/docs/Makefile.am tests/docs/bug-11[67].*
  tests/general/Makefile.am tests/general/bug-11[67]*: added 2
  regression tests one still exposing a mem leak (Mark Vadoc).
Daniel

14 files changed:
ChangeLog
libxslt/transform.c
libxslt/variables.c
tests/docs/Makefile.am
tests/docs/bug-116.xml [new file with mode: 0644]
tests/docs/bug-117.xml [new file with mode: 0644]
tests/docs/bug-118.xml [new file with mode: 0644]
tests/general/Makefile.am
tests/general/bug-116.out [new file with mode: 0644]
tests/general/bug-116.xsl [new file with mode: 0644]
tests/general/bug-117.out [new file with mode: 0644]
tests/general/bug-117.xsl [new file with mode: 0644]
tests/general/bug-118.out [new file with mode: 0644]
tests/general/bug-118.xsl [new file with mode: 0644]

index d2ec68c..fa9fb93 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Wed Apr 23 14:25:46 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+       * libxslt/transform.c: fix bug #110577 namespace in copy-of
+         don't obbey the same rules as for literal reusl elements.
+       * tests/docs/Makefile.am tests/docs/bug-118.*
+         tests/general/Makefile.am tests/general/bug-118*: added the
+         example in the regression tests for that bug.
+       * libxslt/variables.c: fixed a bug introduced in fixing #110020
+       * tests/docs/Makefile.am tests/docs/bug-11[67].*
+         tests/general/Makefile.am tests/general/bug-11[67]*: added 2
+         regression tests one still exposing a mem leak (Mark Vadoc).
+
 Tue Apr 22 16:01:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
        * libxslt/pattern.c: fix a memory related segfault on a
index fa09458..e0f1adf 100644 (file)
@@ -473,8 +473,8 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
  *                                                                     *
  ************************************************************************/
 
-xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
-                       xmlNodePtr insert);
+xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt,
+                        xmlNodePtr node, xmlNodePtr insert, int literal);
 
 /**
  * xsltCopyTextString:
@@ -738,19 +738,22 @@ xsltCopyNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
  * @ctxt:  a XSLT process context
  * @list:  the list of element nodes in the source tree.
  * @insert:  the parent in the result tree.
+ * @literal:  is this a literal result element list
  *
  * Make a copy of the full list of tree @list
  * and insert it as last children of @insert
+ * For literal result element, some of the namespaces may not be copied
+ * over according to section 7.1 .
  *
  * Returns a pointer to the new list, or NULL in case of error
  */
 static xmlNodePtr
 xsltCopyTreeList(xsltTransformContextPtr ctxt, xmlNodePtr list,
-            xmlNodePtr insert) {
+            xmlNodePtr insert, int literal) {
     xmlNodePtr copy, ret = NULL;
 
     while (list != NULL) {
-       copy = xsltCopyTree(ctxt, list, insert);
+       copy = xsltCopyTree(ctxt, list, insert, literal);
        if (copy != NULL) {
            if (ret == NULL) {
                ret = copy;
@@ -762,19 +765,74 @@ xsltCopyTreeList(xsltTransformContextPtr ctxt, xmlNodePtr list,
 }
 
 /**
+ * xsltCopyNamespaceListInternal:
+ * @node:  the target node
+ * @cur:  the first namespace
+ *
+ * Do a copy of an namespace list. If @node is non-NULL the
+ * new namespaces are added automatically.
+ *
+ * Returns: a new xmlNsPtr, or NULL in case of error.
+ */
+static xmlNsPtr
+xsltCopyNamespaceListInternal(xmlNodePtr node, xmlNsPtr cur) {
+    xmlNsPtr ret = NULL;
+    xmlNsPtr p = NULL,q;
+
+    if (cur == NULL)
+       return(NULL);
+    if (cur->type != XML_NAMESPACE_DECL)
+       return(NULL);
+
+    /*
+     * One can add namespaces only on element nodes
+     */
+    if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
+       node = NULL;
+
+    while (cur != NULL) {
+       if (cur->type != XML_NAMESPACE_DECL)
+           break;
+
+       /*
+        * Avoid duplicating namespace declrations on the tree
+        */
+       if ((node != NULL) && (node->ns != NULL) &&
+            (xmlStrEqual(node->ns->href, cur->href)) &&
+            (xmlStrEqual(node->ns->prefix, cur->prefix))) {
+           cur = cur->next;
+           continue;
+       }
+       
+       q = xmlNewNs(node, cur->href, cur->prefix);
+       if (p == NULL) {
+           ret = p = q;
+       } else if (q != NULL) {
+           p->next = q;
+           p = q;
+       }
+       cur = cur->next;
+    }
+    return(ret);
+}
+
+/**
  * xsltCopyTree:
  * @ctxt:  a XSLT process context
  * @node:  the element node in the source tree.
  * @insert:  the parent in the result tree.
+ * @literal:  is this a literal result element list
  *
  * Make a copy of the full tree under the element node @node
  * and insert it as last child of @insert
+ * For literal result element, some of the namespaces may not be copied
+ * over according to section 7.1 .
  *
  * Returns a pointer to the new tree, or NULL in case of error
  */
 xmlNodePtr
 xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
-            xmlNodePtr insert) {
+                    xmlNodePtr insert, int literal) {
     xmlNodePtr copy;
 
     if (node == NULL)
@@ -817,7 +875,7 @@ xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
     if ((node->name != NULL) && (node->name[0] == ' ') &&
        (xmlStrEqual(node->name, (const xmlChar *) " fake node libxslt"))) {
        if (node->children != NULL)
-           copy = xsltCopyTreeList(ctxt, node->children, insert);
+           copy = xsltCopyTreeList(ctxt, node->children, insert, 0);
        else
            copy = NULL;
        return(copy);
@@ -849,13 +907,17 @@ xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
                    xmlNewNs(copy, BAD_CAST "", NULL);
            }
        }
-       if (node->nsDef != NULL)
-           xsltCopyNamespaceList(ctxt, copy, node->nsDef);
+       if (node->nsDef != NULL) {
+           if (literal)
+               xsltCopyNamespaceList(ctxt, copy, node->nsDef);
+           else
+               xsltCopyNamespaceListInternal(copy, node->nsDef);
+       }
        if (node->properties != NULL)
            copy->properties = xsltCopyPropList(ctxt, copy,
                                               node->properties);
        if (node->children != NULL)
-           xsltCopyTreeList(ctxt, node->children, copy);
+           xsltCopyTreeList(ctxt, node->children, copy, literal);
     } else {
        xsltTransformError(ctxt, NULL, node,
                "xsltCopyTree: copy %s failed\n", node->name);
@@ -2601,12 +2663,12 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
                    if ((list->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
                        (list->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) {
                        xsltCopyTreeList(ctxt, list->nodeTab[i]->children,
-                                        ctxt->insert);
+                                        ctxt->insert, 0);
                    } else if (list->nodeTab[i]->type == XML_ATTRIBUTE_NODE) {
                        xsltCopyProp(ctxt, ctxt->insert, 
                                     (xmlAttrPtr) list->nodeTab[i]);
                    } else {
-                       xsltCopyTree(ctxt, list->nodeTab[i], ctxt->insert);
+                       xsltCopyTree(ctxt, list->nodeTab[i], ctxt->insert, 0);
                    }
                }
            }
@@ -2620,7 +2682,7 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
                (list->nodeTab[0] != NULL) &&
                (IS_XSLT_REAL_NODE(list->nodeTab[0]))) {
                xsltCopyTreeList(ctxt, list->nodeTab[0]->children,
-                                ctxt->insert);
+                                ctxt->insert, 0);
            }
        } else {
            /* convert to a string */
index c52d025..ad00d2a 100644 (file)
@@ -812,24 +812,23 @@ xsltProcessUserParamInternal(xsltTransformContextPtr ctxt,
            "Global parameter %s already defined\n", ncname);
     }
 
+    /*
+     * do not overwrite variables with parameters from the command line
+     */
     while (style != NULL) {
         elem = ctxt->style->variables;
        while (elem != NULL) {
            if ((elem->comp != NULL) &&
-               (elem->comp->type == XSLT_FUNC_PARAM) &&
+               (elem->comp->type == XSLT_FUNC_VARIABLE) &&
                (xmlStrEqual(elem->name, ncname)) &&
-               (xmlStrEqual(elem->nameURI, href)))
-               goto found;
+               (xmlStrEqual(elem->nameURI, href))) {
+               xmlFree(ncname);
+               return(0);
+           }
             elem = elem->next;
        }
         style = xsltNextImport(style);
     }
-    /*
-     * the parameter was not registered in the stylesheet(s), ignore it.
-     */
-    xmlFree(ncname);
-    return(0);
-found:
     style = ctxt->style;
     elem = NULL;
 
index 39c374e..5fa0069 100644 (file)
@@ -115,6 +115,9 @@ EXTRA_DIST =        \
        bug-113.xml \
        bug-114.xml \
        bug-115.xml \
+       bug-116.xml \
+       bug-117.xml \
+       bug-118.xml \
        character.xml \
        array.xml \
        items.xml
diff --git a/tests/docs/bug-116.xml b/tests/docs/bug-116.xml
new file mode 100644 (file)
index 0000000..69d62f2
--- /dev/null
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/docs/bug-117.xml b/tests/docs/bug-117.xml
new file mode 100644 (file)
index 0000000..4369f10
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+
+<l:doc xmlns:l="http://www.foobar.com/xmlns/l">
+        <l:doc-head>
+                <l:doc-title>Doc Title</l:doc-title>
+        </l:doc-head>
+        <l:doc-content>
+                <l:p>Hello World!</l:p>
+        </l:doc-content>
+</l:doc>
diff --git a/tests/docs/bug-118.xml b/tests/docs/bug-118.xml
new file mode 100644 (file)
index 0000000..7b8a7dd
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+    xmlns:ex="http://www.example.org/"
+    >
+</root>
index 938bfb3..df0f01f 100644 (file)
@@ -120,6 +120,9 @@ EXTRA_DIST = \
     bug-113.out bug-113.xsl \
     bug-114.out bug-114.xsl \
     bug-115.out bug-115.xsl \
+    bug-115.out bug-116.xsl \
+    bug-115.out bug-117.xsl \
+    bug-115.out bug-118.xsl \
     character.out character.xsl \
     character2.out character2.xsl \
     itemschoose.out itemschoose.xsl \
diff --git a/tests/general/bug-116.out b/tests/general/bug-116.out
new file mode 100644 (file)
index 0000000..3048a90
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<results/>
diff --git a/tests/general/bug-116.xsl b/tests/general/bug-116.xsl
new file mode 100644 (file)
index 0000000..ea6940e
--- /dev/null
@@ -0,0 +1,22 @@
+<xsl:stylesheet version="1.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:set="http://exslt.org/sets"
+ extension-element-prefixes="exsl set"
+ exclude-result-prefixes="exsl set"
+>
+
+<xsl:output method="xml"/>
+
+<!-- This works as is.  Comment out the p element and un-comment the error line. -->
+<xsl:template match="/">
+ <results>
+   <xsl:variable name="n">
+   <p></p>
+   </xsl:variable>
+   <xsl:copy-of select="set:distinct(exsl:node-set($n)/p/a)"/>
+ </results>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/tests/general/bug-117.out b/tests/general/bug-117.out
new file mode 100644 (file)
index 0000000..6c9cb8b
--- /dev/null
@@ -0,0 +1,5 @@
+<s:doc xmlns:s="http://www.foobar.com/xmlns/s"><s:doc-head>
+                <s:doc-title>Doc Title</s:doc-title>
+        </s:doc-head><s:doc-body><s:div class="header"><s:a href="/"><s:img src="/images/logo/mylogo.jpg" width="200" height="100" border="0" title="LOGO" alt="LOGO"></s:img></s:a></s:div><s:br></s:br><s:div class="body">
+                <s:p>Hello World!</s:p>
+        </s:div></s:doc-body></s:doc>
diff --git a/tests/general/bug-117.xsl b/tests/general/bug-117.xsl
new file mode 100644 (file)
index 0000000..b1e2da6
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:l="http://www.foobar.com/xmlns/l"
+                xmlns:s="http://www.foobar.com/xmlns/s"
+                xmlns:exsl="http://exslt.org/common"
+                exclude-result-prefixes="l"
+                extension-element-prefixes="exsl"
+>
+
+<xsl:output method="html" media-type="text/html" encoding="ISO-8859-1" />
+
+<xsl:template match="/">
+        <xsl:apply-templates select="l:doc" />
+</xsl:template>
+
+<xsl:template match="l:doc">
+        <s:doc>
+                <xsl:for-each select="@*">
+                        <xsl:attribute name="{name()}"><xsl:value-of
+select="."/></xsl:attribute>
+                </xsl:for-each>
+                <s:doc-head>
+                        <xsl:apply-templates select="l:doc-head"/>
+                </s:doc-head>
+                <s:doc-body>
+                        <s:div class="header">
+                                <s:a href="/">
+                                        <s:img
+src="/images/logo/mylogo.jpg" width="200" height="100" border="0"
+title="LOGO" alt="LOGO"/>
+                                </s:a>
+                        </s:div>
+                        <s:br/>
+                        <s:div class="body">
+                                <xsl:apply-templates select="l:doc-content"/>
+                        </s:div>
+                </s:doc-body>
+        </s:doc>
+</xsl:template>
+
+<xsl:template match="l:doc-title">
+        <s:doc-title><xsl:apply-templates/></s:doc-title>
+</xsl:template>
+
+<!-- some HTML-like elements -->
+<xsl:template
+match="l:a|l:abbr|l:acronym|l:address|l:area|l:b|l:base|l:bdo|l:big|l:blockquote|l:body|l:br|l:button|l:caption|l:cite|l:code|l:col|l:colgroup|l:dd|l:del|l:dfn|l:div|l:dl|l:dt|l:em|l:fieldset|l:form|l:frame|l:framset|l:h1|l:h2|l:h3|l:h4|l:h5|l:h6|l:head|l:hr|l:i|l:iframe|l:img|l:input|l:ins|l:kbd|l:label|l:legend|l:li|l:link|l:map|l:noframes|l:noscript|l:object|l:ol|l:optgroup|l:option|l:p|l:param|l:pre|l:q|l:samp|l:script|l:select|l:small|l:span|l:strong|l:style|l:sub|l:sup|l:table|l:tbody|l:td|l:textarea|l:tfoot|l:th|l:thead|l:tr|l:tt|l:ul|l:var">
+        <xsl:element name="s:{local-name()}">
+                <xsl:for-each select="@*">
+                        <xsl:attribute name="{name()}"><xsl:value-of
+select="." /></xsl:attribute>
+                </xsl:for-each>
+                <xsl:apply-templates />
+        </xsl:element>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-118.out b/tests/general/bug-118.out
new file mode 100644 (file)
index 0000000..c190ef5
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<root xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ex="http://www.example.org/">
+</root>
diff --git a/tests/general/bug-118.xsl b/tests/general/bug-118.xsl
new file mode 100644 (file)
index 0000000..37cf296
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<xsl:stylesheet 
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+    xmlns:ex="http://www.example.org/"
+    version="1.0"
+    >
+
+<xsl:output method="xml" />
+
+<xsl:template match="/">
+<xsl:copy-of select="/" />
+</xsl:template>
+
+</xsl:stylesheet>