1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
diff --git a/libxslt/functions.c b/libxslt/functions.c
index 72a58dc4d6592..309af458c22f7 100644
--- a/libxslt/functions.c
+++ b/libxslt/functions.c
@@ -760,7 +760,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
}
if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) {
- id = (unsigned long) (size_t) *psviPtr;
+ id = (unsigned long) xsltGetSourceNodeValue(cur);
} else {
if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) {
/* Text nodes store big line numbers in psvi. */
@@ -772,7 +772,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
goto out;
}
- if (tctxt->currentId == ULONG_MAX) {
+ if (tctxt->currentId == XSLT_SOURCE_NODE_VALUE_MAX) {
xsltTransformError(tctxt, NULL, NULL,
"generate-id(): id overflow\n");
ctxt->error = XPATH_MEMORY_ERROR;
@@ -780,7 +780,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
}
id = ++tctxt->currentId;
- *psviPtr = (void *) (size_t) id;
+ xsltSetSourceNodeValue(cur, id);
xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID);
}
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 54ef821b5016f..1ac2471d6441b 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -5772,7 +5772,8 @@ xsltCleanupSourceDoc(xmlDocPtr doc) {
xmlAttrPtr prop = cur->properties;
while (prop) {
- prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27);
+ prop->extra &=
+ ~(XSLT_SOURCE_NODE_MASK << XSLT_SOURCE_NODE_SHIFT_32);
prop->psvi = NULL;
prop = prop->next;
}
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
index a20da96182289..b431fafbbb441 100644
--- a/libxslt/xsltutils.c
+++ b/libxslt/xsltutils.c
@@ -1920,26 +1920,26 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
int
xsltGetSourceNodeFlags(xmlNodePtr node) {
/*
- * Squeeze the bit flags into the upper bits of
+ * Squeeze the bit flags into the upper 4 bits of
*
- * - 'int properties' member in struct _xmlDoc
- * - 'xmlAttributeType atype' member in struct _xmlAttr
+ * - 'unsigned int extra' member in struct _xmlDoc
+ * - 'unsigned int extra' member in struct _xmlAttr
* - 'unsigned short extra' member in struct _xmlNode
*/
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
- return ((xmlDocPtr) node)->properties >> 27;
+ return ((xmlDocPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32;
case XML_ATTRIBUTE_NODE:
- return ((xmlAttrPtr) node)->atype >> 27;
+ return ((xmlAttrPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
- return node->extra >> 12;
+ return node->extra >> XSLT_SOURCE_NODE_SHIFT_32;
default:
return 0;
@@ -1964,11 +1964,13 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
- ((xmlDocPtr) node)->properties |= flags << 27;
+ ((xmlDocPtr) node)->extra |=
+ ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32);
return 0;
case XML_ATTRIBUTE_NODE:
- ((xmlAttrPtr) node)->atype |= flags << 27;
+ ((xmlAttrPtr) node)->extra |=
+ ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32);
return 0;
case XML_ELEMENT_NODE:
@@ -1976,7 +1978,7 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
- node->extra |= flags << 12;
+ node->extra |= ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16);
return 0;
default:
@@ -1998,11 +2000,13 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
- ((xmlDocPtr) node)->properties &= ~(flags << 27);
+ ((xmlDocPtr) node)->extra &=
+ ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32);
return 0;
case XML_ATTRIBUTE_NODE:
- ((xmlAttrPtr) node)->atype &= ~(flags << 27);
+ ((xmlAttrPtr) node)->extra &=
+ ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32);
return 0;
case XML_ELEMENT_NODE:
@@ -2010,7 +2014,55 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
- node->extra &= ~(flags << 12);
+ node->extra &= ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16);
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+/**
+ * xsltGetSourceNodeValue:
+ * @node: Node from source document
+ *
+ * Returns the associated 28 bit unsigned value for a source node,
+ * or 0 if node does not have an associated value.
+ */
+int
+xsltGetSourceNodeValue(xmlNodePtr node) {
+ switch (node->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ return (((xmlDocPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK);
+
+ case XML_ATTRIBUTE_NODE:
+ return (((xmlAttrPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK);
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ * xsltSetSourceNodeValue:
+ * @node: Node from source document
+ * @value: 28 bit unsigned value to associate with the node.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+xsltSetSourceNodeValue(xmlNodePtr node, int value) {
+ switch (node->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ ((xmlDocPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK;
+ ((xmlDocPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK);
+ return 0;
+
+ case XML_ATTRIBUTE_NODE:
+ ((xmlAttrPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK;
+ ((xmlAttrPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK);
return 0;
default:
diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
index 2514774b3f11a..1e753eebadd98 100644
--- a/libxslt/xsltutils.h
+++ b/libxslt/xsltutils.h
@@ -261,6 +261,10 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
#define XSLT_SOURCE_NODE_MASK 15u
#define XSLT_SOURCE_NODE_HAS_KEY 1u
#define XSLT_SOURCE_NODE_HAS_ID 2u
+#define XSLT_SOURCE_NODE_SHIFT_16 12u
+#define XSLT_SOURCE_NODE_SHIFT_32 28u
+#define XSLT_SOURCE_NODE_VALUE_MASK ((1 << XSLT_SOURCE_NODE_SHIFT_32) - 1)
+#define XSLT_SOURCE_NODE_VALUE_MAX XSLT_SOURCE_NODE_VALUE_MASK
int
xsltGetSourceNodeFlags(xmlNodePtr node);
int
@@ -268,6 +272,10 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
int flags);
int
xsltClearSourceNodeFlags(xmlNodePtr node, int flags);
+int
+xsltSetSourceNodeValue(xmlNodePtr node, int value);
+int
+xsltGetSourceNodeValue(xmlNodePtr node);
void **
xsltGetPSVIPtr(xmlNodePtr cur);
/** DOC_ENABLE */
|