>From e72c507fac55a4a6d608b616231c9fd247dd18ac Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Tue, 12 Feb 2019 00:56:50 -0800 Subject: [PATCH] LRE attribute must have precedence over attribute sets Process attribute sets first. Then, use xmlSetNsProp to create properties copied from the literal result elements (LREs) - which overwrites the values from attribute sets. Signed-off-by: Alexey Neyman --- libxslt/templates.c | 90 ++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 62 deletions(-) diff --git a/libxslt/templates.c b/libxslt/templates.c index 42559210..12a93951 100644 --- a/libxslt/templates.c +++ b/libxslt/templates.c @@ -645,7 +645,7 @@ xmlAttrPtr xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target, xmlAttrPtr attrs) { - xmlAttrPtr attr, copy, last; + xmlAttrPtr attr, copy; xmlNodePtr oldInsert, text; xmlNsPtr origNs = NULL, copyNs = NULL; const xmlChar *value; @@ -659,15 +659,29 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt, ctxt->insert = target; /* - * Instantiate LRE-attributes. + * Apply attribute-sets. + * The creation of such attributes will not overwrite any existing + * attribute. */ - if (target->properties) { - last = target->properties; - while (last->next != NULL) - last = last->next; - } else { - last = NULL; - } + attr = attrs; + do { +#ifdef XSLT_REFACTORED + if ((attr->psvi == xsltXSLTAttrMarker) && + xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets")) + { + xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL); + } +#else + if ((attr->ns != NULL) && + xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets") && + xmlStrEqual(attr->ns->href, XSLT_NAMESPACE)) + { + xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL); + } +#endif + attr = attr->next; + } while (attr != NULL); + attr = attrs; do { /* @@ -702,34 +716,6 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt, } else value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0); - /* - * Create a new attribute. - */ - copy = xmlNewDocProp(target->doc, attr->name, NULL); - if (copy == NULL) { - if (attr->ns) { - xsltTransformError(ctxt, NULL, attr->parent, - "Internal error: Failed to create attribute '{%s}%s'.\n", - attr->ns->href, attr->name); - } else { - xsltTransformError(ctxt, NULL, attr->parent, - "Internal error: Failed to create attribute '%s'.\n", - attr->name); - } - goto error; - } - /* - * Attach it to the target element. - */ - copy->parent = target; - if (last == NULL) { - target->properties = copy; - last = copy; - } else { - last->next = copy; - copy->prev = last; - last = copy; - } /* * Set the namespace. Avoid lookups of same namespaces. */ @@ -748,7 +734,11 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt, } else copyNs = NULL; } - copy->ns = copyNs; + + // xmlSetNsProp will take care of the duplicates + copy = xmlSetNsProp(ctxt->insert, copyNs, attr->name, NULL); + if (copy == NULL) + goto error; /* * Set the value. @@ -803,30 +793,6 @@ next_attribute: attr = attr->next; } while (attr != NULL); - /* - * Apply attribute-sets. - * The creation of such attributes will not overwrite any existing - * attribute. - */ - attr = attrs; - do { -#ifdef XSLT_REFACTORED - if ((attr->psvi == xsltXSLTAttrMarker) && - xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets")) - { - xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL); - } -#else - if ((attr->ns != NULL) && - xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets") && - xmlStrEqual(attr->ns->href, XSLT_NAMESPACE)) - { - xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL); - } -#endif - attr = attr->next; - } while (attr != NULL); - ctxt->insert = oldInsert; return(target->properties); -- 2.19.1