diff options
Diffstat (limited to 'gnu/packages/patches/libxslt-generated-ids.patch')
-rw-r--r-- | gnu/packages/patches/libxslt-generated-ids.patch | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/gnu/packages/patches/libxslt-generated-ids.patch b/gnu/packages/patches/libxslt-generated-ids.patch new file mode 100644 index 0000000000..4273875c7c --- /dev/null +++ b/gnu/packages/patches/libxslt-generated-ids.patch @@ -0,0 +1,173 @@ +This makes generated IDs deterministic. + +Written by Daniel Veillard. + +This should be fixed in next release (2.29). +See https://bugzilla.gnome.org/show_bug.cgi?id=751621. + +diff --git a/libxslt/functions.c b/libxslt/functions.c +index 6448bde..5b00a6d 100644 +--- a/libxslt/functions.c ++++ b/libxslt/functions.c +@@ -651,6 +651,63 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) + } + + /** ++ * xsltCleanupIds: ++ * @ctxt: the transformation context ++ * @root: the root of the resulting document ++ * ++ * This clean up ids which may have been saved in Element contents ++ * by xsltGenerateIdFunction() to provide stable IDs on elements. ++ * ++ * Returns the number of items cleaned or -1 in case of error ++ */ ++int ++xsltCleanupIds(xsltTransformContextPtr ctxt, xmlNodePtr root) { ++ xmlNodePtr cur; ++ int count = 0; ++ ++ if ((ctxt == NULL) || (root == NULL)) ++ return(-1); ++ if (root->type != XML_ELEMENT_NODE) ++ return(-1); ++ ++ cur = root; ++ while (cur != NULL) { ++ if (cur->type == XML_ELEMENT_NODE) { ++ if (cur->content != NULL) { ++ cur->content = NULL; ++ count++; ++ } ++ if (cur->children != NULL) { ++ cur = cur->children; ++ continue; ++ } ++ } ++ if (cur->next != NULL) { ++ cur = cur->next; ++ continue; ++ } ++ do { ++ cur = cur->parent; ++ if (cur == NULL) ++ break; ++ if (cur == (xmlNodePtr) root) { ++ cur = NULL; ++ break; ++ } ++ if (cur->next != NULL) { ++ cur = cur->next; ++ break; ++ } ++ } while (cur != NULL); ++ } ++ ++fprintf(stderr, "Attributed %d IDs for element, cleaned up %d\n", ++ ctxt->nextid, count); ++ ++ return(count); ++} ++ ++/** + * xsltGenerateIdFunction: + * @ctxt: the XPath Parser context + * @nargs: the number of arguments +@@ -701,7 +758,39 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ + if (obj) + xmlXPathFreeObject(obj); + +- val = (long)((char *)cur - (char *)&base_address); ++ /* ++ * Try to provide stable ID for generated document: ++ * - usually ID are computed to be placed on elements via attributes ++ * so using the element as the node for the ID ++ * - the cur->content should be a correct placeholder for this, we use ++ * it to hold element node numbers in xmlXPathOrderDocElems to ++ * speed up XPath too ++ * - xsltCleanupIds() clean them up before handing the XSLT output ++ * to the API client. ++ * - other nodes types use the node address method but that should ++ * not end up in resulting document ID ++ * - we can enable this by default without risk of performance issues ++ * only the one pass xsltCleanupIds() is added ++ */ ++ if (cur->type == XML_ELEMENT_NODE) { ++ if (cur->content == NULL) { ++ xsltTransformContextPtr tctxt; ++ ++ tctxt = xsltXPathGetTransformContext(ctxt); ++ if (tctxt == NULL) { ++ val = (long)((char *)cur - (char *)&base_address); ++ } else { ++ tctxt->nextid++; ++ val = tctxt->nextid; ++ cur->content = (void *) (val); ++ } ++ } else { ++ val = (long) cur->content; ++ } ++ } else { ++ val = (long)((char *)cur - (char *)&base_address); ++ } ++ + if (val >= 0) { + sprintf((char *)str, "idp%ld", val); + } else { +diff --git a/libxslt/functions.h b/libxslt/functions.h +index e0e0bf9..4a1e163 100644 +--- a/libxslt/functions.h ++++ b/libxslt/functions.h +@@ -64,6 +64,13 @@ XSLTPUBFUN void XSLTCALL + int nargs); + + /* ++ * Cleanup for ID generation ++ */ ++XSLTPUBFUN int XSLTCALL ++ xsltCleanupIds (xsltTransformContextPtr ctxt, ++ xmlNodePtr root); ++ ++/* + * And the registration + */ + +diff --git a/libxslt/transform.c b/libxslt/transform.c +index 24f9eb2..2bdf6bf 100644 +--- a/libxslt/transform.c ++++ b/libxslt/transform.c +@@ -700,6 +700,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { + cur->traceCode = (unsigned long*) &xsltDefaultTrace; + cur->xinclude = xsltGetXIncludeDefault(); + cur->keyInitLevel = 0; ++ cur->nextid = 0; + + return(cur); + +@@ -6092,6 +6093,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, + if (root != NULL) { + const xmlChar *doctype = NULL; + ++ /* ++ * cleanup ids which may have been saved in Elements content ptrs ++ */ ++ if (ctxt->nextid != 0) { ++ xsltCleanupIds(ctxt, root); ++ } ++ + if ((root->ns != NULL) && (root->ns->prefix != NULL)) + doctype = xmlDictQLookup(ctxt->dict, root->ns->prefix, root->name); + if (doctype == NULL) +diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h +index 95e8fe6..8eedae4 100644 +--- a/libxslt/xsltInternals.h ++++ b/libxslt/xsltInternals.h +@@ -1786,6 +1786,8 @@ struct _xsltTransformContext { + int funcLevel; /* Needed to catch recursive functions issues */ + int maxTemplateDepth; + int maxTemplateVars; ++ ++ unsigned long nextid;/* for generating stable ids */ + }; + + /** |