[libxslt] Fix handling of names in xsl:attribute



commit d7a5a69990345838d1c5d1b23280caa1c842a949
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Thu Aug 16 02:18:31 2012 +0200

    Fix handling of names in xsl:attribute
    
    A prefix of 'xmlns' is actually allowed. It should simply be ignored
    if a namespace is given. Without a namespace the lookup by prefix will
    fail anyway.
    
    What the spec doesn't allow is an attribute name of 'xmlns' which will
    now be rejected.

 libxslt/attributes.c     |   31 +++++++++----------------------
 libxslt/preproc.c        |   25 ++++---------------------
 tests/REC/test-7.1.3.out |    2 +-
 3 files changed, 14 insertions(+), 44 deletions(-)
---
diff --git a/libxslt/attributes.c b/libxslt/attributes.c
index a584d22..ca81bdb 100644
--- a/libxslt/attributes.c
+++ b/libxslt/attributes.c
@@ -750,31 +750,19 @@ xsltAttributeInternal(xsltTransformContextPtr ctxt,
 		"valid QName.\n", prop);
 	    /* we fall through to catch any further errors, if possible */
 	}
-	name = xsltSplitQName(ctxt->dict, prop, &prefix);
-	xmlFree(prop);
 
 	/*
-	* Reject a prefix of "xmlns".
+	* Reject a name of "xmlns".
 	*/
-	if ((prefix != NULL) &&
-	    (!xmlStrncasecmp(prefix, (xmlChar *) "xmlns", 5)))
-	{
-#ifdef WITH_XSLT_DEBUG_PARSING
-	    xsltGenericDebug(xsltGenericDebugContext,
-		"xsltAttribute: xmlns prefix forbidden\n");
-#endif
-	    /*
-	    * SPEC XSLT 1.0:
-	    *  "It is an error if the string that results from instantiating
-	    *  the attribute value template is not a QName or is the string
-	    *  xmlns. An XSLT processor may signal the error; if it does not
-	    *  signal the error, it must recover by not adding the attribute
-	    *  to the result tree."
-	    * TODO: Decide which way to go here.
-	    */
+	if (xmlStrEqual(prop, BAD_CAST "xmlns")) {
+            xsltTransformError(ctxt, NULL, inst,
+                "xsl:attribute: The effective name 'xmlns' is not allowed.\n");
+	    xmlFree(prop);
 	    goto error;
 	}
 
+	name = xsltSplitQName(ctxt->dict, prop, &prefix);
+	xmlFree(prop);
     } else {
 	/*
 	* The "name" value was static.
@@ -909,11 +897,10 @@ xsltAttributeInternal(xsltTransformContextPtr ctxt,
 	* xsl:attribute can produce a scenario where the prefix is NULL,
 	* so generate a prefix.
 	*/
-	if (prefix == NULL) {
+	if ((prefix == NULL) || xmlStrEqual(prefix, BAD_CAST "xmlns")) {
 	    xmlChar *pref = xmlStrdup(BAD_CAST "ns_1");
 
-	    ns = xsltGetSpecialNamespace(ctxt, inst, nsName, BAD_CAST pref,
-		targetElem);
+	    ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, targetElem);
 
 	    xmlFree(pref);
 	} else {
diff --git a/libxslt/preproc.c b/libxslt/preproc.c
index 4d483ff..ebd2fc1 100644
--- a/libxslt/preproc.c
+++ b/libxslt/preproc.c
@@ -1048,6 +1048,10 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
 		"xsl:attribute: The value '%s' of the attribute 'name' is "
 		"not a valid QName.\n", comp->name);
 	    style->errors++;
+        } else if (xmlStrEqual(comp->name, BAD_CAST "xmlns")) {
+	    xsltTransformError(NULL, style, inst,
+                "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
+	    style->errors++;
 	} else {
 	    const xmlChar *prefix = NULL, *name;
 
@@ -1081,27 +1085,6 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
 			style->errors++;
 		    }
 		}
-		if (!xmlStrncasecmp(prefix, (xmlChar *) "xmlns", 5)) {
-		    /*
-		    * SPEC XSLT 1.0:
-		    *  "It is an error if the string that results from
-		    *  instantiating the attribute value template is not a
-		    *  QName or is the string xmlns. An XSLT processor may
-		    *  signal the error; if it does not signal the error,
-		    *  it must recover by not adding the attribute to the
-		    *  result tree."
-		    *
-		    * Reject a prefix of "xmlns". Mark to be skipped.
-		    */
-		    comp->has_name = 0;
-		    
-#ifdef WITH_XSLT_DEBUG_PARSING
-		    xsltGenericDebug(xsltGenericDebugContext,
-			"xsltAttribute: xmlns prefix forbidden\n");
-#endif		    
-		    return;
-		}
-		
 	    }
 	}	
     }
diff --git a/tests/REC/test-7.1.3.out b/tests/REC/test-7.1.3.out
index dee0832..652fd9c 100644
--- a/tests/REC/test-7.1.3.out
+++ b/tests/REC/test-7.1.3.out
@@ -1,2 +1,2 @@
 <?xml version="1.0"?>
-<doc attr="value"/>
+<doc xmlns:ns_1="whatever" ns_1:xsl="http://www.w3.org/1999/XSL/Transform"; attr="value"/>



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