Coverage Report

Created: 2024-07-27 14:18

/src/libxslt/libexslt/sets.c
Line
Count
Source (jump to first uncovered line)
1
#define IN_LIBEXSLT
2
#include "libexslt/libexslt.h"
3
4
#include <libxml/tree.h>
5
#include <libxml/xpath.h>
6
#include <libxml/xpathInternals.h>
7
8
#include <libxslt/xsltutils.h>
9
#include <libxslt/xsltInternals.h>
10
#include <libxslt/extensions.h>
11
12
#include "exslt.h"
13
14
/**
15
 * exsltSetsDifferenceFunction:
16
 * @ctxt:  an XPath parser context
17
 * @nargs:  the number of arguments
18
 *
19
 * Wraps #xmlXPathDifference for use by the XPath processor
20
 */
21
static void
22
34.6k
exsltSetsDifferenceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
23
34.6k
    xmlNodeSetPtr arg1, arg2, ret;
24
25
34.6k
    if (nargs != 2) {
26
1.58k
  xmlXPathSetArityError(ctxt);
27
1.58k
  return;
28
1.58k
    }
29
30
33.0k
    arg2 = xmlXPathPopNodeSet(ctxt);
31
33.0k
    if (xmlXPathCheckError(ctxt))
32
1.41k
  return;
33
34
31.6k
    arg1 = xmlXPathPopNodeSet(ctxt);
35
31.6k
    if (xmlXPathCheckError(ctxt)) {
36
1.01k
        xmlXPathFreeNodeSet(arg2);
37
1.01k
  return;
38
1.01k
    }
39
40
30.6k
    ret = xmlXPathDifference(arg1, arg2);
41
42
30.6k
    if (ret != arg1)
43
21.4k
  xmlXPathFreeNodeSet(arg1);
44
30.6k
    xmlXPathFreeNodeSet(arg2);
45
46
30.6k
    xmlXPathReturnNodeSet(ctxt, ret);
47
30.6k
}
48
49
/**
50
 * exsltSetsIntersectionFunction:
51
 * @ctxt:  an XPath parser context
52
 * @nargs:  the number of arguments
53
 *
54
 * Wraps #xmlXPathIntersection for use by the XPath processor
55
 */
56
static void
57
23.7k
exsltSetsIntersectionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
58
23.7k
    xmlNodeSetPtr arg1, arg2, ret;
59
60
23.7k
    if (nargs != 2) {
61
677
  xmlXPathSetArityError(ctxt);
62
677
  return;
63
677
    }
64
65
23.0k
    arg2 = xmlXPathPopNodeSet(ctxt);
66
23.0k
    if (xmlXPathCheckError(ctxt))
67
680
  return;
68
69
22.3k
    arg1 = xmlXPathPopNodeSet(ctxt);
70
22.3k
    if (xmlXPathCheckError(ctxt)) {
71
955
        xmlXPathFreeNodeSet(arg2);
72
955
  return;
73
955
    }
74
75
21.4k
    ret = xmlXPathIntersection(arg1, arg2);
76
77
21.4k
    xmlXPathFreeNodeSet(arg1);
78
21.4k
    xmlXPathFreeNodeSet(arg2);
79
80
21.4k
    xmlXPathReturnNodeSet(ctxt, ret);
81
21.4k
}
82
83
/**
84
 * exsltSetsDistinctFunction:
85
 * @ctxt:  an XPath parser context
86
 * @nargs:  the number of arguments
87
 *
88
 * Wraps #xmlXPathDistinct for use by the XPath processor
89
 */
90
static void
91
32.3k
exsltSetsDistinctFunction (xmlXPathParserContextPtr ctxt, int nargs) {
92
32.3k
    xmlXPathObjectPtr obj;
93
32.3k
    xmlNodeSetPtr ns, ret;
94
32.3k
    int boolval = 0;
95
32.3k
    void *user = NULL;
96
97
32.3k
    if (nargs != 1) {
98
2.41k
  xmlXPathSetArityError(ctxt);
99
2.41k
  return;
100
2.41k
    }
101
102
29.9k
    if (ctxt->value != NULL) {
103
29.9k
        boolval = ctxt->value->boolval;
104
29.9k
  user = ctxt->value->user;
105
29.9k
  ctxt->value->boolval = 0;
106
29.9k
  ctxt->value->user = NULL;
107
29.9k
    }
108
29.9k
    ns = xmlXPathPopNodeSet(ctxt);
109
29.9k
    if (xmlXPathCheckError(ctxt))
110
1.63k
  return;
111
112
    /* !!! must be sorted !!! */
113
28.2k
    ret = xmlXPathDistinctSorted(ns);
114
115
28.2k
  if (ret != ns)
116
12.4k
    xmlXPathFreeNodeSet(ns);
117
118
28.2k
    obj = xmlXPathWrapNodeSet(ret);
119
28.2k
    obj->user = user;
120
28.2k
    obj->boolval = boolval;
121
28.2k
    valuePush((ctxt), obj);
122
28.2k
}
123
124
/**
125
 * exsltSetsHasSameNodesFunction:
126
 * @ctxt:  an XPath parser context
127
 * @nargs:  the number of arguments
128
 *
129
 * Wraps #xmlXPathHasSameNodes for use by the XPath processor
130
 */
131
static void
132
exsltSetsHasSameNodesFunction (xmlXPathParserContextPtr ctxt,
133
38.2k
            int nargs) {
134
38.2k
    xmlNodeSetPtr arg1, arg2;
135
38.2k
    int ret;
136
137
38.2k
    if (nargs != 2) {
138
682
  xmlXPathSetArityError(ctxt);
139
682
  return;
140
682
    }
141
142
37.5k
    arg2 = xmlXPathPopNodeSet(ctxt);
143
37.5k
    if (xmlXPathCheckError(ctxt))
144
599
  return;
145
146
36.9k
    arg1 = xmlXPathPopNodeSet(ctxt);
147
36.9k
    if (xmlXPathCheckError(ctxt)) {
148
827
        xmlXPathFreeNodeSet(arg2);
149
827
  return;
150
827
    }
151
152
36.1k
    ret = xmlXPathHasSameNodes(arg1, arg2);
153
154
36.1k
    xmlXPathFreeNodeSet(arg1);
155
36.1k
    xmlXPathFreeNodeSet(arg2);
156
157
36.1k
    xmlXPathReturnBoolean(ctxt, ret);
158
36.1k
}
159
160
/**
161
 * exsltSetsLeadingFunction:
162
 * @ctxt:  an XPath parser context
163
 * @nargs:  the number of arguments
164
 *
165
 * Wraps #xmlXPathLeading for use by the XPath processor
166
 */
167
static void
168
34.4k
exsltSetsLeadingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
169
34.4k
    xmlNodeSetPtr arg1, arg2, ret;
170
171
34.4k
    if (nargs != 2) {
172
2.24k
  xmlXPathSetArityError(ctxt);
173
2.24k
  return;
174
2.24k
    }
175
176
32.2k
    arg2 = xmlXPathPopNodeSet(ctxt);
177
32.2k
    if (xmlXPathCheckError(ctxt))
178
1.80k
  return;
179
180
30.4k
    arg1 = xmlXPathPopNodeSet(ctxt);
181
30.4k
    if (xmlXPathCheckError(ctxt)) {
182
1.72k
  xmlXPathFreeNodeSet(arg2);
183
1.72k
  return;
184
1.72k
    }
185
186
    /*  If the second node set is empty, then the first node set is
187
     * returned.
188
     */
189
28.7k
    if (xmlXPathNodeSetIsEmpty(arg2)) {
190
11.0k
  xmlXPathReturnNodeSet(ctxt, arg1);
191
192
11.0k
  xmlXPathFreeNodeSet(arg2);
193
194
11.0k
  return;
195
11.0k
    }
196
    /* !!! must be sorted */
197
17.6k
    ret = xmlXPathNodeLeadingSorted(arg1, xmlXPathNodeSetItem(arg2, 0));
198
199
17.6k
    xmlXPathFreeNodeSet(arg1);
200
17.6k
    xmlXPathFreeNodeSet(arg2);
201
202
17.6k
    xmlXPathReturnNodeSet(ctxt, ret);
203
17.6k
}
204
205
/**
206
 * exsltSetsTrailingFunction:
207
 * @ctxt:  an XPath parser context
208
 * @nargs:  the number of arguments
209
 *
210
 * Wraps #xmlXPathTrailing for use by the XPath processor
211
 */
212
static void
213
53.5k
exsltSetsTrailingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
214
53.5k
    xmlNodeSetPtr arg1, arg2, ret;
215
216
53.5k
    if (nargs != 2) {
217
4.52k
  xmlXPathSetArityError(ctxt);
218
4.52k
  return;
219
4.52k
    }
220
221
49.0k
    arg2 = xmlXPathPopNodeSet(ctxt);
222
49.0k
    if (xmlXPathCheckError(ctxt))
223
2.67k
  return;
224
225
46.3k
    arg1 = xmlXPathPopNodeSet(ctxt);
226
46.3k
    if (xmlXPathCheckError(ctxt)) {
227
1.30k
  xmlXPathFreeNodeSet(arg2);
228
1.30k
  return;
229
1.30k
    }
230
231
    /*  If the second node set is empty, then the first node set is
232
     * returned.
233
     */
234
45.0k
    if (xmlXPathNodeSetIsEmpty(arg2)) {
235
20.5k
  xmlXPathReturnNodeSet(ctxt, arg1);
236
237
20.5k
  xmlXPathFreeNodeSet(arg2);
238
239
20.5k
  return;
240
20.5k
    }
241
    /* !!! mist be sorted */
242
24.4k
    ret = xmlXPathNodeTrailingSorted(arg1, xmlXPathNodeSetItem(arg2, 0));
243
244
24.4k
    xmlXPathFreeNodeSet(arg1);
245
24.4k
    xmlXPathFreeNodeSet(arg2);
246
247
24.4k
    xmlXPathReturnNodeSet(ctxt, ret);
248
24.4k
}
249
250
/**
251
 * exsltSetsRegister:
252
 *
253
 * Registers the EXSLT - Sets module
254
 */
255
256
void
257
2.46k
exsltSetsRegister (void) {
258
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "difference",
259
2.46k
           EXSLT_SETS_NAMESPACE,
260
2.46k
           exsltSetsDifferenceFunction);
261
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "intersection",
262
2.46k
           EXSLT_SETS_NAMESPACE,
263
2.46k
           exsltSetsIntersectionFunction);
264
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "distinct",
265
2.46k
           EXSLT_SETS_NAMESPACE,
266
2.46k
           exsltSetsDistinctFunction);
267
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "has-same-node",
268
2.46k
           EXSLT_SETS_NAMESPACE,
269
2.46k
           exsltSetsHasSameNodesFunction);
270
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "leading",
271
2.46k
           EXSLT_SETS_NAMESPACE,
272
2.46k
           exsltSetsLeadingFunction);
273
2.46k
    xsltRegisterExtModuleFunction ((const xmlChar *) "trailing",
274
2.46k
           EXSLT_SETS_NAMESPACE,
275
2.46k
           exsltSetsTrailingFunction);
276
2.46k
}
277
278
/**
279
 * exsltSetsXpathCtxtRegister:
280
 *
281
 * Registers the EXSLT - Sets module for use outside XSLT
282
 */
283
int
284
exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix)
285
0
{
286
0
    if (ctxt
287
0
        && prefix
288
0
        && !xmlXPathRegisterNs(ctxt,
289
0
                               prefix,
290
0
                               (const xmlChar *) EXSLT_SETS_NAMESPACE)
291
0
        && !xmlXPathRegisterFuncNS(ctxt,
292
0
                                   (const xmlChar *) "difference",
293
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
294
0
                                   exsltSetsDifferenceFunction)
295
0
        && !xmlXPathRegisterFuncNS(ctxt,
296
0
                                   (const xmlChar *) "intersection",
297
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
298
0
                                   exsltSetsIntersectionFunction)
299
0
        && !xmlXPathRegisterFuncNS(ctxt,
300
0
                                   (const xmlChar *) "distinct",
301
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
302
0
                                   exsltSetsDistinctFunction)
303
0
        && !xmlXPathRegisterFuncNS(ctxt,
304
0
                                   (const xmlChar *) "has-same-node",
305
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
306
0
                                   exsltSetsHasSameNodesFunction)
307
0
        && !xmlXPathRegisterFuncNS(ctxt,
308
0
                                   (const xmlChar *) "leading",
309
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
310
0
                                   exsltSetsLeadingFunction)
311
0
        && !xmlXPathRegisterFuncNS(ctxt,
312
0
                                   (const xmlChar *) "trailing",
313
0
                                   (const xmlChar *) EXSLT_SETS_NAMESPACE,
314
0
                                   exsltSetsTrailingFunction)) {
315
0
        return 0;
316
0
    }
317
0
    return -1;
318
0
}