ReactOS 0.4.15-dev-7942-gd23573b
c14n.c
Go to the documentation of this file.
1/*
2 * "Canonical XML" implementation
3 * http://www.w3.org/TR/xml-c14n
4 *
5 * "Exclusive XML Canonicalization" implementation
6 * http://www.w3.org/TR/xml-exc-c14n
7 *
8 * See Copyright for the status of this software.
9 *
10 * Author: Aleksey Sanin <aleksey@aleksey.com>
11 */
12#define IN_LIBXML
13#include "libxml.h"
14#ifdef LIBXML_C14N_ENABLED
15#ifdef LIBXML_OUTPUT_ENABLED
16
17#include <stdlib.h>
18#include <string.h>
19
20#include <libxml/tree.h>
21#include <libxml/parser.h>
22#include <libxml/uri.h>
23#include <libxml/xmlerror.h>
24#include <libxml/globals.h>
26#include <libxml/c14n.h>
27
28#include "buf.h"
29
30/************************************************************************
31 * *
32 * Some declaration better left private ATM *
33 * *
34 ************************************************************************/
35
36typedef enum {
37 XMLC14N_BEFORE_DOCUMENT_ELEMENT = 0,
38 XMLC14N_INSIDE_DOCUMENT_ELEMENT = 1,
39 XMLC14N_AFTER_DOCUMENT_ELEMENT = 2
40} xmlC14NPosition;
41
42typedef struct _xmlC14NVisibleNsStack {
43 int nsCurEnd; /* number of nodes in the set */
44 int nsPrevStart; /* the beginning of the stack for previous visible node */
45 int nsPrevEnd; /* the end of the stack for previous visible node */
46 int nsMax; /* size of the array as allocated */
47 xmlNsPtr *nsTab; /* array of ns in no particular order */
48 xmlNodePtr *nodeTab; /* array of nodes in no particular order */
49} xmlC14NVisibleNsStack, *xmlC14NVisibleNsStackPtr;
50
51typedef struct _xmlC14NCtx {
52 /* input parameters */
53 xmlDocPtr doc;
54 xmlC14NIsVisibleCallback is_visible_callback;
55 void* user_data;
56 int with_comments;
58
59 /* position in the XML document */
60 xmlC14NPosition pos;
61 int parent_is_doc;
62 xmlC14NVisibleNsStackPtr ns_rendered;
63
64 /* C14N mode */
65 xmlC14NMode mode;
66
67 /* exclusive canonicalization */
68 xmlChar **inclusive_ns_prefixes;
69
70 /* error number */
71 int error;
72} xmlC14NCtx, *xmlC14NCtxPtr;
73
74static xmlC14NVisibleNsStackPtr xmlC14NVisibleNsStackCreate (void);
75static void xmlC14NVisibleNsStackDestroy (xmlC14NVisibleNsStackPtr cur);
76static void xmlC14NVisibleNsStackAdd (xmlC14NVisibleNsStackPtr cur,
79static void xmlC14NVisibleNsStackSave (xmlC14NVisibleNsStackPtr cur,
80 xmlC14NVisibleNsStackPtr state);
81static void xmlC14NVisibleNsStackRestore (xmlC14NVisibleNsStackPtr cur,
82 xmlC14NVisibleNsStackPtr state);
83static void xmlC14NVisibleNsStackShift (xmlC14NVisibleNsStackPtr cur);
84static int xmlC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur,
85 xmlNsPtr ns);
86static int xmlExcC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur,
88 xmlC14NCtxPtr ctx);
89
90static int xmlC14NIsNodeInNodeset (void *user_data,
93
94
95
96static int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur);
97static int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur);
98typedef enum {
99 XMLC14N_NORMALIZE_ATTR = 0,
100 XMLC14N_NORMALIZE_COMMENT = 1,
101 XMLC14N_NORMALIZE_PI = 2,
102 XMLC14N_NORMALIZE_TEXT = 3
103} xmlC14NNormalizationMode;
104
105static xmlChar *xmlC11NNormalizeString(const xmlChar * input,
106 xmlC14NNormalizationMode mode);
107
108#define xmlC11NNormalizeAttr( a ) \
109 xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_ATTR)
110#define xmlC11NNormalizeComment( a ) \
111 xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_COMMENT)
112#define xmlC11NNormalizePI( a ) \
113 xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_PI)
114#define xmlC11NNormalizeText( a ) \
115 xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_TEXT)
116
117#define xmlC14NIsVisible( ctx, node, parent ) \
118 (((ctx)->is_visible_callback != NULL) ? \
119 (ctx)->is_visible_callback((ctx)->user_data, \
120 (xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
121
122#define xmlC14NIsExclusive( ctx ) \
123 ( (ctx)->mode == XML_C14N_EXCLUSIVE_1_0 )
124
125/************************************************************************
126 * *
127 * Some factorized error routines *
128 * *
129 ************************************************************************/
130
137static void
138xmlC14NErrMemory(const char *extra)
139{
140 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
142 NULL, NULL, 0, 0,
143 "Memory allocation failed : %s\n", extra);
144}
145
152static void
153xmlC14NErrParam(const char *extra)
154{
155 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
157 NULL, NULL, 0, 0,
158 "Invalid parameter : %s\n", extra);
159}
160
167static void
168xmlC14NErrInternal(const char *extra)
169{
170 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
172 NULL, NULL, 0, 0,
173 "Internal error : %s\n", extra);
174}
175
182static void
183xmlC14NErrInvalidNode(const char *node_type, const char *extra)
184{
185 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
187 NULL, NULL, 0, 0,
188 "Node %s is invalid here : %s\n", node_type, extra);
189}
190
197static void
198xmlC14NErrUnknownNode(int node_type, const char *extra)
199{
200 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
202 NULL, NULL, 0, 0,
203 "Unknown node type %d found : %s\n", node_type, extra);
204}
205
212static void
213xmlC14NErrRelativeNamespace(const char *ns_uri)
214{
215 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
217 NULL, NULL, 0, 0,
218 "Relative namespace UR is invalid here : %s\n", ns_uri);
219}
220
221
222
233static void
234xmlC14NErr(xmlC14NCtxPtr ctxt, xmlNodePtr node, int error,
235 const char * msg)
236{
237 if (ctxt != NULL)
238 ctxt->error = error;
239 __xmlRaiseError(NULL, NULL, NULL,
240 ctxt, node, XML_FROM_C14N, error,
242 NULL, NULL, NULL, 0, 0, "%s", msg);
243}
244
245/************************************************************************
246 * *
247 * The implementation internals *
248 * *
249 ************************************************************************/
250#define XML_NAMESPACES_DEFAULT 16
251
252static int
253xmlC14NIsNodeInNodeset(void *user_data, xmlNodePtr node, xmlNodePtr parent) {
254 xmlNodeSetPtr nodes = (xmlNodeSetPtr) user_data;
255 if((nodes != NULL) && (node != NULL)) {
256 if(node->type != XML_NAMESPACE_DECL) {
257 return(xmlXPathNodeSetContains(nodes, node));
258 } else {
259 xmlNs ns;
260
261 memcpy(&ns, node, sizeof(ns));
262
263 /* this is a libxml hack! check xpath.c for details */
264 if((parent != NULL) && (parent->type == XML_ATTRIBUTE_NODE)) {
265 ns.next = (xmlNsPtr)parent->parent;
266 } else {
267 ns.next = (xmlNsPtr)parent;
268 }
269
270 /*
271 * If the input is an XPath node-set, then the node-set must explicitly
272 * contain every node to be rendered to the canonical form.
273 */
274 return(xmlXPathNodeSetContains(nodes, (xmlNodePtr)&ns));
275 }
276 }
277 return(1);
278}
279
280static xmlC14NVisibleNsStackPtr
281xmlC14NVisibleNsStackCreate(void) {
282 xmlC14NVisibleNsStackPtr ret;
283
284 ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
285 if (ret == NULL) {
286 xmlC14NErrMemory("creating namespaces stack");
287 return(NULL);
288 }
289 memset(ret, 0 , (size_t) sizeof(xmlC14NVisibleNsStack));
290 return(ret);
291}
292
293static void
294xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
295 if(cur == NULL) {
296 xmlC14NErrParam("destroying namespaces stack");
297 return;
298 }
299 if(cur->nsTab != NULL) {
300 memset(cur->nsTab, 0, cur->nsMax * sizeof(xmlNsPtr));
301 xmlFree(cur->nsTab);
302 }
303 if(cur->nodeTab != NULL) {
304 memset(cur->nodeTab, 0, cur->nsMax * sizeof(xmlNodePtr));
305 xmlFree(cur->nodeTab);
306 }
307 memset(cur, 0, sizeof(xmlC14NVisibleNsStack));
308 xmlFree(cur);
309
310}
311
312static void
313xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr node) {
314 if((cur == NULL) ||
315 ((cur->nsTab == NULL) && (cur->nodeTab != NULL)) ||
316 ((cur->nsTab != NULL) && (cur->nodeTab == NULL))) {
317 xmlC14NErrParam("adding namespace to stack");
318 return;
319 }
320
321 if ((cur->nsTab == NULL) && (cur->nodeTab == NULL)) {
322 cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
323 cur->nodeTab = (xmlNodePtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
324 if ((cur->nsTab == NULL) || (cur->nodeTab == NULL)) {
325 xmlC14NErrMemory("adding node to stack");
326 return;
327 }
328 memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
329 memset(cur->nodeTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
330 cur->nsMax = XML_NAMESPACES_DEFAULT;
331 } else if(cur->nsMax == cur->nsCurEnd) {
332 void *tmp;
333 int tmpSize;
334
335 tmpSize = 2 * cur->nsMax;
336 tmp = xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
337 if (tmp == NULL) {
338 xmlC14NErrMemory("adding node to stack");
339 return;
340 }
341 cur->nsTab = (xmlNsPtr*)tmp;
342
343 tmp = xmlRealloc(cur->nodeTab, tmpSize * sizeof(xmlNodePtr));
344 if (tmp == NULL) {
345 xmlC14NErrMemory("adding node to stack");
346 return;
347 }
348 cur->nodeTab = (xmlNodePtr*)tmp;
349
350 cur->nsMax = tmpSize;
351 }
352 cur->nsTab[cur->nsCurEnd] = ns;
353 cur->nodeTab[cur->nsCurEnd] = node;
354
355 ++cur->nsCurEnd;
356}
357
358static void
359xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
360 if((cur == NULL) || (state == NULL)) {
361 xmlC14NErrParam("saving namespaces stack");
362 return;
363 }
364
365 state->nsCurEnd = cur->nsCurEnd;
366 state->nsPrevStart = cur->nsPrevStart;
367 state->nsPrevEnd = cur->nsPrevEnd;
368}
369
370static void
371xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
372 if((cur == NULL) || (state == NULL)) {
373 xmlC14NErrParam("restoring namespaces stack");
374 return;
375 }
376 cur->nsCurEnd = state->nsCurEnd;
377 cur->nsPrevStart = state->nsPrevStart;
378 cur->nsPrevEnd = state->nsPrevEnd;
379}
380
381static void
382xmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
383 if(cur == NULL) {
384 xmlC14NErrParam("shifting namespaces stack");
385 return;
386 }
387 cur->nsPrevStart = cur->nsPrevEnd;
388 cur->nsPrevEnd = cur->nsCurEnd;
389}
390
391static int
392xmlC14NStrEqual(const xmlChar *str1, const xmlChar *str2) {
393 if (str1 == str2) return(1);
394 if (str1 == NULL) return((*str2) == '\0');
395 if (str2 == NULL) return((*str1) == '\0');
396 do {
397 if (*str1++ != *str2) return(0);
398 } while (*str2++);
399 return(1);
400}
401
411static int
412xmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns)
413{
414 int i;
415 const xmlChar *prefix;
416 const xmlChar *href;
417 int has_empty_ns;
418
419 if(cur == NULL) {
420 xmlC14NErrParam("searching namespaces stack (c14n)");
421 return (0);
422 }
423
424 /*
425 * if the default namespace xmlns="" is not defined yet then
426 * we do not want to print it out
427 */
428 prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
429 href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
430 has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
431
432 if (cur->nsTab != NULL) {
433 int start = (has_empty_ns) ? 0 : cur->nsPrevStart;
434 for (i = cur->nsCurEnd - 1; i >= start; --i) {
435 xmlNsPtr ns1 = cur->nsTab[i];
436
437 if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
438 return(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL));
439 }
440 }
441 }
442 return(has_empty_ns);
443}
444
445static int
446xmlExcC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NCtxPtr ctx) {
447 int i;
448 const xmlChar *prefix;
449 const xmlChar *href;
450 int has_empty_ns;
451
452 if(cur == NULL) {
453 xmlC14NErrParam("searching namespaces stack (exc c14n)");
454 return (0);
455 }
456
457 /*
458 * if the default namespace xmlns="" is not defined yet then
459 * we do not want to print it out
460 */
461 prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
462 href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
463 has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
464
465 if (cur->nsTab != NULL) {
466 int start = 0;
467 for (i = cur->nsCurEnd - 1; i >= start; --i) {
468 xmlNsPtr ns1 = cur->nsTab[i];
469
470 if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
471 if(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL)) {
472 return(xmlC14NIsVisible(ctx, ns1, cur->nodeTab[i]));
473 } else {
474 return(0);
475 }
476 }
477 }
478 }
479 return(has_empty_ns);
480}
481
482
483
484
495/* todo: make it a define? */
496static int
497xmlC14NIsXmlNs(xmlNsPtr ns)
498{
499 return ((ns != NULL) &&
500 (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
502}
503
504
514static int
515xmlC14NNsCompare(const void *data1, const void *data2)
516{
517 const xmlNsPtr ns1 = (const xmlNsPtr) data1;
518 const xmlNsPtr ns2 = (const xmlNsPtr) data2;
519 if (ns1 == ns2)
520 return (0);
521 if (ns1 == NULL)
522 return (-1);
523 if (ns2 == NULL)
524 return (1);
525
526 return (xmlStrcmp(ns1->prefix, ns2->prefix));
527}
528
529
539static int
540xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
541{
542
543 if ((ns == NULL) || (ctx == NULL)) {
544 xmlC14NErrParam("writing namespaces");
545 return 0;
546 }
547
548 if (ns->prefix != NULL) {
549 xmlOutputBufferWriteString(ctx->buf, " xmlns:");
550 xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
551 xmlOutputBufferWriteString(ctx->buf, "=");
552 } else {
553 xmlOutputBufferWriteString(ctx->buf, " xmlns=");
554 }
555 if(ns->href != NULL) {
556 xmlBufWriteQuotedString(ctx->buf->buffer, ns->href);
557 } else {
558 xmlOutputBufferWriteString(ctx->buf, "\"\"");
559 }
560 return (1);
561}
562
563static int
564xmlC14NPrintNamespacesWalker(const void *ns, void *ctx) {
565 return xmlC14NPrintNamespaces((const xmlNsPtr) ns, (xmlC14NCtxPtr) ctx);
566}
567
607static int
608xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
609{
611 xmlNsPtr ns, tmp;
613 int already_rendered;
614 int has_empty_ns = 0;
615
616 if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
617 xmlC14NErrParam("processing namespaces axis (c14n)");
618 return (-1);
619 }
620
621 /*
622 * Create a sorted list to store element namespaces
623 */
624 list = xmlListCreate(NULL, xmlC14NNsCompare);
625 if (list == NULL) {
626 xmlC14NErrInternal("creating namespaces list (c14n)");
627 return (-1);
628 }
629
630 /* check all namespaces */
631 for(n = cur; n != NULL; n = n->parent) {
632 for(ns = n->nsDef; ns != NULL; ns = ns->next) {
633 tmp = xmlSearchNs(cur->doc, cur, ns->prefix);
634
635 if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
636 already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
637 if(visible) {
638 xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
639 }
640 if(!already_rendered) {
642 }
643 if(xmlStrlen(ns->prefix) == 0) {
644 has_empty_ns = 1;
645 }
646 }
647 }
648 }
649
659 if(visible && !has_empty_ns) {
660 static xmlNs ns_default;
661
662 memset(&ns_default, 0, sizeof(ns_default));
663 if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
664 xmlC14NPrintNamespaces(&ns_default, ctx);
665 }
666 }
667
668
669 /*
670 * print out all elements from list
671 */
672 xmlListWalk(list, xmlC14NPrintNamespacesWalker, (void *) ctx);
673
674 /*
675 * Cleanup
676 */
678 return (0);
679}
680
681
712static int
713xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
714{
715 xmlNsPtr ns;
718 int already_rendered;
719 int has_empty_ns = 0;
720 int has_visibly_utilized_empty_ns = 0;
721 int has_empty_ns_in_inclusive_list = 0;
722
723 if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
724 xmlC14NErrParam("processing namespaces axis (exc c14n)");
725 return (-1);
726 }
727
728 if(!xmlC14NIsExclusive(ctx)) {
729 xmlC14NErrParam("processing namespaces axis (exc c14n)");
730 return (-1);
731
732 }
733
734 /*
735 * Create a sorted list to store element namespaces
736 */
737 list = xmlListCreate(NULL, xmlC14NNsCompare);
738 if (list == NULL) {
739 xmlC14NErrInternal("creating namespaces list (exc c14n)");
740 return (-1);
741 }
742
743 /*
744 * process inclusive namespaces:
745 * All namespace nodes appearing on inclusive ns list are
746 * handled as provided in Canonical XML
747 */
748 if(ctx->inclusive_ns_prefixes != NULL) {
749 xmlChar *prefix;
750 int i;
751
752 for (i = 0; ctx->inclusive_ns_prefixes[i] != NULL; ++i) {
753 prefix = ctx->inclusive_ns_prefixes[i];
754 /*
755 * Special values for namespace with empty prefix
756 */
757 if (xmlStrEqual(prefix, BAD_CAST "#default")
758 || xmlStrEqual(prefix, BAD_CAST "")) {
759 prefix = NULL;
760 has_empty_ns_in_inclusive_list = 1;
761 }
762
763 ns = xmlSearchNs(cur->doc, cur, prefix);
764 if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
765 already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
766 if(visible) {
767 xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
768 }
769 if(!already_rendered) {
771 }
772 if(xmlStrlen(ns->prefix) == 0) {
773 has_empty_ns = 1;
774 }
775 }
776 }
777 }
778
779 /* add node namespace */
780 if(cur->ns != NULL) {
781 ns = cur->ns;
782 } else {
783 ns = xmlSearchNs(cur->doc, cur, NULL);
784 has_visibly_utilized_empty_ns = 1;
785 }
786 if((ns != NULL) && !xmlC14NIsXmlNs(ns)) {
787 if(visible && xmlC14NIsVisible(ctx, ns, cur)) {
788 if(!xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, ns, ctx)) {
790 }
791 }
792 if(visible) {
793 xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
794 }
795 if(xmlStrlen(ns->prefix) == 0) {
796 has_empty_ns = 1;
797 }
798 }
799
800
801 /* add attributes */
802 for(attr = cur->properties; attr != NULL; attr = attr->next) {
803 /*
804 * we need to check that attribute is visible and has non
805 * default namespace (XML Namespaces: "default namespaces
806 * do not apply directly to attributes")
807 */
808 if((attr->ns != NULL) && !xmlC14NIsXmlNs(attr->ns) && xmlC14NIsVisible(ctx, attr, cur)) {
809 already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);
810 xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur);
811 if(!already_rendered && visible) {
812 xmlListInsert(list, attr->ns);
813 }
814 if(xmlStrlen(attr->ns->prefix) == 0) {
815 has_empty_ns = 1;
816 }
817 } else if((attr->ns != NULL) && (xmlStrlen(attr->ns->prefix) == 0) && (xmlStrlen(attr->ns->href) == 0)) {
818 has_visibly_utilized_empty_ns = 1;
819 }
820 }
821
822 /*
823 * Process xmlns=""
824 */
825 if(visible && has_visibly_utilized_empty_ns &&
826 !has_empty_ns && !has_empty_ns_in_inclusive_list) {
827 static xmlNs ns_default;
828
829 memset(&ns_default, 0, sizeof(ns_default));
830
831 already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default, ctx);
832 if(!already_rendered) {
833 xmlC14NPrintNamespaces(&ns_default, ctx);
834 }
835 } else if(visible && !has_empty_ns && has_empty_ns_in_inclusive_list) {
836 static xmlNs ns_default;
837
838 memset(&ns_default, 0, sizeof(ns_default));
839 if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
840 xmlC14NPrintNamespaces(&ns_default, ctx);
841 }
842 }
843
844
845
846 /*
847 * print out all elements from list
848 */
849 xmlListWalk(list, xmlC14NPrintNamespacesWalker, (void *) ctx);
850
851 /*
852 * Cleanup
853 */
855 return (0);
856}
857
858
869/* todo: make it a define? */
870static int
871xmlC14NIsXmlAttr(xmlAttrPtr attr)
872{
873 return ((attr->ns != NULL) &&
874 (xmlC14NIsXmlNs(attr->ns) != 0));
875}
876
877
887static int
888xmlC14NAttrsCompare(const void *data1, const void *data2)
889{
890 const xmlAttrPtr attr1 = (const xmlAttrPtr) data1;
891 const xmlAttrPtr attr2 = (const xmlAttrPtr) data2;
892 int ret = 0;
893
894 /*
895 * Simple cases
896 */
897 if (attr1 == attr2)
898 return (0);
899 if (attr1 == NULL)
900 return (-1);
901 if (attr2 == NULL)
902 return (1);
903 if (attr1->ns == attr2->ns) {
904 return (xmlStrcmp(attr1->name, attr2->name));
905 }
906
907 /*
908 * Attributes in the default namespace are first
909 * because the default namespace is not applied to
910 * unqualified attributes
911 */
912 if (attr1->ns == NULL)
913 return (-1);
914 if (attr2->ns == NULL)
915 return (1);
916 if (attr1->ns->prefix == NULL)
917 return (-1);
918 if (attr2->ns->prefix == NULL)
919 return (1);
920
921 ret = xmlStrcmp(attr1->ns->href, attr2->ns->href);
922 if (ret == 0) {
923 ret = xmlStrcmp(attr1->name, attr2->name);
924 }
925 return (ret);
926}
927
928
941static int
942xmlC14NPrintAttrs(const void *data, void *user)
943{
944 const xmlAttrPtr attr = (const xmlAttrPtr) data;
945 xmlC14NCtxPtr ctx = (xmlC14NCtxPtr) user;
946 xmlChar *value;
948
949 if ((attr == NULL) || (ctx == NULL)) {
950 xmlC14NErrParam("writing attributes");
951 return (0);
952 }
953
954 xmlOutputBufferWriteString(ctx->buf, " ");
955 if (attr->ns != NULL && xmlStrlen(attr->ns->prefix) > 0) {
956 xmlOutputBufferWriteString(ctx->buf,
957 (const char *) attr->ns->prefix);
958 xmlOutputBufferWriteString(ctx->buf, ":");
959 }
960 xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
961 xmlOutputBufferWriteString(ctx->buf, "=\"");
962
963 value = xmlNodeListGetString(ctx->doc, attr->children, 1);
964 /* todo: should we log an error if value==NULL ? */
965 if (value != NULL) {
966 buffer = xmlC11NNormalizeAttr(value);
967 xmlFree(value);
968 if (buffer != NULL) {
969 xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);
971 } else {
972 xmlC14NErrInternal("normalizing attributes axis");
973 return (0);
974 }
975 }
976 xmlOutputBufferWriteString(ctx->buf, "\"");
977 return (1);
978}
979
987static xmlAttrPtr
988xmlC14NFindHiddenParentAttr(xmlC14NCtxPtr ctx, xmlNodePtr cur, const xmlChar * name, const xmlChar * ns)
989{
991 while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
993 if(res != NULL) {
994 return res;
995 }
996
997 cur = cur->parent;
998 }
999
1000 return NULL;
1001}
1002
1010static xmlAttrPtr
1011xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
1012{
1013 xmlChar * res = NULL;
1016 xmlChar * tmp_str;
1017 xmlChar * tmp_str2;
1018 int tmp_str_len;
1019
1020 if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
1021 xmlC14NErrParam("processing xml:base attribute");
1022 return (NULL);
1023 }
1024
1025 /* start from current value */
1026 res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
1027 if(res == NULL) {
1028 xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
1029 return (NULL);
1030 }
1031
1032 /* go up the stack until we find a node that we rendered already */
1033 cur = xml_base_attr->parent->parent;
1034 while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
1036 if(attr != NULL) {
1037 /* get attr value */
1038 tmp_str = xmlNodeListGetString(ctx->doc, attr->children, 1);
1039 if(tmp_str == NULL) {
1040 xmlFree(res);
1041
1042 xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
1043 return (NULL);
1044 }
1045
1046 /* we need to add '/' if our current base uri ends with '..' or '.'
1047 to ensure that we are forced to go "up" all the time */
1048 tmp_str_len = xmlStrlen(tmp_str);
1049 if(tmp_str_len > 1 && tmp_str[tmp_str_len - 2] == '.') {
1050 tmp_str2 = xmlStrcat(tmp_str, BAD_CAST "/");
1051 if(tmp_str2 == NULL) {
1052 xmlFree(tmp_str);
1053 xmlFree(res);
1054
1055 xmlC14NErrInternal("processing xml:base attribute - can't modify uri");
1056 return (NULL);
1057 }
1058
1059 tmp_str = tmp_str2;
1060 }
1061
1062 /* build uri */
1063 tmp_str2 = xmlBuildURI(res, tmp_str);
1064 if(tmp_str2 == NULL) {
1065 xmlFree(tmp_str);
1066 xmlFree(res);
1067
1068 xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
1069 return (NULL);
1070 }
1071
1072 /* cleanup and set the new res */
1073 xmlFree(tmp_str);
1074 xmlFree(res);
1075 res = tmp_str2;
1076 }
1077
1078 /* next */
1079 cur = cur->parent;
1080 }
1081
1082 /* check if result uri is empty or not */
1083 if((res == NULL) || xmlStrEqual(res, BAD_CAST "")) {
1084 xmlFree(res);
1085 return (NULL);
1086 }
1087
1088 /* create and return the new attribute node */
1089 attr = xmlNewNsProp(NULL, xml_base_attr->ns, BAD_CAST "base", res);
1090 if(attr == NULL) {
1091 xmlFree(res);
1092
1093 xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
1094 return (NULL);
1095 }
1096
1097 /* done */
1098 xmlFree(res);
1099 return (attr);
1100}
1101
1135static int
1136xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
1137{
1140 xmlAttrPtr attrs_to_delete = NULL;
1141
1142 /* special processing for 1.1 spec */
1143 xmlAttrPtr xml_base_attr = NULL;
1144 xmlAttrPtr xml_lang_attr = NULL;
1145 xmlAttrPtr xml_space_attr = NULL;
1146
1147 if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
1148 xmlC14NErrParam("processing attributes axis");
1149 return (-1);
1150 }
1151
1152 /*
1153 * Create a sorted list to store element attributes
1154 */
1155 list = xmlListCreate(NULL, xmlC14NAttrsCompare);
1156 if (list == NULL) {
1157 xmlC14NErrInternal("creating attributes list");
1158 return (-1);
1159 }
1160
1161 switch(ctx->mode) {
1162 case XML_C14N_1_0:
1163 /* The processing of an element node E MUST be modified slightly when an XPath node-set is
1164 * given as input and the element's parent is omitted from the node-set. The method for processing
1165 * the attribute axis of an element E in the node-set is enhanced. All element nodes along E's
1166 * ancestor axis are examined for nearest occurrences of attributes in the xml namespace, such
1167 * as xml:lang and xml:space (whether or not they are in the node-set). From this list of attributes,
1168 * remove any that are in E's attribute axis (whether or not they are in the node-set). Then,
1169 * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
1170 * the node-set. The result of visiting the attribute axis is computed by processing the attribute
1171 * nodes in this merged attribute list.
1172 */
1173
1174 /*
1175 * Add all visible attributes from current node.
1176 */
1177 attr = cur->properties;
1178 while (attr != NULL) {
1179 /* check that attribute is visible */
1180 if (xmlC14NIsVisible(ctx, attr, cur)) {
1182 }
1183 attr = attr->next;
1184 }
1185
1186 /*
1187 * Handle xml attributes
1188 */
1189 if (parent_visible && (cur->parent != NULL) &&
1190 (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent)))
1191 {
1192 xmlNodePtr tmp;
1193
1194 /*
1195 * If XPath node-set is not specified then the parent is always
1196 * visible!
1197 */
1198 tmp = cur->parent;
1199 while (tmp != NULL) {
1200 attr = tmp->properties;
1201 while (attr != NULL) {
1202 if (xmlC14NIsXmlAttr(attr) != 0) {
1203 if (xmlListSearch(list, attr) == NULL) {
1205 }
1206 }
1207 attr = attr->next;
1208 }
1209 tmp = tmp->parent;
1210 }
1211 }
1212
1213 /* done */
1214 break;
1215 case XML_C14N_EXCLUSIVE_1_0:
1216 /* attributes in the XML namespace, such as xml:lang and xml:space
1217 * are not imported into orphan nodes of the document subset
1218 */
1219
1220 /*
1221 * Add all visible attributes from current node.
1222 */
1223 attr = cur->properties;
1224 while (attr != NULL) {
1225 /* check that attribute is visible */
1226 if (xmlC14NIsVisible(ctx, attr, cur)) {
1228 }
1229 attr = attr->next;
1230 }
1231
1232 /* do nothing special for xml attributes */
1233 break;
1234 case XML_C14N_1_1:
1235 /* The processing of an element node E MUST be modified slightly when an XPath node-set is
1236 * given as input and some of the element's ancestors are omitted from the node-set.
1237 *
1238 * Simple inheritable attributes are attributes that have a value that requires at most a simple
1239 * redeclaration. This redeclaration is done by supplying a new value in the child axis. The
1240 * redeclaration of a simple inheritable attribute A contained in one of E's ancestors is done
1241 * by supplying a value to an attribute Ae inside E with the same name. Simple inheritable attributes
1242 * are xml:lang and xml:space.
1243 *
1244 * The method for processing the attribute axis of an element E in the node-set is hence enhanced.
1245 * All element nodes along E's ancestor axis are examined for the nearest occurrences of simple
1246 * inheritable attributes in the xml namespace, such as xml:lang and xml:space (whether or not they
1247 * are in the node-set). From this list of attributes, any simple inheritable attributes that are
1248 * already in E's attribute axis (whether or not they are in the node-set) are removed. Then,
1249 * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
1250 * the node-set. The result of visiting the attribute axis is computed by processing the attribute
1251 * nodes in this merged attribute list.
1252 *
1253 * The xml:id attribute is not a simple inheritable attribute and no processing of these attributes is
1254 * performed.
1255 *
1256 * The xml:base attribute is not a simple inheritable attribute and requires special processing beyond
1257 * a simple redeclaration.
1258 *
1259 * Attributes in the XML namespace other than xml:base, xml:id, xml:lang, and xml:space MUST be processed
1260 * as ordinary attributes.
1261 */
1262
1263 /*
1264 * Add all visible attributes from current node.
1265 */
1266 attr = cur->properties;
1267 while (attr != NULL) {
1268 /* special processing for XML attribute kiks in only when we have invisible parents */
1269 if ((!parent_visible) || (xmlC14NIsXmlAttr(attr) == 0)) {
1270 /* check that attribute is visible */
1271 if (xmlC14NIsVisible(ctx, attr, cur)) {
1273 }
1274 } else {
1275 int matched = 0;
1276
1277 /* check for simple inheritance attributes */
1278 if((!matched) && (xml_lang_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "lang")) {
1279 xml_lang_attr = attr;
1280 matched = 1;
1281 }
1282 if((!matched) && (xml_space_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "space")) {
1283 xml_space_attr = attr;
1284 matched = 1;
1285 }
1286
1287 /* check for base attr */
1288 if((!matched) && (xml_base_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "base")) {
1289 xml_base_attr = attr;
1290 matched = 1;
1291 }
1292
1293 /* otherwise, it is a normal attribute, so just check if it is visible */
1294 if((!matched) && xmlC14NIsVisible(ctx, attr, cur)) {
1296 }
1297 }
1298
1299 /* move to the next one */
1300 attr = attr->next;
1301 }
1302
1303 /* special processing for XML attribute kiks in only when we have invisible parents */
1304 if ((parent_visible)) {
1305
1306 /* simple inheritance attributes - copy */
1307 if(xml_lang_attr == NULL) {
1308 xml_lang_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "lang", XML_XML_NAMESPACE);
1309 }
1310 if(xml_lang_attr != NULL) {
1311 xmlListInsert(list, xml_lang_attr);
1312 }
1313 if(xml_space_attr == NULL) {
1314 xml_space_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "space", XML_XML_NAMESPACE);
1315 }
1316 if(xml_space_attr != NULL) {
1317 xmlListInsert(list, xml_space_attr);
1318 }
1319
1320 /* base uri attribute - fix up */
1321 if(xml_base_attr == NULL) {
1322 /* if we don't have base uri attribute, check if we have a "hidden" one above */
1323 xml_base_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "base", XML_XML_NAMESPACE);
1324 }
1325 if(xml_base_attr != NULL) {
1326 xml_base_attr = xmlC14NFixupBaseAttr(ctx, xml_base_attr);
1327 if(xml_base_attr != NULL) {
1328 xmlListInsert(list, xml_base_attr);
1329
1330 /* note that we MUST delete returned attr node ourselves! */
1331 xml_base_attr->next = attrs_to_delete;
1332 attrs_to_delete = xml_base_attr;
1333 }
1334 }
1335 }
1336
1337 /* done */
1338 break;
1339 }
1340
1341 /*
1342 * print out all elements from list
1343 */
1344 xmlListWalk(list, xmlC14NPrintAttrs, (void *) ctx);
1345
1346 /*
1347 * Cleanup
1348 */
1349 xmlFreePropList(attrs_to_delete);
1351 return (0);
1352}
1353
1363static int
1364xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
1365{
1366 xmlNsPtr ns;
1367
1368 if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
1369 xmlC14NErrParam("checking for relative namespaces");
1370 return (-1);
1371 }
1372
1373 ns = cur->nsDef;
1374 while (ns != NULL) {
1375 if (xmlStrlen(ns->href) > 0) {
1376 xmlURIPtr uri;
1377
1378 uri = xmlParseURI((const char *) ns->href);
1379 if (uri == NULL) {
1380 xmlC14NErrInternal("parsing namespace uri");
1381 return (-1);
1382 }
1383 if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {
1384 xmlC14NErrRelativeNamespace(uri->scheme);
1385 xmlFreeURI(uri);
1386 return (-1);
1387 }
1388 xmlFreeURI(uri);
1389 }
1390 ns = ns->next;
1391 }
1392 return (0);
1393}
1394
1418static int
1419xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
1420{
1421 int ret;
1422 xmlC14NVisibleNsStack state;
1423 int parent_is_doc = 0;
1424
1425 if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
1426 xmlC14NErrParam("processing element node");
1427 return (-1);
1428 }
1429
1430 /*
1431 * Check relative relative namespaces:
1432 * implementations of XML canonicalization MUST report an operation
1433 * failure on documents containing relative namespace URIs.
1434 */
1435 if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {
1436 xmlC14NErrInternal("checking for relative namespaces");
1437 return (-1);
1438 }
1439
1440
1441 /*
1442 * Save ns_rendered stack position
1443 */
1444 memset(&state, 0, sizeof(state));
1445 xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);
1446
1447 if (visible) {
1448 if (ctx->parent_is_doc) {
1449 /* save this flag into the stack */
1450 parent_is_doc = ctx->parent_is_doc;
1451 ctx->parent_is_doc = 0;
1452 ctx->pos = XMLC14N_INSIDE_DOCUMENT_ELEMENT;
1453 }
1454 xmlOutputBufferWriteString(ctx->buf, "<");
1455
1456 if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
1457 xmlOutputBufferWriteString(ctx->buf,
1458 (const char *) cur->ns->prefix);
1459 xmlOutputBufferWriteString(ctx->buf, ":");
1460 }
1461 xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
1462 }
1463
1464 if (!xmlC14NIsExclusive(ctx)) {
1465 ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
1466 } else {
1467 ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
1468 }
1469 if (ret < 0) {
1470 xmlC14NErrInternal("processing namespaces axis");
1471 return (-1);
1472 }
1473 /* todo: shouldn't this go to "visible only"? */
1474 if(visible) {
1475 xmlC14NVisibleNsStackShift(ctx->ns_rendered);
1476 }
1477
1478 ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);
1479 if (ret < 0) {
1480 xmlC14NErrInternal("processing attributes axis");
1481 return (-1);
1482 }
1483
1484 if (visible) {
1485 xmlOutputBufferWriteString(ctx->buf, ">");
1486 }
1487 if (cur->children != NULL) {
1488 ret = xmlC14NProcessNodeList(ctx, cur->children);
1489 if (ret < 0) {
1490 xmlC14NErrInternal("processing childrens list");
1491 return (-1);
1492 }
1493 }
1494 if (visible) {
1495 xmlOutputBufferWriteString(ctx->buf, "</");
1496 if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
1497 xmlOutputBufferWriteString(ctx->buf,
1498 (const char *) cur->ns->prefix);
1499 xmlOutputBufferWriteString(ctx->buf, ":");
1500 }
1501 xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
1502 xmlOutputBufferWriteString(ctx->buf, ">");
1503 if (parent_is_doc) {
1504 /* restore this flag from the stack for next node */
1505 ctx->parent_is_doc = parent_is_doc;
1506 ctx->pos = XMLC14N_AFTER_DOCUMENT_ELEMENT;
1507 }
1508 }
1509
1510 /*
1511 * Restore ns_rendered stack position
1512 */
1513 xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);
1514 return (0);
1515}
1516
1526static int
1527xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
1528{
1529 int ret = 0;
1530 int visible;
1531
1532 if ((ctx == NULL) || (cur == NULL)) {
1533 xmlC14NErrParam("processing node");
1534 return (-1);
1535 }
1536
1537 visible = xmlC14NIsVisible(ctx, cur, cur->parent);
1538 switch (cur->type) {
1539 case XML_ELEMENT_NODE:
1540 ret = xmlC14NProcessElementNode(ctx, cur, visible);
1541 break;
1543 case XML_TEXT_NODE:
1544 /*
1545 * Text Nodes
1546 * the string value, except all ampersands are replaced
1547 * by &amp;, all open angle brackets (<) are replaced by &lt;, all closing
1548 * angle brackets (>) are replaced by &gt;, and all #xD characters are
1549 * replaced by &#xD;.
1550 */
1551 /* cdata sections are processed as text nodes */
1552 /* todo: verify that cdata sections are included in XPath nodes set */
1553 if ((visible) && (cur->content != NULL)) {
1554 xmlChar *buffer;
1555
1556 buffer = xmlC11NNormalizeText(cur->content);
1557 if (buffer != NULL) {
1558 xmlOutputBufferWriteString(ctx->buf,
1559 (const char *) buffer);
1560 xmlFree(buffer);
1561 } else {
1562 xmlC14NErrInternal("normalizing text node");
1563 return (-1);
1564 }
1565 }
1566 break;
1567 case XML_PI_NODE:
1568 /*
1569 * Processing Instruction (PI) Nodes-
1570 * The opening PI symbol (<?), the PI target name of the node,
1571 * a leading space and the string value if it is not empty, and
1572 * the closing PI symbol (?>). If the string value is empty,
1573 * then the leading space is not added. Also, a trailing #xA is
1574 * rendered after the closing PI symbol for PI children of the
1575 * root node with a lesser document order than the document
1576 * element, and a leading #xA is rendered before the opening PI
1577 * symbol of PI children of the root node with a greater document
1578 * order than the document element.
1579 */
1580 if (visible) {
1581 if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
1582 xmlOutputBufferWriteString(ctx->buf, "\x0A<?");
1583 } else {
1584 xmlOutputBufferWriteString(ctx->buf, "<?");
1585 }
1586
1587 xmlOutputBufferWriteString(ctx->buf,
1588 (const char *) cur->name);
1589 if ((cur->content != NULL) && (*(cur->content) != '\0')) {
1590 xmlChar *buffer;
1591
1592 xmlOutputBufferWriteString(ctx->buf, " ");
1593
1594 /* todo: do we need to normalize pi? */
1595 buffer = xmlC11NNormalizePI(cur->content);
1596 if (buffer != NULL) {
1597 xmlOutputBufferWriteString(ctx->buf,
1598 (const char *) buffer);
1599 xmlFree(buffer);
1600 } else {
1601 xmlC14NErrInternal("normalizing pi node");
1602 return (-1);
1603 }
1604 }
1605
1606 if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
1607 xmlOutputBufferWriteString(ctx->buf, "?>\x0A");
1608 } else {
1609 xmlOutputBufferWriteString(ctx->buf, "?>");
1610 }
1611 }
1612 break;
1613 case XML_COMMENT_NODE:
1614 /*
1615 * Comment Nodes
1616 * Nothing if generating canonical XML without comments. For
1617 * canonical XML with comments, generate the opening comment
1618 * symbol (<!--), the string value of the node, and the
1619 * closing comment symbol (-->). Also, a trailing #xA is rendered
1620 * after the closing comment symbol for comment children of the
1621 * root node with a lesser document order than the document
1622 * element, and a leading #xA is rendered before the opening
1623 * comment symbol of comment children of the root node with a
1624 * greater document order than the document element. (Comment
1625 * children of the root node represent comments outside of the
1626 * top-level document element and outside of the document type
1627 * declaration).
1628 */
1629 if (visible && ctx->with_comments) {
1630 if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
1631 xmlOutputBufferWriteString(ctx->buf, "\x0A<!--");
1632 } else {
1633 xmlOutputBufferWriteString(ctx->buf, "<!--");
1634 }
1635
1636 if (cur->content != NULL) {
1637 xmlChar *buffer;
1638
1639 /* todo: do we need to normalize comment? */
1640 buffer = xmlC11NNormalizeComment(cur->content);
1641 if (buffer != NULL) {
1642 xmlOutputBufferWriteString(ctx->buf,
1643 (const char *) buffer);
1644 xmlFree(buffer);
1645 } else {
1646 xmlC14NErrInternal("normalizing comment node");
1647 return (-1);
1648 }
1649 }
1650
1651 if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
1652 xmlOutputBufferWriteString(ctx->buf, "-->\x0A");
1653 } else {
1654 xmlOutputBufferWriteString(ctx->buf, "-->");
1655 }
1656 }
1657 break;
1658 case XML_DOCUMENT_NODE:
1659 case XML_DOCUMENT_FRAG_NODE: /* should be processed as document? */
1660#ifdef LIBXML_HTML_ENABLED
1661 case XML_HTML_DOCUMENT_NODE: /* should be processed as document? */
1662#endif
1663 if (cur->children != NULL) {
1664 ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
1665 ctx->parent_is_doc = 1;
1666 ret = xmlC14NProcessNodeList(ctx, cur->children);
1667 }
1668 break;
1669
1670 case XML_ATTRIBUTE_NODE:
1671 xmlC14NErrInvalidNode("XML_ATTRIBUTE_NODE", "processing node");
1672 return (-1);
1673 case XML_NAMESPACE_DECL:
1674 xmlC14NErrInvalidNode("XML_NAMESPACE_DECL", "processing node");
1675 return (-1);
1677 xmlC14NErrInvalidNode("XML_ENTITY_REF_NODE", "processing node");
1678 return (-1);
1679 case XML_ENTITY_NODE:
1680 xmlC14NErrInvalidNode("XML_ENTITY_NODE", "processing node");
1681 return (-1);
1682
1684 case XML_NOTATION_NODE:
1685 case XML_DTD_NODE:
1686 case XML_ELEMENT_DECL:
1687 case XML_ATTRIBUTE_DECL:
1688 case XML_ENTITY_DECL:
1689#ifdef LIBXML_XINCLUDE_ENABLED
1690 case XML_XINCLUDE_START:
1691 case XML_XINCLUDE_END:
1692#endif
1693 /*
1694 * should be ignored according to "W3C Canonical XML"
1695 */
1696 break;
1697 default:
1698 xmlC14NErrUnknownNode(cur->type, "processing node");
1699 return (-1);
1700 }
1701
1702 return (ret);
1703}
1704
1714static int
1715xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
1716{
1717 int ret;
1718
1719 if (ctx == NULL) {
1720 xmlC14NErrParam("processing node list");
1721 return (-1);
1722 }
1723
1724 for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {
1725 ret = xmlC14NProcessNode(ctx, cur);
1726 }
1727 return (ret);
1728}
1729
1730
1738static void
1739xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
1740{
1741 if (ctx == NULL) {
1742 xmlC14NErrParam("freeing context");
1743 return;
1744 }
1745
1746 if (ctx->ns_rendered != NULL) {
1747 xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);
1748 }
1749 xmlFree(ctx);
1750}
1751
1773static xmlC14NCtxPtr
1774xmlC14NNewCtx(xmlDocPtr doc,
1775 xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
1776 xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
1777 int with_comments, xmlOutputBufferPtr buf)
1778{
1779 xmlC14NCtxPtr ctx = NULL;
1780
1781 if ((doc == NULL) || (buf == NULL)) {
1782 xmlC14NErrParam("creating new context");
1783 return (NULL);
1784 }
1785
1786 /*
1787 * Validate the encoding output buffer encoding
1788 */
1789 if (buf->encoder != NULL) {
1790 xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
1791"xmlC14NNewCtx: output buffer encoder != NULL but C14N requires UTF8 output\n");
1792 return (NULL);
1793 }
1794
1795 /*
1796 * Allocate a new xmlC14NCtxPtr and fill the fields.
1797 */
1798 ctx = (xmlC14NCtxPtr) xmlMalloc(sizeof(xmlC14NCtx));
1799 if (ctx == NULL) {
1800 xmlC14NErrMemory("creating context");
1801 return (NULL);
1802 }
1803 memset(ctx, 0, sizeof(xmlC14NCtx));
1804
1805 /*
1806 * initialize C14N context
1807 */
1808 ctx->doc = doc;
1809 ctx->with_comments = with_comments;
1810 ctx->is_visible_callback = is_visible_callback;
1811 ctx->user_data = user_data;
1812 ctx->buf = buf;
1813 ctx->parent_is_doc = 1;
1814 ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
1815 ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
1816
1817 if(ctx->ns_rendered == NULL) {
1818 xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_CREATE_STACK,
1819 "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
1820 xmlC14NFreeCtx(ctx);
1821 return (NULL);
1822 }
1823
1824 /*
1825 * Set "mode" flag and remember list of inclusive prefixes
1826 * for exclusive c14n
1827 */
1828 ctx->mode = mode;
1829 if(xmlC14NIsExclusive(ctx)) {
1830 ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
1831 }
1832 return (ctx);
1833}
1834
1858int
1859xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
1860 void* user_data, int mode, xmlChar **inclusive_ns_prefixes,
1861 int with_comments, xmlOutputBufferPtr buf) {
1862
1863 xmlC14NCtxPtr ctx;
1864 xmlC14NMode c14n_mode = XML_C14N_1_0;
1865 int ret;
1866
1867 if ((buf == NULL) || (doc == NULL)) {
1868 xmlC14NErrParam("executing c14n");
1869 return (-1);
1870 }
1871
1872 /* for backward compatibility, we have to have "mode" as "int"
1873 and here we check that user gives valid value */
1874 switch(mode) {
1875 case XML_C14N_1_0:
1876 case XML_C14N_EXCLUSIVE_1_0:
1877 case XML_C14N_1_1:
1878 c14n_mode = (xmlC14NMode)mode;
1879 break;
1880 default:
1881 xmlC14NErrParam("invalid mode for executing c14n");
1882 return (-1);
1883 }
1884
1885 /*
1886 * Validate the encoding output buffer encoding
1887 */
1888 if (buf->encoder != NULL) {
1889 xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
1890"xmlC14NExecute: output buffer encoder != NULL but C14N requires UTF8 output\n");
1891 return (-1);
1892 }
1893
1894 ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
1895 c14n_mode, inclusive_ns_prefixes,
1896 with_comments, buf);
1897 if (ctx == NULL) {
1898 xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
1899 "xmlC14NExecute: unable to create C14N context\n");
1900 return (-1);
1901 }
1902
1903
1904
1905 /*
1906 * Root Node
1907 * The root node is the parent of the top-level document element. The
1908 * result of processing each of its child nodes that is in the node-set
1909 * in document order. The root node does not generate a byte order mark,
1910 * XML declaration, nor anything from within the document type
1911 * declaration.
1912 */
1913 if (doc->children != NULL) {
1914 ret = xmlC14NProcessNodeList(ctx, doc->children);
1915 if (ret < 0) {
1916 xmlC14NErrInternal("processing docs children list");
1917 xmlC14NFreeCtx(ctx);
1918 return (-1);
1919 }
1920 }
1921
1922 /*
1923 * Flush buffer to get number of bytes written
1924 */
1925 ret = xmlOutputBufferFlush(buf);
1926 if (ret < 0) {
1927 xmlC14NErrInternal("flushing output buffer");
1928 xmlC14NFreeCtx(ctx);
1929 return (-1);
1930 }
1931
1932 /*
1933 * Cleanup
1934 */
1935 xmlC14NFreeCtx(ctx);
1936 return (ret);
1937}
1938
1960int
1961xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
1962 int mode, xmlChar ** inclusive_ns_prefixes,
1963 int with_comments, xmlOutputBufferPtr buf) {
1964 return(xmlC14NExecute(doc,
1965 xmlC14NIsNodeInNodeset,
1966 nodes,
1967 mode,
1968 inclusive_ns_prefixes,
1969 with_comments,
1970 buf));
1971}
1972
1973
1995int
1996xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
1997 int mode, xmlChar ** inclusive_ns_prefixes,
1998 int with_comments, xmlChar ** doc_txt_ptr)
1999{
2000 int ret;
2002
2003 if (doc_txt_ptr == NULL) {
2004 xmlC14NErrParam("dumping doc to memory");
2005 return (-1);
2006 }
2007
2008 *doc_txt_ptr = NULL;
2009
2010 /*
2011 * create memory buffer with UTF8 (default) encoding
2012 */
2013 buf = xmlAllocOutputBuffer(NULL);
2014 if (buf == NULL) {
2015 xmlC14NErrMemory("creating output buffer");
2016 return (-1);
2017 }
2018
2019 /*
2020 * canonize document and write to buffer
2021 */
2022 ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
2023 with_comments, buf);
2024 if (ret < 0) {
2025 xmlC14NErrInternal("saving doc to output buffer");
2026 (void) xmlOutputBufferClose(buf);
2027 return (-1);
2028 }
2029
2030 ret = xmlBufUse(buf->buffer);
2031 if (ret >= 0) {
2032 *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), ret);
2033 }
2034 (void) xmlOutputBufferClose(buf);
2035
2036 if ((*doc_txt_ptr == NULL) && (ret >= 0)) {
2037 xmlC14NErrMemory("copying canonicalized document");
2038 return (-1);
2039 }
2040 return (ret);
2041}
2042
2066int
2067xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
2068 int mode, xmlChar ** inclusive_ns_prefixes,
2069 int with_comments, const char *filename, int compression)
2070{
2072 int ret;
2073
2074 if (filename == NULL) {
2075 xmlC14NErrParam("saving doc");
2076 return (-1);
2077 }
2078#ifdef LIBXML_ZLIB_ENABLED
2079 if (compression < 0)
2081#endif
2082
2083 /*
2084 * save the content to a temp buffer, use default UTF8 encoding.
2085 */
2086 buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
2087 if (buf == NULL) {
2088 xmlC14NErrInternal("creating temporary filename");
2089 return (-1);
2090 }
2091
2092 /*
2093 * canonize document and write to buffer
2094 */
2095 ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
2096 with_comments, buf);
2097 if (ret < 0) {
2098 xmlC14NErrInternal("canonize document to buffer");
2099 (void) xmlOutputBufferClose(buf);
2100 return (-1);
2101 }
2102
2103 /*
2104 * get the numbers of bytes written
2105 */
2106 ret = xmlOutputBufferClose(buf);
2107 return (ret);
2108}
2109
2110
2111
2112/*
2113 * Macro used to grow the current buffer.
2114 */
2115#define growBufferReentrant() { \
2116 buffer_size *= 2; \
2117 buffer = (xmlChar *) \
2118 xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
2119 if (buffer == NULL) { \
2120 xmlC14NErrMemory("growing buffer"); \
2121 return(NULL); \
2122 } \
2123}
2124
2137static xmlChar *
2138xmlC11NNormalizeString(const xmlChar * input,
2139 xmlC14NNormalizationMode mode)
2140{
2141 const xmlChar *cur = input;
2142 xmlChar *buffer = NULL;
2143 xmlChar *out = NULL;
2144 int buffer_size = 0;
2145
2146 if (input == NULL)
2147 return (NULL);
2148
2149 /*
2150 * allocate an translation buffer.
2151 */
2152 buffer_size = 1000;
2154 if (buffer == NULL) {
2155 xmlC14NErrMemory("allocating buffer");
2156 return (NULL);
2157 }
2158 out = buffer;
2159
2160 while (*cur != '\0') {
2161 if ((out - buffer) > (buffer_size - 10)) {
2162 int indx = out - buffer;
2163
2165 out = &buffer[indx];
2166 }
2167
2168 if ((*cur == '<') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
2169 (mode == XMLC14N_NORMALIZE_TEXT))) {
2170 *out++ = '&';
2171 *out++ = 'l';
2172 *out++ = 't';
2173 *out++ = ';';
2174 } else if ((*cur == '>') && (mode == XMLC14N_NORMALIZE_TEXT)) {
2175 *out++ = '&';
2176 *out++ = 'g';
2177 *out++ = 't';
2178 *out++ = ';';
2179 } else if ((*cur == '&') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
2180 (mode == XMLC14N_NORMALIZE_TEXT))) {
2181 *out++ = '&';
2182 *out++ = 'a';
2183 *out++ = 'm';
2184 *out++ = 'p';
2185 *out++ = ';';
2186 } else if ((*cur == '"') && (mode == XMLC14N_NORMALIZE_ATTR)) {
2187 *out++ = '&';
2188 *out++ = 'q';
2189 *out++ = 'u';
2190 *out++ = 'o';
2191 *out++ = 't';
2192 *out++ = ';';
2193 } else if ((*cur == '\x09') && (mode == XMLC14N_NORMALIZE_ATTR)) {
2194 *out++ = '&';
2195 *out++ = '#';
2196 *out++ = 'x';
2197 *out++ = '9';
2198 *out++ = ';';
2199 } else if ((*cur == '\x0A') && (mode == XMLC14N_NORMALIZE_ATTR)) {
2200 *out++ = '&';
2201 *out++ = '#';
2202 *out++ = 'x';
2203 *out++ = 'A';
2204 *out++ = ';';
2205 } else if ((*cur == '\x0D') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
2206 (mode == XMLC14N_NORMALIZE_TEXT) ||
2207 (mode == XMLC14N_NORMALIZE_COMMENT) ||
2208 (mode == XMLC14N_NORMALIZE_PI))) {
2209 *out++ = '&';
2210 *out++ = '#';
2211 *out++ = 'x';
2212 *out++ = 'D';
2213 *out++ = ';';
2214 } else {
2215 /*
2216 * Works because on UTF-8, all extended sequences cannot
2217 * result in bytes in the ASCII range.
2218 */
2219 *out++ = *cur;
2220 }
2221 cur++;
2222 }
2223 *out = 0;
2224 return (buffer);
2225}
2226#endif /* LIBXML_OUTPUT_ENABLED */
2227
2228#endif /* LIBXML_C14N_ENABLED */
static int state
Definition: maze.c:121
#define msg(x)
Definition: auth_time.c:54
void user(int argc, const char *argv[])
Definition: cmds.c:1350
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1365
int xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string)
Definition: buf.c:921
Definition: list.h:37
#define NULL
Definition: types.h:112
r parent
Definition: btrfs.c:3010
#define growBufferReentrant()
FxCollectionEntry * cur
GLuint start
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ extra
Definition: id3.c:95
const char * filename
Definition: ioapi.h:137
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
const char * uri
Definition: sec_mgr.c:1588
static FILE * out
Definition: regtests2xml.c:44
#define list
Definition: rosglue.h:35
XMLPUBVAR xmlMallocFunc xmlMallocAtomic
Definition: globals.h:249
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
XMLPUBFUN void XMLCALL xmlListWalk(xmlListPtr l, xmlListWalker walker, void *user)
Definition: list.c:676
XMLPUBFUN void *XMLCALL xmlListSearch(xmlListPtr l, void *data)
Definition: list.c:231
XMLPUBFUN int XMLCALL xmlListInsert(xmlListPtr l, void *data)
Definition: list.c:273
XMLPUBFUN void XMLCALL xmlListDelete(xmlListPtr l)
Definition: list.c:333
XMLPUBFUN xmlListPtr XMLCALL xmlListCreate(xmlListDeallocator deallocator, xmlListDataCompare compare)
Definition: list.c:188
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
XMLPUBFUN size_t XMLCALL xmlBufUse(const xmlBufPtr buf)
Definition: buf.c:633
@ XML_DOCUMENT_TYPE_NODE
Definition: tree.h:169
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_XINCLUDE_START
Definition: tree.h:178
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_PI_NODE
Definition: tree.h:166
@ XML_XINCLUDE_END
Definition: tree.h:179
@ XML_DOCUMENT_FRAG_NODE
Definition: tree.h:170
@ XML_COMMENT_NODE
Definition: tree.h:167
@ XML_DTD_NODE
Definition: tree.h:173
@ XML_NAMESPACE_DECL
Definition: tree.h:177
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
@ XML_ELEMENT_NODE
Definition: tree.h:160
@ XML_ELEMENT_DECL
Definition: tree.h:174
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
@ XML_NOTATION_NODE
Definition: tree.h:171
@ XML_ATTRIBUTE_DECL
Definition: tree.h:175
XMLPUBFUN int XMLCALL xmlGetCompressMode(void)
xmlAttr * xmlAttrPtr
Definition: tree.h:433
#define XML_XML_NAMESPACE
Definition: tree.h:140
XMLPUBFUN void XMLCALL xmlFreePropList(xmlAttrPtr cur)
XMLPUBFUN xmlAttrPtr XMLCALL xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
xmlNs * xmlNsPtr
Definition: tree.h:388
XMLPUBFUN xmlAttrPtr XMLCALL xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value)
XMLPUBFUN xmlChar *XMLCALL xmlBufContent(const xmlBuf *buf)
Definition: buf.c:553
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
#define memset(x, y, z)
Definition: compat.h:39
Definition: tree.h:434
xmlNs * ns
Definition: tree.h:444
struct _xmlNode * children
Definition: tree.h:438
struct _xmlAttr * next
Definition: tree.h:441
struct _xmlNode * parent
Definition: tree.h:440
const xmlChar * name
Definition: tree.h:437
Definition: tree.h:551
struct _xmlNode * children
Definition: tree.h:555
Definition: list.c:39
Definition: tree.h:489
struct _xmlAttr * properties
Definition: tree.h:503
struct _xmlNode * parent
Definition: tree.h:495
Definition: tree.h:389
const xmlChar * href
Definition: tree.h:392
const xmlChar * prefix
Definition: tree.h:393
Definition: uri.h:33
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203
Definition: tftpd.h:126
Definition: tftpd.h:138
Definition: name.c:39
Definition: mxnamespace.c:45
BSTR prefix
Definition: mxnamespace.c:46
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:888
Definition: dlist.c:348
Definition: pdh_main.c:94
XMLPUBFUN xmlURIPtr XMLCALL xmlParseURI(const char *str)
Definition: uri.c:940
XMLPUBFUN void XMLCALL xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1387
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1892
int ret
@ XML_ERR_ERROR
Definition: xmlerror.h:27
@ XML_FROM_C14N
Definition: xmlerror.h:58
@ XML_C14N_RELATIVE_NAMESPACE
Definition: xmlerror.h:688
@ XML_C14N_CREATE_CTXT
Definition: xmlerror.h:683
@ XML_C14N_REQUIRES_UTF8
Definition: xmlerror.h:684
@ XML_C14N_CREATE_STACK
Definition: xmlerror.h:685
@ XML_ERR_INTERNAL_ERROR
Definition: xmlerror.h:101
@ XML_C14N_INVALID_NODE
Definition: xmlerror.h:686
@ XML_C14N_UNKNOW_NODE
Definition: xmlerror.h:687
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:133
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28