Fix handling of names in xsl:attribute
authorNick Wellnhofer <wellnhofer@aevum.de>
Thu, 16 Aug 2012 00:18:31 +0000 (02:18 +0200)
committerDaniel Veillard <veillard@redhat.com>
Thu, 6 Sep 2012 13:58:42 +0000 (21:58 +0800)
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
libxslt/preproc.c
tests/REC/test-7.1.3.out

index a584d22..ca81bdb 100644 (file)
@@ -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 {
index 4d483ff..ebd2fc1 100644 (file)
@@ -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;
-               }
-               
            }
        }       
     }
index dee0832..652fd9c 100644 (file)
@@ -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"/>