[libxslt] Reserved namespaces in xsl:element and xsl:attribute



commit f6c48211e5ee97b36ae9f3d2f8711fdce38e6e5e
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Wed Aug 15 23:50:22 2012 +0200

    Reserved namespaces in xsl:element and xsl:attribute
    
    For https://bugzilla.gnome.org/show_bug.cgi?id=587360
    
    Correct handling of 'xml' and 'xmlns' namespaces in xsl:element and
    xsl:attribute.

 libxslt/attributes.c      |   14 +++++++++++-
 libxslt/transform.c       |   52 ++++++++++++++++++++++++++------------------
 tests/docs/bug-177.xml    |    1 +
 tests/general/Makefile.am |    1 +
 tests/general/bug-177.out |    2 +
 tests/general/bug-177.xsl |    7 ++++++
 6 files changed, 55 insertions(+), 22 deletions(-)
---
diff --git a/libxslt/attributes.c b/libxslt/attributes.c
index 11d558b..a584d22 100644
--- a/libxslt/attributes.c
+++ b/libxslt/attributes.c
@@ -822,7 +822,19 @@ xsltAttributeInternal(xsltTransformContextPtr ctxt,
 	    if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
 		nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
 	    xmlFree(tmpNsName);		
-	};	    
+	}
+
+        if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/";)) {
+            xsltTransformError(ctxt, NULL, inst,
+                "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ "
+                "forbidden.\n");
+            goto error;
+        }
+        if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
+            prefix = BAD_CAST "xml";
+        } else if (xmlStrEqual(prefix, BAD_CAST "xml")) {
+            prefix = NULL;
+        }
     } else if (prefix != NULL) {
 	/*
 	* SPEC XSLT 1.0:
diff --git a/libxslt/transform.c b/libxslt/transform.c
index bc6d851..4c6b2a5 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -3978,14 +3978,6 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
 	}
 	name = xsltSplitQName(ctxt->dict, prop, &prefix);
 	xmlFree(prop);
-	if ((prefix != NULL) &&
-	    (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
-	{
-	    /*
-	    * TODO: Should we really disallow an "xml" prefix?
-	    */
-	    goto error;
-	}
     } else {
 	/*
 	* The "name" value was static.
@@ -4040,8 +4032,20 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
 	    if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
 		nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
 	    xmlFree(tmpNsName);
-	};
-    } else {
+	}
+
+        if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/";)) {
+            xsltTransformError(ctxt, NULL, inst,
+                "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ "
+                "forbidden.\n");
+            goto error;
+        }
+        if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
+            prefix = BAD_CAST "xml";
+        } else if (xmlStrEqual(prefix, BAD_CAST "xml")) {
+            prefix = NULL;
+        }
+    } else if (prefix != NULL) {
 	xmlNsPtr ns;
 	/*
 	* SPEC XSLT 1.0:
@@ -4056,13 +4060,11 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
 	    * TODO: Check this in the compilation layer in case it's a
 	    * static value.
 	    */
-	    if (prefix != NULL) {
-		xsltTransformError(ctxt, NULL, inst,
-		    "xsl:element: The QName '%s:%s' has no "
-		    "namespace binding in scope in the stylesheet; "
-		    "this is an error, since the namespace was not "
-		    "specified by the instruction itself.\n", prefix, name);
-	    }
+            xsltTransformError(ctxt, NULL, inst,
+                "xsl:element: The QName '%s:%s' has no "
+                "namespace binding in scope in the stylesheet; "
+                "this is an error, since the namespace was not "
+                "specified by the instruction itself.\n", prefix, name);
 	} else
 	    nsName = ns->href;
     }
@@ -4070,7 +4072,17 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
     * Find/create a matching ns-decl in the result tree.
     */
     if (nsName != NULL) {
-	copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix, copy);
+	if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
+            /* Don't use a prefix of "xmlns" */
+	    xmlChar *pref = xmlStrdup(BAD_CAST "ns_1");
+
+	    copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, copy);
+
+	    xmlFree(pref);
+	} else {
+	    copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix,
+		copy);
+	}
     } else if ((copy->parent != NULL) &&
 	(copy->parent->type == XML_ELEMENT_NODE) &&
 	(copy->parent->ns != NULL))
@@ -4427,7 +4439,6 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
     xsltStylePreCompPtr comp = castedComp;
 #endif
     xmlXPathObjectPtr res = NULL;
-    xmlNodePtr copy = NULL;
     xmlChar *value = NULL;
     xmlDocPtr oldXPContextDoc;
     xmlNsPtr *oldXPNamespaces;
@@ -4500,8 +4511,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
 	    goto error;
 	}
 	if (value[0] != 0) {
-	    copy = xsltCopyTextString(ctxt,
-		ctxt->insert, value, comp->noescape);
+	    xsltCopyTextString(ctxt, ctxt->insert, value, comp->noescape);
 	}
     } else {
 	xsltTransformError(ctxt, NULL, inst,
diff --git a/tests/docs/bug-177.xml b/tests/docs/bug-177.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-177.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/Makefile.am b/tests/general/Makefile.am
index c9b2036..e531870 100644
--- a/tests/general/Makefile.am
+++ b/tests/general/Makefile.am
@@ -184,6 +184,7 @@ EXTRA_DIST = \
     bug-174.out bug-174.xsl bug-174.err \
     bug-175.out bug-175.xsl bug-175.err \
     bug-176.out bug-176.xsl \
+    bug-177.out bug-177.xsl \
     bug-178.out bug-178.xsl \
     character.out character.xsl \
     character2.out character2.xsl \
diff --git a/tests/general/bug-177.out b/tests/general/bug-177.out
new file mode 100644
index 0000000..91cd684
--- /dev/null
+++ b/tests/general/bug-177.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<doc xml:id="etc"/>
diff --git a/tests/general/bug-177.xsl b/tests/general/bug-177.xsl
new file mode 100644
index 0000000..52036f5
--- /dev/null
+++ b/tests/general/bug-177.xsl
@@ -0,0 +1,7 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
+    <xsl:template match="/*">
+        <xsl:copy>
+            <xsl:attribute name="id" namespace="http://www.w3.org/XML/1998/namespace";>etc</xsl:attribute>
+        </xsl:copy>
+    </xsl:template>
+</xsl:stylesheet>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]