nokogiri-xmlsec1 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +133 -0
- data/Rakefile +30 -0
- data/dependencies.yml +3 -0
- data/ext/nokogiri_ext_xmlsec/extconf.rb +489 -0
- data/ext/nokogiri_ext_xmlsec/init.c +46 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +124 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +182 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +43 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +32 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign_certificate.c +104 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign_rsa.c +95 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_certificates.c +96 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_named_keys.c +106 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_rsa.c +56 -0
- data/ext/nokogiri_ext_xmlsec/shutdown.c +12 -0
- data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +39 -0
- data/lib/nokogiri-xmlsec.rb +1 -0
- data/lib/xmlsec.rb +110 -0
- data/lib/xmlsec/version.rb +3 -0
- data/nokogiri-xmlsec1.gemspec +46 -0
- data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
- data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
- data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
- data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
- data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
- data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
- data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
- data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
- data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
- data/ports/patches/libxml2/0010-Keep-non-significant-blanks-node-in-HTML-parser.patch +2006 -0
- data/ports/patches/libxml2/0011-Do-not-fetch-external-parameter-entities.patch +39 -0
- data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
- data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
- data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
- data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
- data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
- data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
- data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
- data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
- data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
- data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
- data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
- data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
- data/ports/patches/xmlsec1/.keep +0 -0
- data/spec/fixtures/cert/server.crt +14 -0
- data/spec/fixtures/cert/server.csr +11 -0
- data/spec/fixtures/cert/server.key.decrypted +15 -0
- data/spec/fixtures/cert/server.key.encrypted +18 -0
- data/spec/fixtures/rsa.pem +15 -0
- data/spec/fixtures/rsa.pub +6 -0
- data/spec/fixtures/sign2-doc.xml +6 -0
- data/spec/fixtures/sign2-result.xml +24 -0
- data/spec/fixtures/sign3-result.xml +37 -0
- data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +22 -0
- data/spec/lib/nokogiri/xml/document/signing_and_verifying_spec.rb +77 -0
- data/spec/spec_helper.rb +10 -0
- metadata +251 -0
@@ -0,0 +1,587 @@
|
|
1
|
+
From a0116212e6dde5efe311e8240e45ae1477f8988f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
3
|
+
Date: Sun, 4 Aug 2013 20:28:19 +0200
|
4
|
+
Subject: [PATCH 07/14] Separate function for predicate matching in patterns
|
5
|
+
|
6
|
+
No functional change, only make the predicate matching code more
|
7
|
+
readable.
|
8
|
+
---
|
9
|
+
libxslt/pattern.c | 546 +++++++++++++++++++++++++++---------------------------
|
10
|
+
1 file changed, 274 insertions(+), 272 deletions(-)
|
11
|
+
|
12
|
+
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
|
13
|
+
index 63ec25a..414363b 100644
|
14
|
+
--- a/libxslt/pattern.c
|
15
|
+
+++ b/libxslt/pattern.c
|
16
|
+
@@ -621,6 +621,278 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
+ * xsltTestPredicateMatch:
|
21
|
+
+ * @ctxt: a XSLT process context
|
22
|
+
+ * @comp: the precompiled pattern
|
23
|
+
+ * @node: a node
|
24
|
+
+ * @step: the predicate step
|
25
|
+
+ * @sel: the previous step
|
26
|
+
+ *
|
27
|
+
+ * Test whether the node matches the predicate
|
28
|
+
+ *
|
29
|
+
+ * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
|
30
|
+
+ */
|
31
|
+
+static int
|
32
|
+
+xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
33
|
+
+ xmlNodePtr node, xsltStepOpPtr step,
|
34
|
+
+ xsltStepOpPtr sel) {
|
35
|
+
+ xmlNodePtr oldNode;
|
36
|
+
+ xmlDocPtr doc;
|
37
|
+
+ int oldCS, oldCP;
|
38
|
+
+ int pos = 0, len = 0;
|
39
|
+
+ int isRVT;
|
40
|
+
+ int match;
|
41
|
+
+
|
42
|
+
+ if (step->value == NULL)
|
43
|
+
+ return(0);
|
44
|
+
+ if (step->comp == NULL)
|
45
|
+
+ return(0);
|
46
|
+
+
|
47
|
+
+ doc = node->doc;
|
48
|
+
+ if (XSLT_IS_RES_TREE_FRAG(doc))
|
49
|
+
+ isRVT = 1;
|
50
|
+
+ else
|
51
|
+
+ isRVT = 0;
|
52
|
+
+
|
53
|
+
+ /*
|
54
|
+
+ * Depending on the last selection, one may need to
|
55
|
+
+ * recompute contextSize and proximityPosition.
|
56
|
+
+ */
|
57
|
+
+ oldCS = ctxt->xpathCtxt->contextSize;
|
58
|
+
+ oldCP = ctxt->xpathCtxt->proximityPosition;
|
59
|
+
+ if ((sel != NULL) &&
|
60
|
+
+ (sel->op == XSLT_OP_ELEM) &&
|
61
|
+
+ (sel->value != NULL) &&
|
62
|
+
+ (node->type == XML_ELEMENT_NODE) &&
|
63
|
+
+ (node->parent != NULL)) {
|
64
|
+
+ xmlNodePtr previous;
|
65
|
+
+ int nocache = 0;
|
66
|
+
+
|
67
|
+
+ previous = (xmlNodePtr)
|
68
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
|
69
|
+
+ if ((previous != NULL) &&
|
70
|
+
+ (previous->parent == node->parent)) {
|
71
|
+
+ /*
|
72
|
+
+ * just walk back to adjust the index
|
73
|
+
+ */
|
74
|
+
+ int indx = 0;
|
75
|
+
+ xmlNodePtr sibling = node;
|
76
|
+
+
|
77
|
+
+ while (sibling != NULL) {
|
78
|
+
+ if (sibling == previous)
|
79
|
+
+ break;
|
80
|
+
+ if ((sibling->type == XML_ELEMENT_NODE) &&
|
81
|
+
+ (previous->name != NULL) &&
|
82
|
+
+ (sibling->name != NULL) &&
|
83
|
+
+ (previous->name[0] == sibling->name[0]) &&
|
84
|
+
+ (xmlStrEqual(previous->name, sibling->name)))
|
85
|
+
+ {
|
86
|
+
+ if ((sel->value2 == NULL) ||
|
87
|
+
+ ((sibling->ns != NULL) &&
|
88
|
+
+ (xmlStrEqual(sel->value2, sibling->ns->href))))
|
89
|
+
+ indx++;
|
90
|
+
+ }
|
91
|
+
+ sibling = sibling->prev;
|
92
|
+
+ }
|
93
|
+
+ if (sibling == NULL) {
|
94
|
+
+ /* hum going backward in document order ... */
|
95
|
+
+ indx = 0;
|
96
|
+
+ sibling = node;
|
97
|
+
+ while (sibling != NULL) {
|
98
|
+
+ if (sibling == previous)
|
99
|
+
+ break;
|
100
|
+
+ if ((sibling->type == XML_ELEMENT_NODE) &&
|
101
|
+
+ (previous->name != NULL) &&
|
102
|
+
+ (sibling->name != NULL) &&
|
103
|
+
+ (previous->name[0] == sibling->name[0]) &&
|
104
|
+
+ (xmlStrEqual(previous->name, sibling->name)))
|
105
|
+
+ {
|
106
|
+
+ if ((sel->value2 == NULL) ||
|
107
|
+
+ ((sibling->ns != NULL) &&
|
108
|
+
+ (xmlStrEqual(sel->value2,
|
109
|
+
+ sibling->ns->href))))
|
110
|
+
+ {
|
111
|
+
+ indx--;
|
112
|
+
+ }
|
113
|
+
+ }
|
114
|
+
+ sibling = sibling->next;
|
115
|
+
+ }
|
116
|
+
+ }
|
117
|
+
+ if (sibling != NULL) {
|
118
|
+
+ pos = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) + indx;
|
119
|
+
+ /*
|
120
|
+
+ * If the node is in a Value Tree we need to
|
121
|
+
+ * save len, but cannot cache the node!
|
122
|
+
+ * (bugs 153137 and 158840)
|
123
|
+
+ */
|
124
|
+
+ if (node->doc != NULL) {
|
125
|
+
+ len = XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival);
|
126
|
+
+ if (!isRVT) {
|
127
|
+
+ XSLT_RUNTIME_EXTRA(ctxt,
|
128
|
+
+ sel->previousExtra, ptr) = node;
|
129
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
130
|
+
+ }
|
131
|
+
+ }
|
132
|
+
+ } else
|
133
|
+
+ pos = 0;
|
134
|
+
+ } else {
|
135
|
+
+ /*
|
136
|
+
+ * recompute the index
|
137
|
+
+ */
|
138
|
+
+ xmlNodePtr parent = node->parent;
|
139
|
+
+ xmlNodePtr siblings = NULL;
|
140
|
+
+
|
141
|
+
+ if (parent) siblings = parent->children;
|
142
|
+
+
|
143
|
+
+ while (siblings != NULL) {
|
144
|
+
+ if (siblings->type == XML_ELEMENT_NODE) {
|
145
|
+
+ if (siblings == node) {
|
146
|
+
+ len++;
|
147
|
+
+ pos = len;
|
148
|
+
+ } else if ((node->name != NULL) &&
|
149
|
+
+ (siblings->name != NULL) &&
|
150
|
+
+ (node->name[0] == siblings->name[0]) &&
|
151
|
+
+ (xmlStrEqual(node->name, siblings->name))) {
|
152
|
+
+ if ((sel->value2 == NULL) ||
|
153
|
+
+ ((siblings->ns != NULL) &&
|
154
|
+
+ (xmlStrEqual(sel->value2, siblings->ns->href))))
|
155
|
+
+ len++;
|
156
|
+
+ }
|
157
|
+
+ }
|
158
|
+
+ siblings = siblings->next;
|
159
|
+
+ }
|
160
|
+
+ if ((parent == NULL) || (node->doc == NULL))
|
161
|
+
+ nocache = 1;
|
162
|
+
+ else {
|
163
|
+
+ while (parent->parent != NULL)
|
164
|
+
+ parent = parent->parent;
|
165
|
+
+ if (((parent->type != XML_DOCUMENT_NODE) &&
|
166
|
+
+ (parent->type != XML_HTML_DOCUMENT_NODE)) ||
|
167
|
+
+ (parent != (xmlNodePtr) node->doc))
|
168
|
+
+ nocache = 1;
|
169
|
+
+ }
|
170
|
+
+ }
|
171
|
+
+ if (pos != 0) {
|
172
|
+
+ ctxt->xpathCtxt->contextSize = len;
|
173
|
+
+ ctxt->xpathCtxt->proximityPosition = pos;
|
174
|
+
+ /*
|
175
|
+
+ * If the node is in a Value Tree we cannot
|
176
|
+
+ * cache it !
|
177
|
+
+ */
|
178
|
+
+ if ((!isRVT) && (node->doc != NULL) &&
|
179
|
+
+ (nocache == 0)) {
|
180
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = node;
|
181
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
182
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = len;
|
183
|
+
+ }
|
184
|
+
+ }
|
185
|
+
+ } else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) &&
|
186
|
+
+ (node->type == XML_ELEMENT_NODE)) {
|
187
|
+
+ xmlNodePtr previous;
|
188
|
+
+ int nocache = 0;
|
189
|
+
+
|
190
|
+
+ previous = (xmlNodePtr)
|
191
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
|
192
|
+
+ if ((previous != NULL) &&
|
193
|
+
+ (previous->parent == node->parent)) {
|
194
|
+
+ /*
|
195
|
+
+ * just walk back to adjust the index
|
196
|
+
+ */
|
197
|
+
+ int indx = 0;
|
198
|
+
+ xmlNodePtr sibling = node;
|
199
|
+
+
|
200
|
+
+ while (sibling != NULL) {
|
201
|
+
+ if (sibling == previous)
|
202
|
+
+ break;
|
203
|
+
+ if (sibling->type == XML_ELEMENT_NODE)
|
204
|
+
+ indx++;
|
205
|
+
+ sibling = sibling->prev;
|
206
|
+
+ }
|
207
|
+
+ if (sibling == NULL) {
|
208
|
+
+ /* hum going backward in document order ... */
|
209
|
+
+ indx = 0;
|
210
|
+
+ sibling = node;
|
211
|
+
+ while (sibling != NULL) {
|
212
|
+
+ if (sibling == previous)
|
213
|
+
+ break;
|
214
|
+
+ if (sibling->type == XML_ELEMENT_NODE)
|
215
|
+
+ indx--;
|
216
|
+
+ sibling = sibling->next;
|
217
|
+
+ }
|
218
|
+
+ }
|
219
|
+
+ if (sibling != NULL) {
|
220
|
+
+ pos = XSLT_RUNTIME_EXTRA(ctxt,
|
221
|
+
+ sel->indexExtra, ival) + indx;
|
222
|
+
+ /*
|
223
|
+
+ * If the node is in a Value Tree we cannot
|
224
|
+
+ * cache it !
|
225
|
+
+ */
|
226
|
+
+ if ((node->doc != NULL) && !isRVT) {
|
227
|
+
+ len = XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival);
|
228
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = node;
|
229
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
230
|
+
+ }
|
231
|
+
+ } else
|
232
|
+
+ pos = 0;
|
233
|
+
+ } else {
|
234
|
+
+ /*
|
235
|
+
+ * recompute the index
|
236
|
+
+ */
|
237
|
+
+ xmlNodePtr parent = node->parent;
|
238
|
+
+ xmlNodePtr siblings = NULL;
|
239
|
+
+
|
240
|
+
+ if (parent) siblings = parent->children;
|
241
|
+
+
|
242
|
+
+ while (siblings != NULL) {
|
243
|
+
+ if (siblings->type == XML_ELEMENT_NODE) {
|
244
|
+
+ len++;
|
245
|
+
+ if (siblings == node) {
|
246
|
+
+ pos = len;
|
247
|
+
+ }
|
248
|
+
+ }
|
249
|
+
+ siblings = siblings->next;
|
250
|
+
+ }
|
251
|
+
+ if ((parent == NULL) || (node->doc == NULL))
|
252
|
+
+ nocache = 1;
|
253
|
+
+ else {
|
254
|
+
+ while (parent->parent != NULL)
|
255
|
+
+ parent = parent->parent;
|
256
|
+
+ if (((parent->type != XML_DOCUMENT_NODE) &&
|
257
|
+
+ (parent->type != XML_HTML_DOCUMENT_NODE)) ||
|
258
|
+
+ (parent != (xmlNodePtr) node->doc))
|
259
|
+
+ nocache = 1;
|
260
|
+
+ }
|
261
|
+
+ }
|
262
|
+
+ if (pos != 0) {
|
263
|
+
+ ctxt->xpathCtxt->contextSize = len;
|
264
|
+
+ ctxt->xpathCtxt->proximityPosition = pos;
|
265
|
+
+ /*
|
266
|
+
+ * If the node is in a Value Tree we cannot
|
267
|
+
+ * cache it !
|
268
|
+
+ */
|
269
|
+
+ if ((node->doc != NULL) && (nocache == 0) && !isRVT) {
|
270
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = node;
|
271
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
272
|
+
+ XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = len;
|
273
|
+
+ }
|
274
|
+
+ }
|
275
|
+
+ }
|
276
|
+
+
|
277
|
+
+ oldNode = ctxt->node;
|
278
|
+
+ ctxt->node = node;
|
279
|
+
+
|
280
|
+
+ match = xsltEvalXPathPredicate(ctxt, step->comp, comp->nsList, comp->nsNr);
|
281
|
+
+
|
282
|
+
+ if (pos != 0) {
|
283
|
+
+ ctxt->xpathCtxt->contextSize = oldCS;
|
284
|
+
+ ctxt->xpathCtxt->proximityPosition = oldCP;
|
285
|
+
+ }
|
286
|
+
+ ctxt->node = oldNode;
|
287
|
+
+
|
288
|
+
+ return match;
|
289
|
+
+}
|
290
|
+
+
|
291
|
+
+/**
|
292
|
+
* xsltTestCompMatch:
|
293
|
+
* @ctxt: a XSLT process context
|
294
|
+
* @comp: the precompiled pattern
|
295
|
+
@@ -854,12 +1126,6 @@ restart:
|
296
|
+
goto rollback;
|
297
|
+
break;
|
298
|
+
case XSLT_OP_PREDICATE: {
|
299
|
+
- xmlNodePtr oldNode;
|
300
|
+
- xmlDocPtr doc;
|
301
|
+
- int oldCS, oldCP;
|
302
|
+
- int pos = 0, len = 0;
|
303
|
+
- int isRVT;
|
304
|
+
-
|
305
|
+
/*
|
306
|
+
* when there is cascading XSLT_OP_PREDICATE, then use a
|
307
|
+
* direct computation approach. It's not done directly
|
308
|
+
@@ -875,274 +1141,10 @@ restart:
|
309
|
+
comp->nsList, comp->nsNr));
|
310
|
+
}
|
311
|
+
|
312
|
+
- doc = node->doc;
|
313
|
+
- if (XSLT_IS_RES_TREE_FRAG(doc))
|
314
|
+
- isRVT = 1;
|
315
|
+
- else
|
316
|
+
- isRVT = 0;
|
317
|
+
-
|
318
|
+
- /*
|
319
|
+
- * Depending on the last selection, one may need to
|
320
|
+
- * recompute contextSize and proximityPosition.
|
321
|
+
- */
|
322
|
+
- oldCS = ctxt->xpathCtxt->contextSize;
|
323
|
+
- oldCP = ctxt->xpathCtxt->proximityPosition;
|
324
|
+
- if ((sel != NULL) &&
|
325
|
+
- (sel->op == XSLT_OP_ELEM) &&
|
326
|
+
- (sel->value != NULL) &&
|
327
|
+
- (node->type == XML_ELEMENT_NODE) &&
|
328
|
+
- (node->parent != NULL)) {
|
329
|
+
- xmlNodePtr previous;
|
330
|
+
- int nocache = 0;
|
331
|
+
-
|
332
|
+
- previous = (xmlNodePtr)
|
333
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
|
334
|
+
- if ((previous != NULL) &&
|
335
|
+
- (previous->parent == node->parent)) {
|
336
|
+
- /*
|
337
|
+
- * just walk back to adjust the index
|
338
|
+
- */
|
339
|
+
- int indx = 0;
|
340
|
+
- xmlNodePtr sibling = node;
|
341
|
+
-
|
342
|
+
- while (sibling != NULL) {
|
343
|
+
- if (sibling == previous)
|
344
|
+
- break;
|
345
|
+
- if ((sibling->type == XML_ELEMENT_NODE) &&
|
346
|
+
- (previous->name != NULL) &&
|
347
|
+
- (sibling->name != NULL) &&
|
348
|
+
- (previous->name[0] == sibling->name[0]) &&
|
349
|
+
- (xmlStrEqual(previous->name, sibling->name)))
|
350
|
+
- {
|
351
|
+
- if ((sel->value2 == NULL) ||
|
352
|
+
- ((sibling->ns != NULL) &&
|
353
|
+
- (xmlStrEqual(sel->value2,
|
354
|
+
- sibling->ns->href))))
|
355
|
+
- indx++;
|
356
|
+
- }
|
357
|
+
- sibling = sibling->prev;
|
358
|
+
- }
|
359
|
+
- if (sibling == NULL) {
|
360
|
+
- /* hum going backward in document order ... */
|
361
|
+
- indx = 0;
|
362
|
+
- sibling = node;
|
363
|
+
- while (sibling != NULL) {
|
364
|
+
- if (sibling == previous)
|
365
|
+
- break;
|
366
|
+
- if ((sibling->type == XML_ELEMENT_NODE) &&
|
367
|
+
- (previous->name != NULL) &&
|
368
|
+
- (sibling->name != NULL) &&
|
369
|
+
- (previous->name[0] == sibling->name[0]) &&
|
370
|
+
- (xmlStrEqual(previous->name, sibling->name)))
|
371
|
+
- {
|
372
|
+
- if ((sel->value2 == NULL) ||
|
373
|
+
- ((sibling->ns != NULL) &&
|
374
|
+
- (xmlStrEqual(sel->value2,
|
375
|
+
- sibling->ns->href))))
|
376
|
+
- {
|
377
|
+
- indx--;
|
378
|
+
- }
|
379
|
+
- }
|
380
|
+
- sibling = sibling->next;
|
381
|
+
- }
|
382
|
+
- }
|
383
|
+
- if (sibling != NULL) {
|
384
|
+
- pos = XSLT_RUNTIME_EXTRA(ctxt,
|
385
|
+
- sel->indexExtra, ival) + indx;
|
386
|
+
- /*
|
387
|
+
- * If the node is in a Value Tree we need to
|
388
|
+
- * save len, but cannot cache the node!
|
389
|
+
- * (bugs 153137 and 158840)
|
390
|
+
- */
|
391
|
+
- if (node->doc != NULL) {
|
392
|
+
- len = XSLT_RUNTIME_EXTRA(ctxt,
|
393
|
+
- sel->lenExtra, ival);
|
394
|
+
- if (!isRVT) {
|
395
|
+
- XSLT_RUNTIME_EXTRA(ctxt,
|
396
|
+
- sel->previousExtra, ptr) = node;
|
397
|
+
- XSLT_RUNTIME_EXTRA(ctxt,
|
398
|
+
- sel->indexExtra, ival) = pos;
|
399
|
+
- }
|
400
|
+
- }
|
401
|
+
- } else
|
402
|
+
- pos = 0;
|
403
|
+
- } else {
|
404
|
+
- /*
|
405
|
+
- * recompute the index
|
406
|
+
- */
|
407
|
+
- xmlNodePtr parent = node->parent;
|
408
|
+
- xmlNodePtr siblings = NULL;
|
409
|
+
-
|
410
|
+
- if (parent) siblings = parent->children;
|
411
|
+
-
|
412
|
+
- while (siblings != NULL) {
|
413
|
+
- if (siblings->type == XML_ELEMENT_NODE) {
|
414
|
+
- if (siblings == node) {
|
415
|
+
- len++;
|
416
|
+
- pos = len;
|
417
|
+
- } else if ((node->name != NULL) &&
|
418
|
+
- (siblings->name != NULL) &&
|
419
|
+
- (node->name[0] == siblings->name[0]) &&
|
420
|
+
- (xmlStrEqual(node->name, siblings->name))) {
|
421
|
+
- if ((sel->value2 == NULL) ||
|
422
|
+
- ((siblings->ns != NULL) &&
|
423
|
+
- (xmlStrEqual(sel->value2,
|
424
|
+
- siblings->ns->href))))
|
425
|
+
- len++;
|
426
|
+
- }
|
427
|
+
- }
|
428
|
+
- siblings = siblings->next;
|
429
|
+
- }
|
430
|
+
- if ((parent == NULL) || (node->doc == NULL))
|
431
|
+
- nocache = 1;
|
432
|
+
- else {
|
433
|
+
- while (parent->parent != NULL)
|
434
|
+
- parent = parent->parent;
|
435
|
+
- if (((parent->type != XML_DOCUMENT_NODE) &&
|
436
|
+
- (parent->type != XML_HTML_DOCUMENT_NODE)) ||
|
437
|
+
- (parent != (xmlNodePtr) node->doc))
|
438
|
+
- nocache = 1;
|
439
|
+
- }
|
440
|
+
- }
|
441
|
+
- if (pos != 0) {
|
442
|
+
- ctxt->xpathCtxt->contextSize = len;
|
443
|
+
- ctxt->xpathCtxt->proximityPosition = pos;
|
444
|
+
- /*
|
445
|
+
- * If the node is in a Value Tree we cannot
|
446
|
+
- * cache it !
|
447
|
+
- */
|
448
|
+
- if ((!isRVT) && (node->doc != NULL) &&
|
449
|
+
- (nocache == 0)) {
|
450
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) =
|
451
|
+
- node;
|
452
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
|
453
|
+
- pos;
|
454
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) =
|
455
|
+
- len;
|
456
|
+
- }
|
457
|
+
- }
|
458
|
+
- } else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) &&
|
459
|
+
- (node->type == XML_ELEMENT_NODE)) {
|
460
|
+
- xmlNodePtr previous;
|
461
|
+
- int nocache = 0;
|
462
|
+
-
|
463
|
+
- previous = (xmlNodePtr)
|
464
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
|
465
|
+
- if ((previous != NULL) &&
|
466
|
+
- (previous->parent == node->parent)) {
|
467
|
+
- /*
|
468
|
+
- * just walk back to adjust the index
|
469
|
+
- */
|
470
|
+
- int indx = 0;
|
471
|
+
- xmlNodePtr sibling = node;
|
472
|
+
-
|
473
|
+
- while (sibling != NULL) {
|
474
|
+
- if (sibling == previous)
|
475
|
+
- break;
|
476
|
+
- if (sibling->type == XML_ELEMENT_NODE)
|
477
|
+
- indx++;
|
478
|
+
- sibling = sibling->prev;
|
479
|
+
- }
|
480
|
+
- if (sibling == NULL) {
|
481
|
+
- /* hum going backward in document order ... */
|
482
|
+
- indx = 0;
|
483
|
+
- sibling = node;
|
484
|
+
- while (sibling != NULL) {
|
485
|
+
- if (sibling == previous)
|
486
|
+
- break;
|
487
|
+
- if (sibling->type == XML_ELEMENT_NODE)
|
488
|
+
- indx--;
|
489
|
+
- sibling = sibling->next;
|
490
|
+
- }
|
491
|
+
- }
|
492
|
+
- if (sibling != NULL) {
|
493
|
+
- pos = XSLT_RUNTIME_EXTRA(ctxt,
|
494
|
+
- sel->indexExtra, ival) + indx;
|
495
|
+
- /*
|
496
|
+
- * If the node is in a Value Tree we cannot
|
497
|
+
- * cache it !
|
498
|
+
- */
|
499
|
+
- if ((node->doc != NULL) && !isRVT) {
|
500
|
+
- len = XSLT_RUNTIME_EXTRA(ctxt,
|
501
|
+
- sel->lenExtra, ival);
|
502
|
+
- XSLT_RUNTIME_EXTRA(ctxt,
|
503
|
+
- sel->previousExtra, ptr) = node;
|
504
|
+
- XSLT_RUNTIME_EXTRA(ctxt,
|
505
|
+
- sel->indexExtra, ival) = pos;
|
506
|
+
- }
|
507
|
+
- } else
|
508
|
+
- pos = 0;
|
509
|
+
- } else {
|
510
|
+
- /*
|
511
|
+
- * recompute the index
|
512
|
+
- */
|
513
|
+
- xmlNodePtr parent = node->parent;
|
514
|
+
- xmlNodePtr siblings = NULL;
|
515
|
+
-
|
516
|
+
- if (parent) siblings = parent->children;
|
517
|
+
-
|
518
|
+
- while (siblings != NULL) {
|
519
|
+
- if (siblings->type == XML_ELEMENT_NODE) {
|
520
|
+
- len++;
|
521
|
+
- if (siblings == node) {
|
522
|
+
- pos = len;
|
523
|
+
- }
|
524
|
+
- }
|
525
|
+
- siblings = siblings->next;
|
526
|
+
- }
|
527
|
+
- if ((parent == NULL) || (node->doc == NULL))
|
528
|
+
- nocache = 1;
|
529
|
+
- else {
|
530
|
+
- while (parent->parent != NULL)
|
531
|
+
- parent = parent->parent;
|
532
|
+
- if (((parent->type != XML_DOCUMENT_NODE) &&
|
533
|
+
- (parent->type != XML_HTML_DOCUMENT_NODE)) ||
|
534
|
+
- (parent != (xmlNodePtr) node->doc))
|
535
|
+
- nocache = 1;
|
536
|
+
- }
|
537
|
+
- }
|
538
|
+
- if (pos != 0) {
|
539
|
+
- ctxt->xpathCtxt->contextSize = len;
|
540
|
+
- ctxt->xpathCtxt->proximityPosition = pos;
|
541
|
+
- /*
|
542
|
+
- * If the node is in a Value Tree we cannot
|
543
|
+
- * cache it !
|
544
|
+
- */
|
545
|
+
- if ((node->doc != NULL) && (nocache == 0) && !isRVT) {
|
546
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) =
|
547
|
+
- node;
|
548
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
|
549
|
+
- pos;
|
550
|
+
- XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) =
|
551
|
+
- len;
|
552
|
+
- }
|
553
|
+
- }
|
554
|
+
- }
|
555
|
+
- oldNode = ctxt->node;
|
556
|
+
- ctxt->node = node;
|
557
|
+
-
|
558
|
+
- if (step->value == NULL)
|
559
|
+
- goto wrong_index;
|
560
|
+
- if (step->comp == NULL)
|
561
|
+
- goto wrong_index;
|
562
|
+
-
|
563
|
+
- if (!xsltEvalXPathPredicate(ctxt, step->comp, comp->nsList,
|
564
|
+
- comp->nsNr))
|
565
|
+
- goto wrong_index;
|
566
|
+
+ if (!xsltTestPredicateMatch(ctxt, comp, node, step, sel))
|
567
|
+
+ goto rollback;
|
568
|
+
|
569
|
+
- if (pos != 0) {
|
570
|
+
- ctxt->xpathCtxt->contextSize = oldCS;
|
571
|
+
- ctxt->xpathCtxt->proximityPosition = oldCP;
|
572
|
+
- }
|
573
|
+
- ctxt->node = oldNode;
|
574
|
+
break;
|
575
|
+
-wrong_index:
|
576
|
+
- if (pos != 0) {
|
577
|
+
- ctxt->xpathCtxt->contextSize = oldCS;
|
578
|
+
- ctxt->xpathCtxt->proximityPosition = oldCP;
|
579
|
+
- }
|
580
|
+
- ctxt->node = oldNode;
|
581
|
+
- goto rollback;
|
582
|
+
}
|
583
|
+
case XSLT_OP_PI:
|
584
|
+
if (node->type != XML_PI_NODE)
|
585
|
+
--
|
586
|
+
1.8.4.1
|
587
|
+
|