Coverage Report

Created: 2026-04-12 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxslt/libxslt/extra.c
Line
Count
Source
1
/*
2
 * extra.c: Implementation of non-standard features
3
 *
4
 * Reference:
5
 *   Michael Kay "XSLT Programmer's Reference" pp 637-643
6
 *   The node-set() extension function
7
 *
8
 * See Copyright for the status of this software.
9
 *
10
 * daniel@veillard.com
11
 */
12
13
#define IN_LIBXSLT
14
#include "libxslt.h"
15
16
#include <string.h>
17
#include <stdlib.h>
18
19
#include <libxml/xmlmemory.h>
20
#include <libxml/tree.h>
21
#include <libxml/hash.h>
22
#include <libxml/xmlerror.h>
23
#include <libxml/parserInternals.h>
24
#include "xslt.h"
25
#include "xsltInternals.h"
26
#include "xsltutils.h"
27
#include "extensions.h"
28
#include "variables.h"
29
#include "transform.h"
30
#include "extra.h"
31
#include "preproc.h"
32
33
#ifdef WITH_XSLT_DEBUG
34
#define WITH_XSLT_DEBUG_EXTRA
35
#endif
36
37
/************************************************************************
38
 *                  *
39
 *    Handling of XSLT debugging        *
40
 *                  *
41
 ************************************************************************/
42
43
/**
44
 * xsltDebug:
45
 * @ctxt:  an XSLT processing context
46
 * @node:  The current node
47
 * @inst:  the instruction in the stylesheet
48
 * @comp:  precomputed information
49
 *
50
 * Process an debug node
51
 */
52
void
53
xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED,
54
          xmlNodePtr inst ATTRIBUTE_UNUSED,
55
          xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
56
402
{
57
402
    int i, j;
58
59
402
    xsltGenericError(xsltGenericErrorContext, "Templates:\n");
60
5.88k
    for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
61
5.48k
        xsltGenericError(xsltGenericErrorContext, "#%d ", i);
62
5.48k
        if (ctxt->templTab[j]->name != NULL)
63
45
            xsltGenericError(xsltGenericErrorContext, "name %s ",
64
45
                             ctxt->templTab[j]->name);
65
5.48k
        if (ctxt->templTab[j]->match != NULL)
66
5.43k
            xsltGenericError(xsltGenericErrorContext, "name %s ",
67
5.43k
                             ctxt->templTab[j]->match);
68
5.48k
        if (ctxt->templTab[j]->mode != NULL)
69
21
            xsltGenericError(xsltGenericErrorContext, "name %s ",
70
21
                             ctxt->templTab[j]->mode);
71
5.48k
        xsltGenericError(xsltGenericErrorContext, "\n");
72
5.48k
    }
73
402
    xsltGenericError(xsltGenericErrorContext, "Variables:\n");
74
1.63k
    for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
75
1.23k
        xsltStackElemPtr cur;
76
77
1.23k
        if (ctxt->varsTab[j] == NULL)
78
0
            continue;
79
1.23k
        xsltGenericError(xsltGenericErrorContext, "#%d\n", i);
80
1.23k
        cur = ctxt->varsTab[j];
81
2.48k
        while (cur != NULL) {
82
1.25k
            if (cur->comp == NULL) {
83
0
                xsltGenericError(xsltGenericErrorContext,
84
0
                                 "corrupted !!!\n");
85
1.25k
            } else if (cur->comp->type == XSLT_FUNC_PARAM) {
86
253
                xsltGenericError(xsltGenericErrorContext, "param ");
87
1.00k
            } else if (cur->comp->type == XSLT_FUNC_VARIABLE) {
88
958
                xsltGenericError(xsltGenericErrorContext, "var ");
89
958
            }
90
1.25k
            if (cur->name != NULL)
91
1.25k
                xsltGenericError(xsltGenericErrorContext, "%s ",
92
1.25k
                                 cur->name);
93
0
            else
94
0
                xsltGenericError(xsltGenericErrorContext, "noname !!!!");
95
1.25k
#ifdef LIBXML_DEBUG_ENABLED
96
1.25k
            if (cur->value != NULL) {
97
1.24k
                if ((xsltGenericDebugContext == stdout) ||
98
1.24k
                    (xsltGenericDebugContext == stderr))
99
0
                    xmlXPathDebugDumpObject((FILE*)xsltGenericDebugContext,
100
0
                                            cur->value, 1);
101
1.24k
            } else {
102
8
                xsltGenericError(xsltGenericErrorContext, "NULL !!!!");
103
8
            }
104
1.25k
#endif
105
1.25k
            xsltGenericError(xsltGenericErrorContext, "\n");
106
1.25k
            cur = cur->next;
107
1.25k
        }
108
109
1.23k
    }
110
402
}
111
112
/************************************************************************
113
 *                  *
114
 *    Classic extensions as described by M. Kay   *
115
 *                  *
116
 ************************************************************************/
117
118
/**
119
 * xsltFunctionNodeSet:
120
 * @ctxt:  the XPath Parser context
121
 * @nargs:  the number of arguments
122
 *
123
 * Implement the node-set() XSLT function
124
 *   node-set node-set(result-tree)
125
 *
126
 * This function is available in libxslt, saxon or xt namespace.
127
 */
128
void
129
10.3k
xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){
130
10.3k
    if (nargs != 1) {
131
131
  xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
132
131
    "node-set() : expects one result-tree arg\n");
133
131
  ctxt->error = XPATH_INVALID_ARITY;
134
131
  return;
135
131
    }
136
10.2k
    if ((ctxt->value == NULL) ||
137
10.2k
  ((ctxt->value->type != XPATH_XSLT_TREE) &&
138
255
   (ctxt->value->type != XPATH_NODESET))) {
139
0
  xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
140
0
      "node-set() invalid arg expecting a result tree\n");
141
0
  ctxt->error = XPATH_INVALID_TYPE;
142
0
  return;
143
0
    }
144
10.2k
    if (ctxt->value->type == XPATH_XSLT_TREE) {
145
9.97k
  ctxt->value->type = XPATH_NODESET;
146
9.97k
    }
147
10.2k
}
148
149
/**
150
 * xsltRegisterExtras:
151
 * @ctxt:  a XSLT process context
152
 *
153
 * Registers the built-in extensions. This function is deprecated, use
154
 * xsltRegisterAllExtras instead.
155
 */
156
void
157
0
xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) {
158
0
    xsltRegisterAllExtras();
159
0
}
160
161
/**
162
 * xsltRegisterAllExtras:
163
 *
164
 * Registers the built-in extensions
165
 */
166
void
167
4
xsltRegisterAllExtras (void) {
168
4
    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
169
4
          XSLT_LIBXSLT_NAMESPACE,
170
4
          xsltFunctionNodeSet);
171
4
    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
172
4
          XSLT_SAXON_NAMESPACE,
173
4
          xsltFunctionNodeSet);
174
4
    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
175
4
          XSLT_XT_NAMESPACE,
176
4
          xsltFunctionNodeSet);
177
4
    xsltRegisterExtModuleElement((const xmlChar *) "debug",
178
4
         XSLT_LIBXSLT_NAMESPACE,
179
4
         NULL,
180
4
         xsltDebug);
181
4
    xsltRegisterExtModuleElement((const xmlChar *) "output",
182
4
         XSLT_SAXON_NAMESPACE,
183
4
         xsltDocumentComp,
184
4
         xsltDocumentElem);
185
4
    xsltRegisterExtModuleElement((const xmlChar *) "write",
186
4
         XSLT_XALAN_NAMESPACE,
187
4
         xsltDocumentComp,
188
4
         xsltDocumentElem);
189
4
    xsltRegisterExtModuleElement((const xmlChar *) "document",
190
4
         XSLT_XT_NAMESPACE,
191
4
         xsltDocumentComp,
192
4
         xsltDocumentElem);
193
4
    xsltRegisterExtModuleElement((const xmlChar *) "document",
194
4
         XSLT_NAMESPACE,
195
4
         xsltDocumentComp,
196
4
         xsltDocumentElem);
197
4
}