Line data Source code
1 : /**
2 : * XML Security Library (http://www.aleksey.com/xmlsec).
3 : *
4 : * Common XML Doc utility functions
5 : *
6 : * This is free software; see Copyright file in the source
7 : * distribution for preciese wording.
8 : *
9 : * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
10 : */
11 : #include "globals.h"
12 :
13 : #include <stdlib.h>
14 : #include <string.h>
15 : #include <ctype.h>
16 : #include <errno.h>
17 :
18 : #include <libxml/tree.h>
19 : #include <libxml/valid.h>
20 : #include <libxml/xpath.h>
21 : #include <libxml/xpathInternals.h>
22 :
23 : #include <xmlsec/xmlsec.h>
24 : #include <xmlsec/xmltree.h>
25 : #include <xmlsec/parser.h>
26 : #include <xmlsec/private.h>
27 : #include <xmlsec/base64.h>
28 : #include <xmlsec/errors.h>
29 :
30 : /**
31 : * xmlSecFindChild:
32 : * @parent: the pointer to XML node.
33 : * @name: the name.
34 : * @ns: the namespace href (may be NULL).
35 : *
36 : * Searches a direct child of the @parent node having given name and
37 : * namespace href.
38 : *
39 : * Returns: the pointer to the found node or NULL if an error occurs or
40 : * node is not found.
41 : */
42 : xmlNodePtr
43 0 : xmlSecFindChild(const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
44 : xmlNodePtr cur;
45 :
46 0 : xmlSecAssert2(parent != NULL, NULL);
47 0 : xmlSecAssert2(name != NULL, NULL);
48 :
49 0 : cur = parent->children;
50 0 : while(cur != NULL) {
51 0 : if(cur->type == XML_ELEMENT_NODE) {
52 0 : if(xmlSecCheckNodeName(cur, name, ns)) {
53 0 : return(cur);
54 : }
55 : }
56 0 : cur = cur->next;
57 : }
58 0 : return(NULL);
59 : }
60 :
61 : /**
62 : * xmlSecFindParent:
63 : * @cur: the pointer to an XML node.
64 : * @name: the name.
65 : * @ns: the namespace href (may be NULL).
66 : *
67 : * Searches the ancestors axis of the @cur node for a node having given name
68 : * and namespace href.
69 : *
70 : * Returns: the pointer to the found node or NULL if an error occurs or
71 : * node is not found.
72 : */
73 : xmlNodePtr
74 0 : xmlSecFindParent(const xmlNodePtr cur, const xmlChar *name, const xmlChar *ns) {
75 0 : xmlSecAssert2(cur != NULL, NULL);
76 0 : xmlSecAssert2(name != NULL, NULL);
77 :
78 0 : if(xmlSecCheckNodeName(cur, name, ns)) {
79 0 : return(cur);
80 0 : } else if(cur->parent != NULL) {
81 0 : return(xmlSecFindParent(cur->parent, name, ns));
82 : }
83 0 : return(NULL);
84 : }
85 :
86 : /**
87 : * xmlSecFindNode:
88 : * @parent: the pointer to XML node.
89 : * @name: the name.
90 : * @ns: the namespace href (may be NULL).
91 : *
92 : * Searches all children of the @parent node having given name and
93 : * namespace href.
94 : *
95 : * Returns: the pointer to the found node or NULL if an error occurs or
96 : * node is not found.
97 : */
98 : xmlNodePtr
99 0 : xmlSecFindNode(const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
100 : xmlNodePtr cur;
101 : xmlNodePtr ret;
102 :
103 0 : xmlSecAssert2(name != NULL, NULL);
104 :
105 0 : cur = parent;
106 0 : while(cur != NULL) {
107 0 : if((cur->type == XML_ELEMENT_NODE) && xmlSecCheckNodeName(cur, name, ns)) {
108 0 : return(cur);
109 : }
110 0 : if(cur->children != NULL) {
111 0 : ret = xmlSecFindNode(cur->children, name, ns);
112 0 : if(ret != NULL) {
113 0 : return(ret);
114 : }
115 : }
116 0 : cur = cur->next;
117 : }
118 0 : return(NULL);
119 : }
120 :
121 : /**
122 : * xmlSecGetNodeNsHref:
123 : * @cur: the pointer to node.
124 : *
125 : * Get's node's namespace href.
126 : *
127 : * Returns: node's namespace href.
128 : */
129 : const xmlChar*
130 0 : xmlSecGetNodeNsHref(const xmlNodePtr cur) {
131 : xmlNsPtr ns;
132 :
133 0 : xmlSecAssert2(cur != NULL, NULL);
134 :
135 : /* do we have a namespace in the node? */
136 0 : if(cur->ns != NULL) {
137 0 : return(cur->ns->href);
138 : }
139 :
140 : /* search for default namespace */
141 0 : ns = xmlSearchNs(cur->doc, cur, NULL);
142 0 : if(ns != NULL) {
143 0 : return(ns->href);
144 : }
145 :
146 0 : return(NULL);
147 : }
148 :
149 : /**
150 : * xmlSecCheckNodeName:
151 : * @cur: the pointer to an XML node.
152 : * @name: the name,
153 : * @ns: the namespace href.
154 : *
155 : * Checks that the node has a given name and a given namespace href.
156 : *
157 : * Returns: 1 if the node matches or 0 otherwise.
158 : */
159 : int
160 0 : xmlSecCheckNodeName(const xmlNodePtr cur, const xmlChar *name, const xmlChar *ns) {
161 0 : xmlSecAssert2(cur != NULL, 0);
162 :
163 0 : return(xmlStrEqual(cur->name, name) &&
164 0 : xmlStrEqual(xmlSecGetNodeNsHref(cur), ns));
165 : }
166 :
167 : /**
168 : * xmlSecAddChild:
169 : * @parent: the pointer to an XML node.
170 : * @name: the new node name.
171 : * @ns: the new node namespace.
172 : *
173 : * Adds a child to the node @parent with given @name and namespace @ns.
174 : *
175 : * Returns: pointer to the new node or NULL if an error occurs.
176 : */
177 : xmlNodePtr
178 0 : xmlSecAddChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
179 : xmlNodePtr cur;
180 : xmlNodePtr text;
181 :
182 0 : xmlSecAssert2(parent != NULL, NULL);
183 0 : xmlSecAssert2(name != NULL, NULL);
184 :
185 0 : if(parent->children == NULL) {
186 : /* TODO: add indents */
187 0 : text = xmlNewText(xmlSecStringCR);
188 0 : if(text == NULL) {
189 0 : xmlSecError(XMLSEC_ERRORS_HERE,
190 : NULL,
191 : "xmlNewText",
192 : XMLSEC_ERRORS_R_XML_FAILED,
193 : XMLSEC_ERRORS_NO_MESSAGE);
194 0 : return(NULL);
195 : }
196 0 : xmlAddChild(parent, text);
197 : }
198 :
199 0 : cur = xmlNewChild(parent, NULL, name, NULL);
200 0 : if(cur == NULL) {
201 0 : xmlSecError(XMLSEC_ERRORS_HERE,
202 : NULL,
203 : "xmlNewChild",
204 : XMLSEC_ERRORS_R_XML_FAILED,
205 : XMLSEC_ERRORS_NO_MESSAGE);
206 0 : return(NULL);
207 : }
208 :
209 : /* namespaces support */
210 0 : if(ns != NULL) {
211 : xmlNsPtr nsPtr;
212 :
213 : /* find namespace by href and check that its prefix is not overwritten */
214 0 : nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
215 0 : if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
216 0 : nsPtr = xmlNewNs(cur, ns, NULL);
217 : }
218 0 : xmlSetNs(cur, nsPtr);
219 : }
220 :
221 : /* TODO: add indents */
222 0 : text = xmlNewText(xmlSecStringCR);
223 0 : if(text == NULL) {
224 0 : xmlSecError(XMLSEC_ERRORS_HERE,
225 : NULL,
226 : "xmlNewText",
227 : XMLSEC_ERRORS_R_XML_FAILED,
228 : XMLSEC_ERRORS_NO_MESSAGE);
229 0 : return(NULL);
230 : }
231 0 : xmlAddChild(parent, text);
232 :
233 0 : return(cur);
234 : }
235 :
236 : /**
237 : * xmlSecAddChildNode:
238 : * @parent: the pointer to an XML node.
239 : * @child: the new node.
240 : *
241 : * Adds @child node to the @parent node.
242 : *
243 : * Returns: pointer to the new node or NULL if an error occurs.
244 : */
245 : xmlNodePtr
246 0 : xmlSecAddChildNode(xmlNodePtr parent, xmlNodePtr child) {
247 : xmlNodePtr text;
248 :
249 0 : xmlSecAssert2(parent != NULL, NULL);
250 0 : xmlSecAssert2(child != NULL, NULL);
251 :
252 0 : if(parent->children == NULL) {
253 : /* TODO: add indents */
254 0 : text = xmlNewText(xmlSecStringCR);
255 0 : if(text == NULL) {
256 0 : xmlSecError(XMLSEC_ERRORS_HERE,
257 : NULL,
258 : "xmlNewText",
259 : XMLSEC_ERRORS_R_XML_FAILED,
260 : XMLSEC_ERRORS_NO_MESSAGE);
261 0 : return(NULL);
262 : }
263 0 : xmlAddChild(parent, text);
264 : }
265 :
266 0 : xmlAddChild(parent, child);
267 :
268 : /* TODO: add indents */
269 0 : text = xmlNewText(xmlSecStringCR);
270 0 : if(text == NULL) {
271 0 : xmlSecError(XMLSEC_ERRORS_HERE,
272 : NULL,
273 : "xmlNewText",
274 : XMLSEC_ERRORS_R_XML_FAILED,
275 : XMLSEC_ERRORS_NO_MESSAGE);
276 0 : return(NULL);
277 : }
278 0 : xmlAddChild(parent, text);
279 :
280 0 : return(child);
281 : }
282 :
283 : /**
284 : * xmlSecAddNextSibling
285 : * @node: the pointer to an XML node.
286 : * @name: the new node name.
287 : * @ns: the new node namespace.
288 : *
289 : * Adds next sibling to the node @node with given @name and namespace @ns.
290 : *
291 : * Returns: pointer to the new node or NULL if an error occurs.
292 : */
293 : xmlNodePtr
294 0 : xmlSecAddNextSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) {
295 : xmlNodePtr cur;
296 : xmlNodePtr text;
297 :
298 0 : xmlSecAssert2(node != NULL, NULL);
299 0 : xmlSecAssert2(name != NULL, NULL);
300 :
301 0 : cur = xmlNewNode(NULL, name);
302 0 : if(cur == NULL) {
303 0 : xmlSecError(XMLSEC_ERRORS_HERE,
304 : NULL,
305 : "xmlNewNode",
306 : XMLSEC_ERRORS_R_XML_FAILED,
307 : XMLSEC_ERRORS_NO_MESSAGE);
308 0 : return(NULL);
309 : }
310 0 : xmlAddNextSibling(node, cur);
311 :
312 : /* namespaces support */
313 0 : if(ns != NULL) {
314 : xmlNsPtr nsPtr;
315 :
316 : /* find namespace by href and check that its prefix is not overwritten */
317 0 : nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
318 0 : if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
319 0 : nsPtr = xmlNewNs(cur, ns, NULL);
320 : }
321 0 : xmlSetNs(cur, nsPtr);
322 : }
323 :
324 : /* TODO: add indents */
325 0 : text = xmlNewText(xmlSecStringCR);
326 0 : if(text == NULL) {
327 0 : xmlSecError(XMLSEC_ERRORS_HERE,
328 : NULL,
329 : "xmlNewText",
330 : XMLSEC_ERRORS_R_XML_FAILED,
331 : XMLSEC_ERRORS_NO_MESSAGE);
332 0 : return(NULL);
333 : }
334 0 : xmlAddNextSibling(node, text);
335 :
336 0 : return(cur);
337 : }
338 :
339 : /**
340 : * xmlSecAddPrevSibling
341 : * @node: the pointer to an XML node.
342 : * @name: the new node name.
343 : * @ns: the new node namespace.
344 : *
345 : * Adds prev sibling to the node @node with given @name and namespace @ns.
346 : *
347 : * Returns: pointer to the new node or NULL if an error occurs.
348 : */
349 : xmlNodePtr
350 0 : xmlSecAddPrevSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) {
351 : xmlNodePtr cur;
352 : xmlNodePtr text;
353 :
354 0 : xmlSecAssert2(node != NULL, NULL);
355 0 : xmlSecAssert2(name != NULL, NULL);
356 :
357 0 : cur = xmlNewNode(NULL, name);
358 0 : if(cur == NULL) {
359 0 : xmlSecError(XMLSEC_ERRORS_HERE,
360 : NULL,
361 : "xmlNewNode",
362 : XMLSEC_ERRORS_R_XML_FAILED,
363 : XMLSEC_ERRORS_NO_MESSAGE);
364 0 : return(NULL);
365 : }
366 0 : xmlAddPrevSibling(node, cur);
367 :
368 : /* namespaces support */
369 0 : if(ns != NULL) {
370 : xmlNsPtr nsPtr;
371 :
372 : /* find namespace by href and check that its prefix is not overwritten */
373 0 : nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
374 0 : if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
375 0 : nsPtr = xmlNewNs(cur, ns, NULL);
376 : }
377 0 : xmlSetNs(cur, nsPtr);
378 : }
379 :
380 : /* TODO: add indents */
381 0 : text = xmlNewText(xmlSecStringCR);
382 0 : if(text == NULL) {
383 0 : xmlSecError(XMLSEC_ERRORS_HERE,
384 : NULL,
385 : "xmlNewText",
386 : XMLSEC_ERRORS_R_XML_FAILED,
387 : XMLSEC_ERRORS_NO_MESSAGE);
388 0 : return(NULL);
389 : }
390 0 : xmlAddPrevSibling(node, text);
391 :
392 0 : return(cur);
393 : }
394 :
395 : /**
396 : * xmlSecGetNextElementNode:
397 : * @cur: the pointer to an XML node.
398 : *
399 : * Seraches for the next element node.
400 : *
401 : * Returns: the pointer to next element node or NULL if it is not found.
402 : */
403 : xmlNodePtr
404 0 : xmlSecGetNextElementNode(xmlNodePtr cur) {
405 :
406 0 : while((cur != NULL) && (cur->type != XML_ELEMENT_NODE)) {
407 0 : cur = cur->next;
408 : }
409 0 : return(cur);
410 : }
411 :
412 : /**
413 : * xmlSecReplaceNode:
414 : * @node: the current node.
415 : * @newNode: the new node.
416 : *
417 : * Swaps the @node and @newNode in the XML tree.
418 : *
419 : * Returns: 0 on success or a negative value if an error occurs.
420 : */
421 : int
422 0 : xmlSecReplaceNode(xmlNodePtr node, xmlNodePtr newNode) {
423 0 : return xmlSecReplaceNodeAndReturn(node, newNode, NULL);
424 : }
425 :
426 : /**
427 : * xmlSecReplaceNodeAndReturn:
428 : * @node: the current node.
429 : * @newNode: the new node.
430 : * @replaced: the replaced node, or release it if NULL is given
431 : *
432 : * Swaps the @node and @newNode in the XML tree.
433 : *
434 : * Returns: 0 on success or a negative value if an error occurs.
435 : */
436 : int
437 0 : xmlSecReplaceNodeAndReturn(xmlNodePtr node, xmlNodePtr newNode, xmlNodePtr* replaced) {
438 : xmlNodePtr oldNode;
439 0 : int restoreRoot = 0;
440 :
441 0 : xmlSecAssert2(node != NULL, -1);
442 0 : xmlSecAssert2(newNode != NULL, -1);
443 :
444 : /* fix documents children if necessary first */
445 0 : if((node->doc != NULL) && (node->doc->children == node)) {
446 0 : node->doc->children = node->next;
447 0 : restoreRoot = 1;
448 : }
449 0 : if((newNode->doc != NULL) && (newNode->doc->children == newNode)) {
450 0 : newNode->doc->children = newNode->next;
451 : }
452 :
453 0 : oldNode = xmlReplaceNode(node, newNode);
454 0 : if(oldNode == NULL) {
455 0 : xmlSecError(XMLSEC_ERRORS_HERE,
456 : NULL,
457 : "xmlReplaceNode",
458 : XMLSEC_ERRORS_R_XML_FAILED,
459 : XMLSEC_ERRORS_NO_MESSAGE);
460 0 : return(-1);
461 : }
462 :
463 0 : if(restoreRoot != 0) {
464 0 : xmlDocSetRootElement(oldNode->doc, newNode);
465 : }
466 :
467 : /* return the old node if requested */
468 0 : if(replaced != NULL) {
469 0 : (*replaced) = oldNode;
470 : } else {
471 0 : xmlFreeNode(oldNode);
472 : }
473 :
474 0 : return(0);
475 : }
476 :
477 : /**
478 : * xmlSecReplaceContent
479 : * @node: the current node.
480 : * @newNode: the new node.
481 : *
482 : * Swaps the content of @node and @newNode.
483 : *
484 : * Returns: 0 on success or a negative value if an error occurs.
485 : */
486 : int
487 0 : xmlSecReplaceContent(xmlNodePtr node, xmlNodePtr newNode) {
488 0 : return xmlSecReplaceContentAndReturn(node, newNode, NULL);
489 : }
490 :
491 : /**
492 : * xmlSecReplaceContentAndReturn
493 : * @node: the current node.
494 : * @newNode: the new node.
495 : * @replaced: the replaced nodes, or release them if NULL is given
496 : *
497 : * Swaps the content of @node and @newNode.
498 : *
499 : * Returns: 0 on success or a negative value if an error occurs.
500 : */
501 : int
502 0 : xmlSecReplaceContentAndReturn(xmlNodePtr node, xmlNodePtr newNode, xmlNodePtr *replaced) {
503 0 : xmlSecAssert2(node != NULL, -1);
504 0 : xmlSecAssert2(newNode != NULL, -1);
505 :
506 0 : xmlUnlinkNode(newNode);
507 0 : xmlSetTreeDoc(newNode, node->doc);
508 :
509 : /* return the old nodes if requested */
510 0 : if(replaced != NULL) {
511 : xmlNodePtr cur, next, tail;
512 :
513 0 : (*replaced) = tail = NULL;
514 0 : for(cur = node->children; (cur != NULL); cur = next) {
515 0 : next = cur->next;
516 0 : if((*replaced) != NULL) {
517 : /* n is unlinked in this function */
518 0 : xmlAddNextSibling(tail, cur);
519 0 : tail = cur;
520 : } else {
521 : /* this is the first node, (*replaced) is the head */
522 0 : xmlUnlinkNode(cur);
523 0 : (*replaced) = tail = cur;
524 : }
525 : }
526 : } else {
527 : /* just delete the content */
528 0 : xmlNodeSetContent(node, NULL);
529 : }
530 :
531 0 : xmlAddChild(node, newNode);
532 0 : xmlSetTreeDoc(newNode, node->doc);
533 :
534 0 : return(0);
535 : }
536 :
537 : /**
538 : * xmlSecReplaceNodeBuffer:
539 : * @node: the current node.
540 : * @buffer: the XML data.
541 : * @size: the XML data size.
542 : *
543 : * Swaps the @node and the parsed XML data from the @buffer in the XML tree.
544 : *
545 : * Returns: 0 on success or a negative value if an error occurs.
546 : */
547 : int
548 0 : xmlSecReplaceNodeBuffer(xmlNodePtr node, const xmlSecByte *buffer, xmlSecSize size) {
549 0 : return xmlSecReplaceNodeBufferAndReturn(node, buffer, size, NULL);
550 : }
551 :
552 : /**
553 : * xmlSecReplaceNodeBufferAndReturn:
554 : * @node: the current node.
555 : * @buffer: the XML data.
556 : * @size: the XML data size.
557 : * @replaced: the replaced nodes, or release them if NULL is given
558 : *
559 : * Swaps the @node and the parsed XML data from the @buffer in the XML tree.
560 : *
561 : * Returns: 0 on success or a negative value if an error occurs.
562 : */
563 : int
564 0 : xmlSecReplaceNodeBufferAndReturn(xmlNodePtr node, const xmlSecByte *buffer, xmlSecSize size, xmlNodePtr *replaced) {
565 0 : xmlNodePtr results = NULL;
566 0 : xmlNodePtr next = NULL;
567 :
568 0 : xmlSecAssert2(node != NULL, -1);
569 0 : xmlSecAssert2(node->parent != NULL, -1);
570 :
571 : /* parse buffer in the context of node's parent */
572 0 : if(xmlParseInNodeContext(node->parent, (const char*)buffer, size, XML_PARSE_NODICT, &results) != XML_ERR_OK) {
573 0 : xmlSecError(XMLSEC_ERRORS_HERE,
574 : NULL,
575 : "xmlParseInNodeContext",
576 : XMLSEC_ERRORS_R_XML_FAILED,
577 : "Failed to parse content");
578 0 : return(-1);
579 : }
580 :
581 : /* add new nodes */
582 0 : while (results != NULL) {
583 0 : next = results->next;
584 0 : xmlAddPrevSibling(node, results);
585 0 : results = next;
586 : }
587 :
588 : /* remove old node */
589 0 : xmlUnlinkNode(node);
590 :
591 : /* return the old node if requested */
592 0 : if(replaced != NULL) {
593 0 : (*replaced) = node;
594 : } else {
595 0 : xmlFreeNode(node);
596 : }
597 :
598 0 : return(0);
599 : }
600 :
601 : /**
602 : * xmlSecNodeEncodeAndSetContent:
603 : * @node: the pointer to an XML node.
604 : * @buffer: the pointer to the node content.
605 : *
606 : * Encodes "special" characters in the @buffer and sets the result
607 : * as the node content.
608 : *
609 : * Returns: 0 on success or a negative value if an error occurs.
610 : */
611 : int
612 0 : xmlSecNodeEncodeAndSetContent(xmlNodePtr node, const xmlChar * buffer) {
613 0 : xmlSecAssert2(node != NULL, -1);
614 0 : xmlSecAssert2(node->doc != NULL, -1);
615 :
616 0 : if(buffer != NULL) {
617 : xmlChar * tmp;
618 :
619 0 : tmp = xmlEncodeSpecialChars(node->doc, buffer);
620 0 : if (tmp == NULL) {
621 0 : xmlSecError(XMLSEC_ERRORS_HERE,
622 : NULL,
623 : "xmlEncodeSpecialChars",
624 : XMLSEC_ERRORS_R_XML_FAILED,
625 : "Failed to encode special characters");
626 0 : return(-1);
627 : }
628 :
629 0 : xmlNodeSetContent(node, tmp);
630 0 : xmlFree(tmp);
631 : } else {
632 0 : xmlNodeSetContent(node, NULL);
633 : }
634 :
635 0 : return(0);
636 : }
637 :
638 : /**
639 : * xmlSecAddIDs:
640 : * @doc: the pointer to an XML document.
641 : * @cur: the pointer to an XML node.
642 : * @ids: the pointer to a NULL terminated list of ID attributes.
643 : *
644 : * Walks thru all children of the @cur node and adds all attributes
645 : * from the @ids list to the @doc document IDs attributes hash.
646 : */
647 : void
648 0 : xmlSecAddIDs(xmlDocPtr doc, xmlNodePtr cur, const xmlChar** ids) {
649 0 : xmlNodePtr children = NULL;
650 :
651 0 : xmlSecAssert(doc != NULL);
652 0 : xmlSecAssert(ids != NULL);
653 :
654 0 : if((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
655 : xmlAttrPtr attr;
656 : xmlAttrPtr tmp;
657 : int i;
658 : xmlChar* name;
659 :
660 0 : for(attr = cur->properties; attr != NULL; attr = attr->next) {
661 0 : for(i = 0; ids[i] != NULL; ++i) {
662 0 : if(xmlStrEqual(attr->name, ids[i])) {
663 0 : name = xmlNodeListGetString(doc, attr->children, 1);
664 0 : if(name != NULL) {
665 0 : tmp = xmlGetID(doc, name);
666 0 : if(tmp == NULL) {
667 0 : xmlAddID(NULL, doc, name, attr);
668 0 : } else if(tmp != attr) {
669 0 : xmlSecError(XMLSEC_ERRORS_HERE,
670 : NULL,
671 : NULL,
672 : XMLSEC_ERRORS_R_INVALID_DATA,
673 : "id=%s already defined",
674 : xmlSecErrorsSafeString(name));
675 : }
676 0 : xmlFree(name);
677 : }
678 : }
679 : }
680 : }
681 :
682 0 : children = cur->children;
683 0 : } else if(cur == NULL) {
684 0 : children = doc->children;
685 : }
686 :
687 0 : while(children != NULL) {
688 0 : if(children->type == XML_ELEMENT_NODE) {
689 0 : xmlSecAddIDs(doc, children, ids);
690 : }
691 0 : children = children->next;
692 : }
693 : }
694 :
695 : /**
696 : * xmlSecGenerateAndAddID:
697 : * @node: the node to ID attr to.
698 : * @attrName: the ID attr name.
699 : * @prefix: the prefix to add to the generated ID (can be NULL).
700 : * @len: the length of ID.
701 : *
702 : * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes)
703 : * and puts it in the attribute @attrName.
704 : *
705 : * Returns: 0 on success or a negative value if an error occurs.
706 : */
707 : int
708 0 : xmlSecGenerateAndAddID(xmlNodePtr node, const xmlChar* attrName, const xmlChar* prefix, xmlSecSize len) {
709 : xmlChar* id;
710 : int count;
711 :
712 0 : xmlSecAssert2(node != NULL, -1);
713 0 : xmlSecAssert2(attrName != NULL, -1);
714 :
715 : /* we will try 5 times before giving up */
716 0 : for(count = 0; count < 5; count++) {
717 0 : id = xmlSecGenerateID(prefix, len);
718 0 : if(id == NULL) {
719 0 : xmlSecError(XMLSEC_ERRORS_HERE,
720 : NULL,
721 : "xmlSecGenerateID",
722 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
723 : XMLSEC_ERRORS_NO_MESSAGE);
724 0 : return(-1);
725 : }
726 :
727 0 : if((node->doc == NULL) || (xmlGetID(node->doc, id) == NULL)) {
728 : /* this is a unique ID in the document and we can use it */
729 0 : if(xmlSetProp(node, attrName, id) == NULL) {
730 0 : xmlSecError(XMLSEC_ERRORS_HERE,
731 : NULL,
732 : "xmlSetProp",
733 : XMLSEC_ERRORS_R_XML_FAILED,
734 : XMLSEC_ERRORS_NO_MESSAGE);
735 0 : xmlFree(id);
736 0 : return(-1);
737 : }
738 :
739 0 : xmlFree(id);
740 0 : return(0);
741 : }
742 0 : xmlFree(id);
743 : }
744 :
745 0 : return(-1);
746 : }
747 :
748 : /**
749 : * xmlSecGenerateID:
750 : * @prefix: the prefix to add to the generated ID (can be NULL).
751 : * @len: the length of ID.
752 : *
753 : * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes).
754 : * The caller is responsible for freeing returned string using @xmlFree function.
755 : *
756 : * Returns: pointer to generated ID string or NULL if an error occurs.
757 : */
758 : xmlChar*
759 0 : xmlSecGenerateID(const xmlChar* prefix, xmlSecSize len) {
760 : xmlSecBuffer buffer;
761 : xmlSecSize i, binLen;
762 : xmlChar* res;
763 : xmlChar* p;
764 : int ret;
765 :
766 0 : xmlSecAssert2(len > 0, NULL);
767 :
768 : /* we will do base64 decoding later */
769 0 : binLen = (3 * len + 1) / 4;
770 :
771 0 : ret = xmlSecBufferInitialize(&buffer, binLen + 1);
772 0 : if(ret < 0) {
773 0 : xmlSecError(XMLSEC_ERRORS_HERE,
774 : NULL,
775 : "xmlSecBufferInitialize",
776 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
777 : XMLSEC_ERRORS_NO_MESSAGE);
778 0 : return(NULL);
779 : }
780 0 : xmlSecAssert2(xmlSecBufferGetData(&buffer) != NULL, NULL);
781 0 : xmlSecAssert2(xmlSecBufferGetMaxSize(&buffer) >= binLen, NULL);
782 :
783 0 : ret = xmlSecBufferSetSize(&buffer, binLen);
784 0 : if(ret < 0) {
785 0 : xmlSecError(XMLSEC_ERRORS_HERE,
786 : NULL,
787 : "xmlSecBufferSetSize",
788 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
789 : XMLSEC_ERRORS_NO_MESSAGE);
790 0 : xmlSecBufferFinalize(&buffer);
791 0 : return(NULL);
792 : }
793 0 : xmlSecAssert2(xmlSecBufferGetSize(&buffer) == binLen, NULL);
794 :
795 : /* create random bytes */
796 0 : for(i = 0; i < binLen; i++) {
797 0 : (xmlSecBufferGetData(&buffer)) [i] = (xmlSecByte) (256.0 * rand() / (RAND_MAX + 1.0));
798 : }
799 :
800 : /* base64 encode random bytes */
801 0 : res = xmlSecBase64Encode(xmlSecBufferGetData(&buffer), xmlSecBufferGetSize(&buffer), 0);
802 0 : if((res == NULL) || (xmlStrlen(res) == 0)) {
803 0 : xmlSecError(XMLSEC_ERRORS_HERE,
804 : NULL,
805 : "xmlSecBase64Encode",
806 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
807 : XMLSEC_ERRORS_NO_MESSAGE);
808 0 : xmlSecBufferFinalize(&buffer);
809 0 : return(NULL);
810 : }
811 0 : xmlSecBufferFinalize(&buffer);
812 :
813 : /* truncate the generated id attribute if needed */
814 0 : if(xmlStrlen(res) > (int)len) {
815 0 : res[len] = '\0';
816 : }
817 :
818 : /* we need to cleanup base64 encoded id because ID attr can't have '+' or '/' characters */
819 0 : for(p = res; (*p) != '\0'; p++) {
820 0 : if(((*p) == '+') || ((*p) == '/')) {
821 0 : (*p) = '_';
822 : }
823 : }
824 :
825 : /* add prefix if exist */
826 0 : if(prefix) {
827 : xmlChar* tmp;
828 : xmlSecSize tmpLen;
829 :
830 0 : tmpLen = xmlStrlen(prefix) + xmlStrlen(res) + 1;
831 0 : tmp = xmlMalloc(tmpLen + 1);
832 0 : if(tmp == NULL) {
833 0 : xmlSecError(XMLSEC_ERRORS_HERE,
834 : NULL,
835 : "xmlMalloc",
836 : XMLSEC_ERRORS_R_MALLOC_FAILED,
837 : XMLSEC_ERRORS_NO_MESSAGE);
838 0 : xmlFree(res);
839 0 : return(NULL);
840 : }
841 :
842 0 : xmlSecStrPrintf(tmp, tmpLen, BAD_CAST "%s%s", prefix, res);
843 0 : xmlFree(res);
844 0 : res = tmp;
845 : } else {
846 : /* no prefix: check that ID attribute starts from a letter */
847 0 : if(!(((res[0] >= 'A') && (res[0] <= 'Z')) ||
848 0 : ((res[0] >= 'a') && (res[0] <= 'z')))) {
849 0 : res[0] = 'A';
850 : }
851 : }
852 :
853 0 : return(res);
854 : }
855 :
856 :
857 : /**
858 : * xmlSecCreateTree:
859 : * @rootNodeName: the root node name.
860 : * @rootNodeNs: the root node namespace (otpional).
861 : *
862 : * Creates a new XML tree with one root node @rootNodeName.
863 : *
864 : * Returns: pointer to the newly created tree or NULL if an error occurs.
865 : */
866 : xmlDocPtr
867 0 : xmlSecCreateTree(const xmlChar* rootNodeName, const xmlChar* rootNodeNs) {
868 : xmlDocPtr doc;
869 : xmlNodePtr root;
870 : xmlNsPtr ns;
871 :
872 0 : xmlSecAssert2(rootNodeName != NULL, NULL);
873 :
874 : /* create doc */
875 0 : doc = xmlNewDoc(BAD_CAST "1.0");
876 0 : if(doc == NULL) {
877 0 : xmlSecError(XMLSEC_ERRORS_HERE,
878 : NULL,
879 : "xmlNewDoc",
880 : XMLSEC_ERRORS_R_XML_FAILED,
881 : XMLSEC_ERRORS_NO_MESSAGE);
882 0 : return(NULL);
883 : }
884 :
885 : /* create root node */
886 0 : root = xmlNewDocNode(doc, NULL, rootNodeName, NULL);
887 0 : if(root == NULL) {
888 0 : xmlSecError(XMLSEC_ERRORS_HERE,
889 : NULL,
890 : "xmlNewDocNode",
891 : XMLSEC_ERRORS_R_XML_FAILED,
892 : "node=Keys");
893 0 : xmlFreeDoc(doc);
894 0 : return(NULL);
895 : }
896 0 : xmlDocSetRootElement(doc, root);
897 :
898 : /* and set root node namespace */
899 0 : ns = xmlNewNs(root, rootNodeNs, NULL);
900 0 : if(ns == NULL) {
901 0 : xmlSecError(XMLSEC_ERRORS_HERE,
902 : NULL,
903 : "xmlNewNs",
904 : XMLSEC_ERRORS_R_XML_FAILED,
905 : "ns=%s",
906 : xmlSecErrorsSafeString(rootNodeNs));
907 0 : xmlFreeDoc(doc);
908 0 : return(NULL);
909 : }
910 0 : xmlSetNs(root, ns);
911 :
912 0 : return(doc);
913 : }
914 :
915 : /**
916 : * xmlSecIsEmptyNode:
917 : * @node: the node to check
918 : *
919 : * Checks whethere the @node is empty (i.e. has only whitespaces children).
920 : *
921 : * Returns: 1 if @node is empty, 0 otherwise or a negative value if an error occurs.
922 : */
923 : int
924 0 : xmlSecIsEmptyNode(xmlNodePtr node) {
925 : xmlChar* content;
926 : int res;
927 :
928 0 : xmlSecAssert2(node != NULL, -1);
929 :
930 0 : if(xmlSecGetNextElementNode(node->children) != NULL) {
931 0 : return(0);
932 : }
933 :
934 0 : content = xmlNodeGetContent(node);
935 0 : if(content == NULL) {
936 0 : return(1);
937 : }
938 :
939 0 : res = xmlSecIsEmptyString(content);
940 0 : xmlFree(content);
941 0 : return(res);
942 : }
943 :
944 : /**
945 : * xmlSecIsEmptyString:
946 : * @str: the string to check
947 : *
948 : * Checks whethere the @str is empty (i.e. has only whitespaces children).
949 : *
950 : * Returns: 1 if @str is empty, 0 otherwise or a negative value if an error occurs.
951 : */
952 : int
953 0 : xmlSecIsEmptyString(const xmlChar* str) {
954 0 : xmlSecAssert2(str != NULL, -1);
955 :
956 0 : for( ;*str != '\0'; ++str) {
957 0 : if(!isspace((int)(*str))) {
958 0 : return(0);
959 : }
960 : }
961 0 : return(1);
962 : }
963 :
964 : /**
965 : * xmlSecPrintXmlString:
966 : * @fd: the file descriptor to write the XML string to
967 : * @str: the string
968 : *
969 : * Encodes the @str (e.g. replaces '&' with '&') and writes it to @fd.
970 : *
971 : * Returns: he number of bytes transmitted or a negative value if an error occurs.
972 : */
973 : int
974 0 : xmlSecPrintXmlString(FILE * fd, const xmlChar * str) {
975 : int res;
976 :
977 0 : if(str != NULL) {
978 0 : xmlChar * encoded_str = NULL;
979 0 : encoded_str = xmlEncodeSpecialChars(NULL, str);
980 0 : if(encoded_str == NULL) {
981 0 : xmlSecError(XMLSEC_ERRORS_HERE,
982 : NULL,
983 : "xmlEncodeSpecialChars",
984 : XMLSEC_ERRORS_R_XML_FAILED,
985 : "string=%s",
986 : xmlSecErrorsSafeString(str));
987 0 : return(-1);
988 : }
989 :
990 0 : res = fprintf(fd, "%s", (const char*)encoded_str);
991 0 : xmlFree(encoded_str);
992 : } else {
993 0 : res = fprintf(fd, "NULL");
994 : }
995 :
996 0 : if(res < 0) {
997 0 : xmlSecError(XMLSEC_ERRORS_HERE,
998 : NULL,
999 : "fprintf",
1000 : XMLSEC_ERRORS_R_IO_FAILED,
1001 : "res=%d,errno=%d",
1002 0 : res, errno);
1003 0 : return(-1);
1004 : }
1005 0 : return(res);
1006 : }
1007 :
1008 :
1009 : /**
1010 : * xmlSecGetQName:
1011 : * @node: the context node.
1012 : * @href: the QName href (can be NULL).
1013 : * @local: the QName local part.
1014 : *
1015 : * Creates QName (prefix:local) from @href and @local in the context of the @node.
1016 : * Caller is responsible for freeing returned string with xmlFree.
1017 : *
1018 : * Returns: qname or NULL if an error occurs.
1019 : */
1020 : xmlChar*
1021 0 : xmlSecGetQName(xmlNodePtr node, const xmlChar* href, const xmlChar* local) {
1022 : xmlChar* qname;
1023 : xmlNsPtr ns;
1024 :
1025 0 : xmlSecAssert2(node != NULL, NULL);
1026 0 : xmlSecAssert2(local != NULL, NULL);
1027 :
1028 : /* we don't want to create namespace node ourselves because
1029 : * it might cause collisions */
1030 0 : ns = xmlSearchNsByHref(node->doc, node, href);
1031 0 : if((ns == NULL) && (href != NULL)) {
1032 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1033 : NULL,
1034 : "xmlSearchNsByHref",
1035 : XMLSEC_ERRORS_R_XML_FAILED,
1036 : "node=%s,href=%s",
1037 0 : xmlSecErrorsSafeString(node->name),
1038 : xmlSecErrorsSafeString(href));
1039 0 : return(NULL);
1040 : }
1041 :
1042 0 : if((ns != NULL) && (ns->prefix != NULL)) {
1043 : xmlSecSize len;
1044 :
1045 0 : len = xmlStrlen(local) + xmlStrlen(ns->prefix) + 4;
1046 0 : qname = xmlMalloc(len);
1047 0 : if(qname == NULL) {
1048 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1049 : NULL,
1050 : "xmlMalloc",
1051 : XMLSEC_ERRORS_R_MALLOC_FAILED,
1052 : "node=%s",
1053 0 : xmlSecErrorsSafeString(node->name));
1054 0 : return(NULL);
1055 : }
1056 0 : xmlSecStrPrintf(qname, len, BAD_CAST "%s:%s", ns->prefix, local);
1057 : } else {
1058 0 : qname = xmlStrdup(local);
1059 0 : if(qname == NULL) {
1060 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1061 : NULL,
1062 : "xmlStrdup",
1063 : XMLSEC_ERRORS_R_MALLOC_FAILED,
1064 : "node=%s",
1065 0 : xmlSecErrorsSafeString(node->name));
1066 0 : return(NULL);
1067 : }
1068 : }
1069 :
1070 :
1071 0 : return(qname);
1072 : }
1073 :
1074 :
1075 : /*************************************************************************
1076 : *
1077 : * QName <-> Integer mapping
1078 : *
1079 : ************************************************************************/
1080 : /**
1081 : * xmlSecQName2IntegerGetInfo:
1082 : * @info: the qname<->integer mapping information.
1083 : * @intValue: the integer value.
1084 : *
1085 : * Maps integer @intValue to a QName prefix.
1086 : *
1087 : * Returns: the QName info that is mapped to @intValue or NULL if such value
1088 : * is not found.
1089 : */
1090 : xmlSecQName2IntegerInfoConstPtr
1091 0 : xmlSecQName2IntegerGetInfo(xmlSecQName2IntegerInfoConstPtr info, int intValue) {
1092 : unsigned int ii;
1093 :
1094 0 : xmlSecAssert2(info != NULL, NULL);
1095 :
1096 0 : for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1097 0 : if(info[ii].intValue == intValue) {
1098 0 : return(&info[ii]);
1099 : }
1100 : }
1101 :
1102 0 : return(NULL);
1103 : }
1104 :
1105 : /**
1106 : * xmlSecQName2IntegerGetInteger:
1107 : * @info: the qname<->integer mapping information.
1108 : * @qnameHref: the qname href value.
1109 : * @qnameLocalPart: the qname local part value.
1110 : * @intValue: the pointer to result integer value.
1111 : *
1112 : * Maps qname qname to an integer and returns it in @intValue.
1113 : *
1114 : * Returns: 0 on success or a negative value if an error occurs,
1115 : */
1116 : int
1117 0 : xmlSecQName2IntegerGetInteger(xmlSecQName2IntegerInfoConstPtr info,
1118 : const xmlChar* qnameHref, const xmlChar* qnameLocalPart,
1119 : int* intValue) {
1120 : unsigned int ii;
1121 :
1122 0 : xmlSecAssert2(info != NULL, -1);
1123 0 : xmlSecAssert2(qnameLocalPart != NULL, -1);
1124 0 : xmlSecAssert2(intValue != NULL, -1);
1125 :
1126 0 : for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1127 0 : if(xmlStrEqual(info[ii].qnameLocalPart, qnameLocalPart) &&
1128 0 : xmlStrEqual(info[ii].qnameHref, qnameHref)) {
1129 0 : (*intValue) = info[ii].intValue;
1130 0 : return(0);
1131 : }
1132 : }
1133 :
1134 0 : return(-1);
1135 : }
1136 :
1137 : /**
1138 : * xmlSecQName2IntegerGetIntegerFromString:
1139 : * @info: the qname<->integer mapping information.
1140 : * @node: the pointer to node.
1141 : * @qname: the qname string.
1142 : * @intValue: the pointer to result integer value.
1143 : *
1144 : * Converts @qname into integer in context of @node.
1145 : *
1146 : * Returns: 0 on success or a negative value if an error occurs,
1147 : */
1148 : int
1149 0 : xmlSecQName2IntegerGetIntegerFromString(xmlSecQName2IntegerInfoConstPtr info,
1150 : xmlNodePtr node, const xmlChar* qname,
1151 : int* intValue) {
1152 0 : const xmlChar* qnameLocalPart = NULL;
1153 0 : xmlChar* qnamePrefix = NULL;
1154 : const xmlChar* qnameHref;
1155 : xmlNsPtr ns;
1156 : int ret;
1157 :
1158 0 : xmlSecAssert2(info != NULL, -1);
1159 0 : xmlSecAssert2(node != NULL, -1);
1160 0 : xmlSecAssert2(qname != NULL, -1);
1161 0 : xmlSecAssert2(intValue != NULL, -1);
1162 :
1163 0 : qnameLocalPart = xmlStrchr(qname, ':');
1164 0 : if(qnameLocalPart != NULL) {
1165 0 : qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname);
1166 0 : if(qnamePrefix == NULL) {
1167 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1168 : NULL,
1169 : "xmlStrndup",
1170 : XMLSEC_ERRORS_R_MALLOC_FAILED,
1171 : "node=%s,value=%s",
1172 0 : xmlSecErrorsSafeString(node->name),
1173 : xmlSecErrorsSafeString(qname));
1174 0 : return(-1);
1175 : }
1176 0 : qnameLocalPart++;
1177 : } else {
1178 0 : qnamePrefix = NULL;
1179 0 : qnameLocalPart = qname;
1180 : }
1181 :
1182 : /* search namespace href */
1183 0 : ns = xmlSearchNs(node->doc, node, qnamePrefix);
1184 0 : if((ns == NULL) && (qnamePrefix != NULL)) {
1185 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1186 : NULL,
1187 : "xmlSearchNs",
1188 : XMLSEC_ERRORS_R_XML_FAILED,
1189 : "node=%s,qnamePrefix=%s",
1190 0 : xmlSecErrorsSafeString(node->name),
1191 : xmlSecErrorsSafeString(qnamePrefix));
1192 0 : if(qnamePrefix != NULL) {
1193 0 : xmlFree(qnamePrefix);
1194 : }
1195 0 : return(-1);
1196 : }
1197 0 : qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
1198 :
1199 : /* and finally search for integer */
1200 0 : ret = xmlSecQName2IntegerGetInteger(info, qnameHref, qnameLocalPart, intValue);
1201 0 : if(ret < 0) {
1202 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1203 : NULL,
1204 : "xmlSecQName2IntegerGetInteger",
1205 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1206 : "node=%s,qnameLocalPart=%s,qnameHref=%s",
1207 0 : xmlSecErrorsSafeString(node->name),
1208 : xmlSecErrorsSafeString(qnameLocalPart),
1209 : xmlSecErrorsSafeString(qnameHref));
1210 0 : if(qnamePrefix != NULL) {
1211 0 : xmlFree(qnamePrefix);
1212 : }
1213 0 : return(-1);
1214 : }
1215 :
1216 0 : if(qnamePrefix != NULL) {
1217 0 : xmlFree(qnamePrefix);
1218 : }
1219 0 : return(0);
1220 : }
1221 :
1222 :
1223 : /**
1224 : * xmlSecQName2IntegerGetStringFromInteger:
1225 : * @info: the qname<->integer mapping information.
1226 : * @node: the pointer to node.
1227 : * @intValue: the integer value.
1228 : *
1229 : * Creates qname string for @intValue in context of given @node. Caller
1230 : * is responsible for freeing returned string with @xmlFree.
1231 : *
1232 : * Returns: pointer to newly allocated string on success or NULL if an error occurs,
1233 : */
1234 : xmlChar*
1235 0 : xmlSecQName2IntegerGetStringFromInteger(xmlSecQName2IntegerInfoConstPtr info,
1236 : xmlNodePtr node, int intValue) {
1237 : xmlSecQName2IntegerInfoConstPtr qnameInfo;
1238 :
1239 0 : xmlSecAssert2(info != NULL, NULL);
1240 0 : xmlSecAssert2(node != NULL, NULL);
1241 :
1242 0 : qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1243 0 : if(qnameInfo == NULL) {
1244 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1245 : NULL,
1246 : "xmlSecQName2IntegerGetInfo",
1247 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1248 : "node=%s,intValue=%d",
1249 0 : xmlSecErrorsSafeString(node->name),
1250 : intValue);
1251 0 : return(NULL);
1252 : }
1253 :
1254 0 : return (xmlSecGetQName(node, qnameInfo->qnameHref, qnameInfo->qnameLocalPart));
1255 : }
1256 :
1257 : /**
1258 : * xmlSecQName2IntegerNodeRead:
1259 : * @info: the qname<->integer mapping information.
1260 : * @node: the pointer to node.
1261 : * @intValue: the pointer to result integer value.
1262 : *
1263 : * Reads the content of @node and converts it to an integer using mapping
1264 : * from @info.
1265 : *
1266 : * Returns: 0 on success or a negative value if an error occurs,
1267 : */
1268 : int
1269 0 : xmlSecQName2IntegerNodeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node, int* intValue) {
1270 0 : xmlChar* content = NULL;
1271 : int ret;
1272 :
1273 0 : xmlSecAssert2(info != NULL, -1);
1274 0 : xmlSecAssert2(node != NULL, -1);
1275 0 : xmlSecAssert2(intValue != NULL, -1);
1276 :
1277 0 : content = xmlNodeGetContent(node);
1278 0 : if(content == NULL) {
1279 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1280 : NULL,
1281 : "xmlNodeGetContent",
1282 : XMLSEC_ERRORS_R_XML_FAILED,
1283 : "node=%s",
1284 0 : xmlSecErrorsSafeString(node->name));
1285 0 : return(-1);
1286 : }
1287 : /* todo: trim content? */
1288 :
1289 0 : ret = xmlSecQName2IntegerGetIntegerFromString(info, node, content, intValue);
1290 0 : if(ret < 0) {
1291 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1292 : NULL,
1293 : "xmlSecQName2IntegerGetIntegerFromString",
1294 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1295 : "node=%s,value=%s",
1296 0 : xmlSecErrorsSafeString(node->name),
1297 : xmlSecErrorsSafeString(content));
1298 0 : xmlFree(content);
1299 0 : return(-1);
1300 : }
1301 :
1302 0 : xmlFree(content);
1303 0 : return(0);
1304 : }
1305 :
1306 : /**
1307 : * xmlSecQName2IntegerNodeWrite:
1308 : * @info: the qname<->integer mapping information.
1309 : * @node: the parent node.
1310 : * @nodeName: the child node name.
1311 : * @nodeNs: the child node namespace.
1312 : * @intValue: the integer value.
1313 : *
1314 : * Creates new child node in @node and sets its value to @intValue.
1315 : *
1316 : * Returns: 0 on success or a negative value if an error occurs,
1317 : */
1318 : int
1319 0 : xmlSecQName2IntegerNodeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1320 : const xmlChar* nodeName, const xmlChar* nodeNs, int intValue) {
1321 : xmlNodePtr cur;
1322 0 : xmlChar* qname = NULL;
1323 :
1324 0 : xmlSecAssert2(info != NULL, -1);
1325 0 : xmlSecAssert2(node != NULL, -1);
1326 0 : xmlSecAssert2(nodeName != NULL, -1);
1327 :
1328 : /* find and build qname */
1329 0 : qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue);
1330 0 : if(qname == NULL) {
1331 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1332 : NULL,
1333 : "xmlSecQName2IntegerGetStringFromInteger",
1334 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1335 : "node=%s,intValue=%d",
1336 0 : xmlSecErrorsSafeString(node->name),
1337 : intValue);
1338 0 : return(-1);
1339 : }
1340 :
1341 0 : cur = xmlSecAddChild(node, nodeName, nodeNs);
1342 0 : if(cur == NULL) {
1343 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1344 : NULL,
1345 : "xmlSecAddChild",
1346 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1347 : "node=%s,intValue=%d",
1348 : xmlSecErrorsSafeString(nodeName),
1349 : intValue);
1350 0 : xmlFree(qname);
1351 0 : return(-1);
1352 : }
1353 :
1354 0 : xmlNodeSetContent(cur, qname);
1355 0 : xmlFree(qname);
1356 0 : return(0);
1357 : }
1358 :
1359 : /**
1360 : * xmlSecQName2IntegerAttributeRead:
1361 : * @info: the qname<->integer mapping information.
1362 : * @node: the element node.
1363 : * @attrName: the attribute name.
1364 : * @intValue: the pointer to result integer value.
1365 : *
1366 : * Gets the value of @attrName atrtibute from @node and converts it to integer
1367 : * according to @info.
1368 : *
1369 : * Returns: 0 on success or a negative value if an error occurs,
1370 : */
1371 : int
1372 0 : xmlSecQName2IntegerAttributeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1373 : const xmlChar* attrName, int* intValue) {
1374 : xmlChar* attrValue;
1375 : int ret;
1376 :
1377 0 : xmlSecAssert2(info != NULL, -1);
1378 0 : xmlSecAssert2(node != NULL, -1);
1379 0 : xmlSecAssert2(attrName != NULL, -1);
1380 0 : xmlSecAssert2(intValue != NULL, -1);
1381 :
1382 0 : attrValue = xmlGetProp(node, attrName);
1383 0 : if(attrValue == NULL) {
1384 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1385 : NULL,
1386 : "xmlGetProp",
1387 : XMLSEC_ERRORS_R_XML_FAILED,
1388 : "node=%s,attrValue=%s",
1389 0 : xmlSecErrorsSafeString(node->name),
1390 : xmlSecErrorsSafeString(attrName));
1391 0 : return(-1);
1392 : }
1393 : /* todo: trim value? */
1394 :
1395 0 : ret = xmlSecQName2IntegerGetIntegerFromString(info, node, attrValue, intValue);
1396 0 : if(ret < 0) {
1397 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1398 : NULL,
1399 : "xmlSecQName2IntegerGetIntegerFromString",
1400 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1401 : "node=%s,attrName=%s,attrValue=%s",
1402 0 : xmlSecErrorsSafeString(node->name),
1403 : xmlSecErrorsSafeString(attrName),
1404 : xmlSecErrorsSafeString(attrValue));
1405 0 : xmlFree(attrValue);
1406 0 : return(-1);
1407 : }
1408 :
1409 0 : xmlFree(attrValue);
1410 0 : return(0);
1411 : }
1412 :
1413 : /**
1414 : * xmlSecQName2IntegerAttributeWrite:
1415 : * @info: the qname<->integer mapping information.
1416 : * @node: the parent node.
1417 : * @attrName: the name of attribute.
1418 : * @intValue: the integer value.
1419 : *
1420 : * Converts @intValue to a qname and sets it to the value of
1421 : * attribute @attrName in @node.
1422 : *
1423 : * Returns: 0 on success or a negative value if an error occurs,
1424 : */
1425 : int
1426 0 : xmlSecQName2IntegerAttributeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1427 : const xmlChar* attrName, int intValue) {
1428 : xmlChar* qname;
1429 : xmlAttrPtr attr;
1430 :
1431 0 : xmlSecAssert2(info != NULL, -1);
1432 0 : xmlSecAssert2(node != NULL, -1);
1433 0 : xmlSecAssert2(attrName != NULL, -1);
1434 :
1435 : /* find and build qname */
1436 0 : qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue);
1437 0 : if(qname == NULL) {
1438 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1439 : NULL,
1440 : "xmlSecQName2IntegerGetStringFromInteger",
1441 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1442 : "node=%s,attrName=%s,intValue=%d",
1443 0 : xmlSecErrorsSafeString(node->name),
1444 : xmlSecErrorsSafeString(attrName),
1445 : intValue);
1446 0 : return(-1);
1447 : }
1448 :
1449 0 : attr = xmlSetProp(node, attrName, qname);
1450 0 : if(attr == NULL) {
1451 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1452 : NULL,
1453 : "xmlSecAddChildNode",
1454 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1455 : "node=%s,attrName=%s,intValue=%d",
1456 0 : xmlSecErrorsSafeString(node->name),
1457 : xmlSecErrorsSafeString(attrName),
1458 : intValue);
1459 0 : xmlFree(qname);
1460 0 : return(-1);
1461 : }
1462 :
1463 0 : xmlFree(qname);
1464 0 : return(0);
1465 : }
1466 :
1467 : /**
1468 : * xmlSecQName2IntegerDebugDump:
1469 : * @info: the qname<->integer mapping information.
1470 : * @intValue: the integer value.
1471 : * @name: the value name to print.
1472 : * @output: the pointer to output FILE.
1473 : *
1474 : * Prints @intValue into @output.
1475 : */
1476 : void
1477 0 : xmlSecQName2IntegerDebugDump(xmlSecQName2IntegerInfoConstPtr info, int intValue,
1478 : const xmlChar* name, FILE* output) {
1479 : xmlSecQName2IntegerInfoConstPtr qnameInfo;
1480 :
1481 0 : xmlSecAssert(info != NULL);
1482 0 : xmlSecAssert(name != NULL);
1483 0 : xmlSecAssert(output != NULL);
1484 :
1485 0 : qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1486 0 : if(qnameInfo != NULL) {
1487 0 : fprintf(output, "== %s: %d (name=\"%s\", href=\"%s\")\n", name, intValue,
1488 0 : (qnameInfo->qnameLocalPart) ? qnameInfo->qnameLocalPart : BAD_CAST NULL,
1489 0 : (qnameInfo->qnameHref) ? qnameInfo->qnameHref : BAD_CAST NULL);
1490 : }
1491 : }
1492 :
1493 : /**
1494 : * xmlSecQName2IntegerDebugXmlDump:
1495 : * @info: the qname<->integer mapping information.
1496 : * @intValue: the integer value.
1497 : * @name: the value name to print.
1498 : * @output: the pointer to output FILE.
1499 : *
1500 : * Prints @intValue into @output in XML format.
1501 : */
1502 : void
1503 0 : xmlSecQName2IntegerDebugXmlDump(xmlSecQName2IntegerInfoConstPtr info, int intValue,
1504 : const xmlChar* name, FILE* output) {
1505 : xmlSecQName2IntegerInfoConstPtr qnameInfo;
1506 :
1507 0 : xmlSecAssert(info != NULL);
1508 0 : xmlSecAssert(name != NULL);
1509 0 : xmlSecAssert(output != NULL);
1510 :
1511 0 : qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1512 0 : if(qnameInfo != NULL) {
1513 0 : fprintf(output, "<%s value=\"%d\" href=\"%s\">%s<%s>\n", name, intValue,
1514 0 : (qnameInfo->qnameHref) ? qnameInfo->qnameHref : BAD_CAST NULL,
1515 0 : (qnameInfo->qnameLocalPart) ? qnameInfo->qnameLocalPart : BAD_CAST NULL,
1516 : name);
1517 : }
1518 : }
1519 :
1520 :
1521 : /*************************************************************************
1522 : *
1523 : * QName <-> Bits mask mapping
1524 : *
1525 : ************************************************************************/
1526 : /**
1527 : * xmlSecQName2BitMaskGetInfo:
1528 : * @info: the qname<->bit mask mapping information.
1529 : * @mask: the bit mask.
1530 : *
1531 : * Converts @mask to qname.
1532 : *
1533 : * Returns: pointer to the qname info for @mask or NULL if mask is unknown.
1534 : */
1535 : xmlSecQName2BitMaskInfoConstPtr
1536 0 : xmlSecQName2BitMaskGetInfo(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask) {
1537 : unsigned int ii;
1538 :
1539 0 : xmlSecAssert2(info != NULL, NULL);
1540 :
1541 0 : for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1542 0 : xmlSecAssert2(info[ii].mask != 0, NULL);
1543 0 : if(info[ii].mask == mask) {
1544 0 : return(&info[ii]);
1545 : }
1546 : }
1547 :
1548 0 : return(NULL);
1549 : }
1550 :
1551 : /**
1552 : * xmlSecQName2BitMaskGetBitMask:
1553 : * @info: the qname<->bit mask mapping information.
1554 : * @qnameHref: the qname Href value.
1555 : * @qnameLocalPart: the qname LocalPart value.
1556 : * @mask: the pointer to result mask.
1557 : *
1558 : * Converts @qnameLocalPart to @mask.
1559 : *
1560 : * Returns: 0 on success or a negative value if an error occurs,
1561 : */
1562 : int
1563 0 : xmlSecQName2BitMaskGetBitMask(xmlSecQName2BitMaskInfoConstPtr info,
1564 : const xmlChar* qnameHref, const xmlChar* qnameLocalPart,
1565 : xmlSecBitMask* mask) {
1566 : unsigned int ii;
1567 :
1568 0 : xmlSecAssert2(info != NULL, -1);
1569 0 : xmlSecAssert2(qnameLocalPart != NULL, -1);
1570 0 : xmlSecAssert2(mask != NULL, -1);
1571 :
1572 0 : for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1573 0 : xmlSecAssert2(info[ii].mask != 0, -1);
1574 0 : if(xmlStrEqual(info[ii].qnameLocalPart, qnameLocalPart) &&
1575 0 : xmlStrEqual(info[ii].qnameHref, qnameHref)) {
1576 :
1577 0 : (*mask) = info[ii].mask;
1578 0 : return(0);
1579 : }
1580 : }
1581 :
1582 0 : return(-1);
1583 : }
1584 :
1585 : /**
1586 : * xmlSecQName2BitMaskGetBitMaskFromString:
1587 : * @info: the qname<->integer mapping information.
1588 : * @node: the pointer to node.
1589 : * @qname: the qname string.
1590 : * @mask: the pointer to result msk value.
1591 : *
1592 : * Converts @qname into integer in context of @node.
1593 : *
1594 : * Returns: 0 on success or a negative value if an error occurs,
1595 : */
1596 : int
1597 0 : xmlSecQName2BitMaskGetBitMaskFromString(xmlSecQName2BitMaskInfoConstPtr info,
1598 : xmlNodePtr node, const xmlChar* qname,
1599 : xmlSecBitMask* mask) {
1600 0 : const xmlChar* qnameLocalPart = NULL;
1601 0 : xmlChar* qnamePrefix = NULL;
1602 : const xmlChar* qnameHref;
1603 : xmlNsPtr ns;
1604 : int ret;
1605 :
1606 0 : xmlSecAssert2(info != NULL, -1);
1607 0 : xmlSecAssert2(node != NULL, -1);
1608 0 : xmlSecAssert2(qname != NULL, -1);
1609 0 : xmlSecAssert2(mask != NULL, -1);
1610 :
1611 0 : qnameLocalPart = xmlStrchr(qname, ':');
1612 0 : if(qnameLocalPart != NULL) {
1613 0 : qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname);
1614 0 : if(qnamePrefix == NULL) {
1615 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1616 : NULL,
1617 : "xmlStrndup",
1618 : XMLSEC_ERRORS_R_MALLOC_FAILED,
1619 : "node=%s,value=%s",
1620 0 : xmlSecErrorsSafeString(node->name),
1621 : xmlSecErrorsSafeString(qname));
1622 0 : return(-1);
1623 : }
1624 0 : qnameLocalPart++;
1625 : } else {
1626 0 : qnamePrefix = NULL;
1627 0 : qnameLocalPart = qname;
1628 : }
1629 :
1630 : /* search namespace href */
1631 0 : ns = xmlSearchNs(node->doc, node, qnamePrefix);
1632 0 : if((ns == NULL) && (qnamePrefix != NULL)) {
1633 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1634 : NULL,
1635 : "xmlSearchNs",
1636 : XMLSEC_ERRORS_R_XML_FAILED,
1637 : "node=%s,qnamePrefix=%s",
1638 0 : xmlSecErrorsSafeString(node->name),
1639 : xmlSecErrorsSafeString(qnamePrefix));
1640 0 : if(qnamePrefix != NULL) {
1641 0 : xmlFree(qnamePrefix);
1642 : }
1643 0 : return(-1);
1644 : }
1645 0 : qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
1646 :
1647 : /* and finally search for integer */
1648 0 : ret = xmlSecQName2BitMaskGetBitMask(info, qnameHref, qnameLocalPart, mask);
1649 0 : if(ret < 0) {
1650 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1651 : NULL,
1652 : "xmlSecQName2BitMaskGetBitMask",
1653 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1654 : "node=%s,qnameLocalPart=%s,qnameHref=%s",
1655 0 : xmlSecErrorsSafeString(node->name),
1656 : xmlSecErrorsSafeString(qnameLocalPart),
1657 : xmlSecErrorsSafeString(qnameHref));
1658 0 : if(qnamePrefix != NULL) {
1659 0 : xmlFree(qnamePrefix);
1660 : }
1661 0 : return(-1);
1662 : }
1663 :
1664 0 : if(qnamePrefix != NULL) {
1665 0 : xmlFree(qnamePrefix);
1666 : }
1667 0 : return(0);
1668 : }
1669 :
1670 :
1671 : /**
1672 : * xmlSecQName2BitMaskGetStringFromBitMask:
1673 : * @info: the qname<->integer mapping information.
1674 : * @node: the pointer to node.
1675 : * @mask: the mask.
1676 : *
1677 : * Creates qname string for @mask in context of given @node. Caller
1678 : * is responsible for freeing returned string with @xmlFree.
1679 : *
1680 : * Returns: pointer to newly allocated string on success or NULL if an error occurs,
1681 : */
1682 : xmlChar*
1683 0 : xmlSecQName2BitMaskGetStringFromBitMask(xmlSecQName2BitMaskInfoConstPtr info,
1684 : xmlNodePtr node, xmlSecBitMask mask) {
1685 : xmlSecQName2BitMaskInfoConstPtr qnameInfo;
1686 :
1687 0 : xmlSecAssert2(info != NULL, NULL);
1688 0 : xmlSecAssert2(node != NULL, NULL);
1689 :
1690 0 : qnameInfo = xmlSecQName2BitMaskGetInfo(info, mask);
1691 0 : if(qnameInfo == NULL) {
1692 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1693 : NULL,
1694 : "xmlSecQName2BitMaskGetInfo",
1695 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1696 : "node=%s,mask=%d",
1697 0 : xmlSecErrorsSafeString(node->name),
1698 : mask);
1699 0 : return(NULL);
1700 : }
1701 :
1702 0 : return(xmlSecGetQName(node, qnameInfo->qnameHref, qnameInfo->qnameLocalPart));
1703 : }
1704 :
1705 : /**
1706 : * xmlSecQName2BitMaskNodesRead:
1707 : * @info: the qname<->bit mask mapping information.
1708 : * @node: the start.
1709 : * @nodeName: the mask nodes name.
1710 : * @nodeNs: the mask nodes namespace.
1711 : * @stopOnUnknown: if this flag is set then function exits if unknown
1712 : * value was found.
1713 : * @mask: the pointer to result mask.
1714 : *
1715 : * Reads <@nodeNs:@nodeName> elements and puts the result bit mask
1716 : * into @mask. When function exits, @node points to the first element node
1717 : * after all the <@nodeNs:@nodeName> elements.
1718 : *
1719 : * Returns: 0 on success or a negative value if an error occurs,
1720 : */
1721 : int
1722 0 : xmlSecQName2BitMaskNodesRead(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr* node,
1723 : const xmlChar* nodeName, const xmlChar* nodeNs,
1724 : int stopOnUnknown, xmlSecBitMask* mask) {
1725 : xmlNodePtr cur;
1726 : xmlChar* content;
1727 : xmlSecBitMask tmp;
1728 : int ret;
1729 :
1730 0 : xmlSecAssert2(info != NULL, -1);
1731 0 : xmlSecAssert2(node != NULL, -1);
1732 0 : xmlSecAssert2(mask != NULL, -1);
1733 :
1734 0 : (*mask) = 0;
1735 0 : cur = (*node);
1736 0 : while((cur != NULL) && (xmlSecCheckNodeName(cur, nodeName, nodeNs))) {
1737 0 : content = xmlNodeGetContent(cur);
1738 0 : if(content == NULL) {
1739 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1740 : NULL,
1741 : "xmlNodeGetContent",
1742 : XMLSEC_ERRORS_R_XML_FAILED,
1743 : "node=%s",
1744 0 : xmlSecErrorsSafeString(cur->name));
1745 0 : return(-1);
1746 : }
1747 :
1748 0 : ret = xmlSecQName2BitMaskGetBitMaskFromString(info, cur, content, &tmp);
1749 0 : if(ret < 0) {
1750 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1751 : NULL,
1752 : "xmlSecQName2BitMaskGetBitMaskFromString",
1753 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1754 : "value=%s",
1755 : xmlSecErrorsSafeString(content));
1756 0 : xmlFree(content);
1757 0 : return(-1);
1758 : }
1759 0 : xmlFree(content);
1760 :
1761 0 : if((stopOnUnknown != 0) && (tmp == 0)) {
1762 : /* todo: better error */
1763 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1764 : NULL,
1765 : "xmlSecQName2BitMaskGetBitMaskFromString",
1766 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1767 : "value=%s",
1768 : xmlSecErrorsSafeString(content));
1769 0 : return(-1);
1770 : }
1771 :
1772 0 : (*mask) |= tmp;
1773 0 : cur = xmlSecGetNextElementNode(cur->next);
1774 : }
1775 :
1776 0 : (*node) = cur;
1777 0 : return(0);
1778 : }
1779 :
1780 : /**
1781 : * xmlSecQName2BitMaskNodesWrite:
1782 : * @info: the qname<->bit mask mapping information.
1783 : * @node: the parent element for mask nodes.
1784 : * @nodeName: the mask nodes name.
1785 : * @nodeNs: the mask nodes namespace.
1786 : * @mask: the bit mask.
1787 : *
1788 : * Writes <@nodeNs:@nodeName> elemnts with values from @mask to @node.
1789 : *
1790 : * Returns: 0 on success or a negative value if an error occurs,
1791 : */
1792 : int
1793 0 : xmlSecQName2BitMaskNodesWrite(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr node,
1794 : const xmlChar* nodeName, const xmlChar* nodeNs,
1795 : xmlSecBitMask mask) {
1796 : unsigned int ii;
1797 :
1798 0 : xmlSecAssert2(info != NULL, -1);
1799 0 : xmlSecAssert2(node != NULL, -1);
1800 0 : xmlSecAssert2(nodeName != NULL, -1);
1801 :
1802 0 : for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1803 0 : xmlSecAssert2(info[ii].mask != 0, -1);
1804 :
1805 0 : if((mask & info[ii].mask) != 0) {
1806 : xmlNodePtr cur;
1807 : xmlChar* qname;
1808 :
1809 0 : qname = xmlSecGetQName(node, info[ii].qnameHref, info[ii].qnameLocalPart);
1810 0 : if(qname == NULL) {
1811 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1812 : NULL,
1813 : "xmlSecGetQName",
1814 : XMLSEC_ERRORS_R_XML_FAILED,
1815 : "node=%s",
1816 : xmlSecErrorsSafeString(nodeName));
1817 0 : return(-1);
1818 : }
1819 :
1820 0 : cur = xmlSecAddChild(node, nodeName, nodeNs);
1821 0 : if(cur == NULL) {
1822 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1823 : NULL,
1824 : "xmlSecAddChild",
1825 : XMLSEC_ERRORS_R_XML_FAILED,
1826 : "node=%s",
1827 : xmlSecErrorsSafeString(nodeName));
1828 0 : xmlFree(qname);
1829 0 : return(-1);
1830 : }
1831 :
1832 0 : xmlNodeSetContent(cur, qname);
1833 0 : xmlFree(qname);
1834 : }
1835 : }
1836 0 : return(0);
1837 : }
1838 :
1839 : /**
1840 : * xmlSecQName2BitMaskDebugDump:
1841 : * @info: the qname<->bit mask mapping information.
1842 : * @mask: the bit mask.
1843 : * @name: the value name to print.
1844 : * @output: the pointer to output FILE.
1845 : *
1846 : * Prints debug information about @mask to @output.
1847 : */
1848 : void
1849 0 : xmlSecQName2BitMaskDebugDump(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask,
1850 : const xmlChar* name, FILE* output) {
1851 : unsigned int ii;
1852 :
1853 0 : xmlSecAssert(info != NULL);
1854 0 : xmlSecAssert(name != NULL);
1855 0 : xmlSecAssert(output != NULL);
1856 :
1857 0 : if(mask == 0) {
1858 0 : return;
1859 : }
1860 :
1861 0 : fprintf(output, "== %s (0x%08x): ", name, mask);
1862 0 : for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1863 0 : xmlSecAssert(info[ii].mask != 0);
1864 :
1865 0 : if((mask & info[ii].mask) != 0) {
1866 0 : fprintf(output, "name=\"%s\" (href=\"%s\"),", info[ii].qnameLocalPart, info[ii].qnameHref);
1867 : }
1868 : }
1869 0 : fprintf(output, "\n");
1870 : }
1871 :
1872 : /**
1873 : * xmlSecQName2BitMaskDebugXmlDump:
1874 : * @info: the qname<->bit mask mapping information.
1875 : * @mask: the bit mask.
1876 : * @name: the value name to print.
1877 : * @output: the pointer to output FILE.
1878 : *
1879 : * Prints debug information about @mask to @output in XML format.
1880 : */
1881 : void
1882 0 : xmlSecQName2BitMaskDebugXmlDump(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask,
1883 : const xmlChar* name, FILE* output) {
1884 : unsigned int ii;
1885 :
1886 0 : xmlSecAssert(info != NULL);
1887 0 : xmlSecAssert(name != NULL);
1888 0 : xmlSecAssert(output != NULL);
1889 :
1890 0 : if(mask == 0) {
1891 0 : return;
1892 : }
1893 :
1894 0 : fprintf(output, "<%sList>\n", name);
1895 0 : for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1896 0 : xmlSecAssert(info[ii].mask != 0);
1897 :
1898 0 : if((mask & info[ii].mask) != 0) {
1899 0 : fprintf(output, "<%s href=\"%s\">%s</%s>\n", name,
1900 0 : info[ii].qnameHref, info[ii].qnameLocalPart, name);
1901 : }
1902 : }
1903 0 : fprintf(output, "</%sList>\n", name);
1904 : }
1905 :
1906 :
1907 :
1908 :
|