db-move: moved gnome-weather from [staging] to [testing] (any)
[arch-packages.git] / libxslt / trunk / 0001-Make-generate-id-deterministic.patch
blob035eb81f41e40e7950d6b15077b4fe89978cc3a2
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Daniel Veillard <veillard@redhat.com>
3 Date: Sun, 29 Oct 2017 01:04:54 +0200
4 Subject: [PATCH] Make generate-id deterministic
6 Origin: upstream, https://bugzilla.gnome.org/attachment.cgi?id=306475
7 Bug: https://bugzilla.gnome.org/show_bug.cgi?id=751621
8 Bug-Debian: https://bugs.debian.org/823857
9 ---
10 libxslt/functions.c | 91 ++++++++++++++++++++++++++++++++++++++++-
11 libxslt/functions.h | 7 ++++
12 libxslt/transform.c | 8 ++++
13 libxslt/xsltInternals.h | 2 +
14 4 files changed, 107 insertions(+), 1 deletion(-)
16 diff --git a/libxslt/functions.c b/libxslt/functions.c
17 index ed2b002362dc..9c4408b325bd 100644
18 --- a/libxslt/functions.c
19 +++ b/libxslt/functions.c
20 @@ -662,6 +662,63 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
21 xmlXPathFreeObject(decimalObj);
24 +/**
25 + * xsltCleanupIds:
26 + * @ctxt: the transformation context
27 + * @root: the root of the resulting document
28 + *
29 + * This clean up ids which may have been saved in Element contents
30 + * by xsltGenerateIdFunction() to provide stable IDs on elements.
31 + *
32 + * Returns the number of items cleaned or -1 in case of error
33 + */
34 +int
35 +xsltCleanupIds(xsltTransformContextPtr ctxt, xmlNodePtr root) {
36 + xmlNodePtr cur;
37 + int count = 0;
39 + if ((ctxt == NULL) || (root == NULL))
40 + return(-1);
41 + if (root->type != XML_ELEMENT_NODE)
42 + return(-1);
44 + cur = root;
45 + while (cur != NULL) {
46 + if (cur->type == XML_ELEMENT_NODE) {
47 + if (cur->content != NULL) {
48 + cur->content = NULL;
49 + count++;
50 + }
51 + if (cur->children != NULL) {
52 + cur = cur->children;
53 + continue;
54 + }
55 + }
56 + if (cur->next != NULL) {
57 + cur = cur->next;
58 + continue;
59 + }
60 + do {
61 + cur = cur->parent;
62 + if (cur == NULL)
63 + break;
64 + if (cur == (xmlNodePtr) root) {
65 + cur = NULL;
66 + break;
67 + }
68 + if (cur->next != NULL) {
69 + cur = cur->next;
70 + break;
71 + }
72 + } while (cur != NULL);
73 + }
75 +fprintf(stderr, "Attributed %d IDs for element, cleaned up %d\n",
76 + ctxt->nextid, count);
78 + return(count);
81 /**
82 * xsltGenerateIdFunction:
83 * @ctxt: the XPath Parser context
84 @@ -713,7 +770,39 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
85 if (obj)
86 xmlXPathFreeObject(obj);
88 - val = (long)((char *)cur - (char *)&base_address);
89 + /*
90 + * Try to provide stable ID for generated document:
91 + * - usually ID are computed to be placed on elements via attributes
92 + * so using the element as the node for the ID
93 + * - the cur->content should be a correct placeholder for this, we use
94 + * it to hold element node numbers in xmlXPathOrderDocElems to
95 + * speed up XPath too
96 + * - xsltCleanupIds() clean them up before handing the XSLT output
97 + * to the API client.
98 + * - other nodes types use the node address method but that should
99 + * not end up in resulting document ID
100 + * - we can enable this by default without risk of performance issues
101 + * only the one pass xsltCleanupIds() is added
102 + */
103 + if (cur->type == XML_ELEMENT_NODE) {
104 + if (cur->content == NULL) {
105 + xsltTransformContextPtr tctxt;
107 + tctxt = xsltXPathGetTransformContext(ctxt);
108 + if (tctxt == NULL) {
109 + val = (long)((char *)cur - (char *)&base_address);
110 + } else {
111 + tctxt->nextid++;
112 + val = tctxt->nextid;
113 + cur->content = (void *) (val);
115 + } else {
116 + val = (long) cur->content;
118 + } else {
119 + val = (long)((char *)cur - (char *)&base_address);
122 if (val >= 0) {
123 snprintf((char *)str, sizeof(str), "idp%ld", val);
124 } else {
125 diff --git a/libxslt/functions.h b/libxslt/functions.h
126 index 5455b7f47802..31163613f6e9 100644
127 --- a/libxslt/functions.h
128 +++ b/libxslt/functions.h
129 @@ -63,6 +63,13 @@ XSLTPUBFUN void XSLTCALL
130 xsltFunctionAvailableFunction (xmlXPathParserContextPtr ctxt,
131 int nargs);
134 + * Cleanup for ID generation
135 + */
136 +XSLTPUBFUN int XSLTCALL
137 + xsltCleanupIds (xsltTransformContextPtr ctxt,
138 + xmlNodePtr root);
141 * And the registration
143 diff --git a/libxslt/transform.c b/libxslt/transform.c
144 index cb43bb47d997..bc1c6afcfdd8 100644
145 --- a/libxslt/transform.c
146 +++ b/libxslt/transform.c
147 @@ -705,6 +705,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
148 cur->traceCode = (unsigned long*) &xsltDefaultTrace;
149 cur->xinclude = xsltGetXIncludeDefault();
150 cur->keyInitLevel = 0;
151 + cur->nextid = 0;
153 return(cur);
155 @@ -6037,6 +6038,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
156 if (root != NULL) {
157 const xmlChar *doctype = NULL;
159 + /*
160 + * cleanup ids which may have been saved in Elements content ptrs
161 + */
162 + if (ctxt->nextid != 0) {
163 + xsltCleanupIds(ctxt, root);
166 if ((root->ns != NULL) && (root->ns->prefix != NULL))
167 doctype = xmlDictQLookup(ctxt->dict, root->ns->prefix, root->name);
168 if (doctype == NULL)
169 diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
170 index 14343d2751c8..9d3ff5fc0c06 100644
171 --- a/libxslt/xsltInternals.h
172 +++ b/libxslt/xsltInternals.h
173 @@ -1786,6 +1786,8 @@ struct _xsltTransformContext {
174 int maxTemplateVars;
175 unsigned long opLimit;
176 unsigned long opCount;
178 + unsigned long nextid;/* for generating stable ids */