1044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/*
2f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * "Canonical XML" implementation
3044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * http://www.w3.org/TR/xml-c14n
4f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
5044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * "Exclusive XML Canonicalization" implementation
6044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * http://www.w3.org/TR/xml-exc-c14n
7044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
8044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * See Copyright for the status of this software.
9f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
10044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Author: Aleksey Sanin <aleksey@aleksey.com>
11044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1234ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML
13044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include "libxml.h"
14044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#ifdef LIBXML_C14N_ENABLED
15a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
16044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
17044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#ifdef HAVE_STDLIB_H
18044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <stdlib.h>
19044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#endif
20044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <string.h>
21044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
22044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/tree.h>
23044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/parser.h>
249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard#include <libxml/uri.h>
25044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/xmlerror.h>
26044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/globals.h>
27044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/xpathInternals.h>
28044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/c14n.h>
29044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3053aa293dd3f6ec8f09fcb38cda4467e38c50f22fDaniel Veillard#include "buf.h"
3153aa293dd3f6ec8f09fcb38cda4467e38c50f22fDaniel Veillard
32044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/************************************************************************
33044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *									*
34044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *		Some declaration better left private ATM		*
35044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *									*
36044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ************************************************************************/
37044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
389ff8817e67b286f081205000a63a897f788e42abDaniel Veillardtypedef enum {
399ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_BEFORE_DOCUMENT_ELEMENT = 0,
409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_INSIDE_DOCUMENT_ELEMENT = 1,
419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_AFTER_DOCUMENT_ELEMENT = 2
42044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} xmlC14NPosition;
43044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
44f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanintypedef struct _xmlC14NVisibleNsStack {
459e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    int nsCurEnd;           /* number of nodes in the set */
469e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    int nsPrevStart;        /* the begginning of the stack for previous visible node */
479e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    int nsPrevEnd;          /* the end of the stack for previous visible node */
489e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    int nsMax;              /* size of the array as allocated */
49f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    xmlNsPtr	*nsTab;	    /* array of ns in no particular order */
509e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    xmlNodePtr	*nodeTab;   /* array of nodes in no particular order */
51f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin} xmlC14NVisibleNsStack, *xmlC14NVisibleNsStackPtr;
52dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
53044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardtypedef struct _xmlC14NCtx {
54044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /* input parameters */
559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlDocPtr doc;
562c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    xmlC14NIsVisibleCallback is_visible_callback;
57f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    void* user_data;
589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    int with_comments;
599ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlOutputBufferPtr buf;
60044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
61044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /* position in the XML document */
629ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC14NPosition pos;
639ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    int parent_is_doc;
64f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlC14NVisibleNsStackPtr ns_rendered;
65f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
66838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* C14N mode */
67838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlC14NMode mode;
68044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
69044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /* exclusive canonicalization */
709ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlChar **inclusive_ns_prefixes;
71d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard
72d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard    /* error number */
73d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard    int error;
74044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} xmlC14NCtx, *xmlC14NCtxPtr;
75044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
762c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Saninstatic xmlC14NVisibleNsStackPtr	xmlC14NVisibleNsStackCreate	(void);
779e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void     xmlC14NVisibleNsStackDestroy	(xmlC14NVisibleNsStackPtr cur);
78f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void     xmlC14NVisibleNsStackAdd	    (xmlC14NVisibleNsStackPtr cur,
799e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                                                 xmlNsPtr ns,
809e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                                                 xmlNodePtr node);
81f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void			xmlC14NVisibleNsStackSave	(xmlC14NVisibleNsStackPtr cur,
822c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlC14NVisibleNsStackPtr state);
83f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void			xmlC14NVisibleNsStackRestore	(xmlC14NVisibleNsStackPtr cur,
842c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlC14NVisibleNsStackPtr state);
85f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void			xmlC14NVisibleNsStackShift	(xmlC14NVisibleNsStackPtr cur);
86f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int			xmlC14NVisibleNsStackFind	(xmlC14NVisibleNsStackPtr cur,
872c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlNsPtr ns);
88f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int			xmlExcC14NVisibleNsStackFind	(xmlC14NVisibleNsStackPtr cur,
892c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlNsPtr ns,
902c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlC14NCtxPtr ctx);
912c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
922c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Saninstatic int			xmlC14NIsNodeInNodeset		(xmlNodeSetPtr nodes,
932c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlNodePtr node,
942c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin								 xmlNodePtr parent);
952c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
962c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
97044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
989ff8817e67b286f081205000a63a897f788e42abDaniel Veillardstatic int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur);
999ff8817e67b286f081205000a63a897f788e42abDaniel Veillardstatic int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur);
100044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardtypedef enum {
1019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_NORMALIZE_ATTR = 0,
1029ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_NORMALIZE_COMMENT = 1,
1039ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_NORMALIZE_PI = 2,
1049ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    XMLC14N_NORMALIZE_TEXT = 3
1059ff8817e67b286f081205000a63a897f788e42abDaniel Veillard} xmlC14NNormalizationMode;
106044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1079ff8817e67b286f081205000a63a897f788e42abDaniel Veillardstatic xmlChar *xmlC11NNormalizeString(const xmlChar * input,
1089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                       xmlC14NNormalizationMode mode);
109044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
110f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC11NNormalizeAttr( a ) \
1119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_ATTR)
112f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC11NNormalizeComment( a ) \
1139ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_COMMENT)
114f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC11NNormalizePI( a )	\
1159ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_PI)
116f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC11NNormalizeText( a ) \
1179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_TEXT)
118044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
119f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC14NIsVisible( ctx, node, parent ) \
1202c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     (((ctx)->is_visible_callback != NULL) ? \
1212c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	(ctx)->is_visible_callback((ctx)->user_data, \
1222c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		(xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
123d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard
124f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define	xmlC14NIsExclusive( ctx ) \
125838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    ( (ctx)->mode == XML_C14N_EXCLUSIVE_1_0 )
126838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
127d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard/************************************************************************
128d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard *									*
129f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Some factorized error routines				*
130d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard *									*
131d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard ************************************************************************/
132d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard
133d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard/**
134d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * xmlC14NErrMemory:
135d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @extra:  extra informations
136d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard *
1379e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of memory error
138d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard */
139d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillardstatic void
140d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel VeillardxmlC14NErrMemory(const char *extra)
141d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard{
142659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
143d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
144d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		    NULL, NULL, 0, 0,
145d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		    "Memory allocation failed : %s\n", extra);
146d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard}
147d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard
148d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard/**
1499e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * xmlC14NErrParam:
1509e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * @extra:  extra informations
1519e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin *
1529e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of param error
1539e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin */
1549e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void
1559e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey SaninxmlC14NErrParam(const char *extra)
1569e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin{
1579e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
1589e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
1599e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    NULL, NULL, 0, 0,
1609e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    "Invalid parameter : %s\n", extra);
1619e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin}
1629e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
1639e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin/**
1649e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * xmlC14NErrInternal:
1659e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * @extra:  extra informations
1669e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin *
1679e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of internal error
1689e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin */
1699e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void
1709e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey SaninxmlC14NErrInternal(const char *extra)
1719e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin{
1729e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
1739e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    XML_ERR_INTERNAL_ERROR, XML_ERR_ERROR, NULL, 0, extra,
1749e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    NULL, NULL, 0, 0,
1759e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    "Internal error : %s\n", extra);
1769e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin}
1779e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
1789e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin/**
1799e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * xmlC14NErrInvalidNode:
1809e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * @extra:  extra informations
1819e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin *
1829e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of invalid node error
1839e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin */
1849e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void
1859e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey SaninxmlC14NErrInvalidNode(const char *node_type, const char *extra)
1869e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin{
1879e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
1889e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    XML_C14N_INVALID_NODE, XML_ERR_ERROR, NULL, 0, extra,
1899e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    NULL, NULL, 0, 0,
1909e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    "Node %s is invalid here : %s\n", node_type, extra);
1919e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin}
1929e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
1939e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin/**
1949e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * xmlC14NErrUnknownNode:
1959e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * @extra:  extra informations
1969e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin *
1979e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of unknown node error
1989e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin */
1999e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void
2009e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey SaninxmlC14NErrUnknownNode(int node_type, const char *extra)
2019e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin{
2029e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
2039e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    XML_C14N_UNKNOW_NODE, XML_ERR_ERROR, NULL, 0, extra,
2049e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    NULL, NULL, 0, 0,
2059e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    "Unknown node type %d found : %s\n", node_type, extra);
2069e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin}
2079e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
2089e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin/**
2099e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * xmlC14NErrRelativeNamespace:
2109e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * @extra:  extra informations
2119e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin *
2129e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin * Handle a redefinition of relative namespace error
2139e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin */
2149e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Saninstatic void
2159e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey SaninxmlC14NErrRelativeNamespace(const char *ns_uri)
2169e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin{
2179e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_C14N,
2189e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    XML_C14N_RELATIVE_NAMESPACE, XML_ERR_ERROR, NULL, 0, NULL,
2199e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    NULL, NULL, 0, 0,
2209e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin		    "Relative namespace UR is invalid here : %s\n", ns_uri);
2219e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin}
2229e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
2239e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
2249e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin
2259e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin/**
226d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * xmlC14NErr:
227d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @ctxt:  a C14N evaluation context
228d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @node:  the context node
229d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @error:  the erorr code
230d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @msg:  the message
231d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * @extra:  extra informations
232d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard *
233d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard * Handle a redefinition of attribute error
234d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard */
235d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillardstatic void
236d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel VeillardxmlC14NErr(xmlC14NCtxPtr ctxt, xmlNodePtr node, int error,
237d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard           const char * msg)
238d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard{
239d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard    if (ctxt != NULL)
240d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        ctxt->error = error;
241659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(NULL, NULL, NULL,
242d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		    ctxt, node, XML_FROM_C14N, error,
243d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		    XML_ERR_ERROR, NULL, 0,
244bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard		    NULL, NULL, NULL, 0, 0, "%s", msg);
245d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard}
246d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard
247044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/************************************************************************
248044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *									*
249044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *		The implementation internals				*
250044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *									*
251044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ************************************************************************/
252dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin#define XML_NAMESPACES_DEFAULT		16
253dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
254f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int
2552c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlC14NIsNodeInNodeset(xmlNodeSetPtr nodes, xmlNodePtr node, xmlNodePtr parent) {
2562c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if((nodes != NULL) && (node != NULL)) {
2572c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if(node->type != XML_NAMESPACE_DECL) {
2582c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    return(xmlXPathNodeSetContains(nodes, node));
2592c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	} else {
2602c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    xmlNs ns;
261f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
262f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    memcpy(&ns, node, sizeof(ns));
263f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
2646de6f97d193acc5b760f298d340086c2219d1ccbAleksey Sanin	    /* this is a libxml hack! check xpath.c for details */
2656de6f97d193acc5b760f298d340086c2219d1ccbAleksey Sanin	    if((parent != NULL) && (parent->type == XML_ATTRIBUTE_NODE)) {
2666de6f97d193acc5b760f298d340086c2219d1ccbAleksey Sanin		ns.next = (xmlNsPtr)parent->parent;
2676de6f97d193acc5b760f298d340086c2219d1ccbAleksey Sanin	    } else {
268f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		ns.next = (xmlNsPtr)parent;
2696de6f97d193acc5b760f298d340086c2219d1ccbAleksey Sanin	    }
2702c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
271f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    /*
272f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	     * If the input is an XPath node-set, then the node-set must explicitly
2732c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	     * contain every node to be rendered to the canonical form.
2742c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	     */
2752c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    return(xmlXPathNodeSetContains(nodes, (xmlNodePtr)&ns));
2762c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
2772c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    }
2782c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    return(1);
2792c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin}
2802c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
281f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninstatic xmlC14NVisibleNsStackPtr
282f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NVisibleNsStackCreate(void) {
283f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlC14NVisibleNsStackPtr ret;
284dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
285f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
286dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    if (ret == NULL) {
2879e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrMemory("creating namespaces stack");
288dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	return(NULL);
289dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    }
290f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    memset(ret, 0 , (size_t) sizeof(xmlC14NVisibleNsStack));
291dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    return(ret);
292dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin}
293dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
294dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Saninstatic void
295f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
296dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    if(cur == NULL) {
2979e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("destroying namespaces stack");
2989e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        return;
299dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    }
300dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    if(cur->nsTab != NULL) {
301dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	memset(cur->nsTab, 0, cur->nsMax * sizeof(xmlNsPtr));
302dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	xmlFree(cur->nsTab);
303dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    }
304ea4272a199ff749f33f80a30325d108bfd49182eAleksey Sanin    if(cur->nodeTab != NULL) {
305ea4272a199ff749f33f80a30325d108bfd49182eAleksey Sanin	memset(cur->nodeTab, 0, cur->nsMax * sizeof(xmlNodePtr));
306ea4272a199ff749f33f80a30325d108bfd49182eAleksey Sanin	xmlFree(cur->nodeTab);
307ea4272a199ff749f33f80a30325d108bfd49182eAleksey Sanin    }
308f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    memset(cur, 0, sizeof(xmlC14NVisibleNsStack));
309dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    xmlFree(cur);
310f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
311dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin}
312dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
313f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void
3142c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr node) {
315f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if((cur == NULL) ||
3162c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin       ((cur->nsTab == NULL) && (cur->nodeTab != NULL)) ||
3172c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin       ((cur->nsTab != NULL) && (cur->nodeTab == NULL))) {
3189e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("adding namespace to stack");
319dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	return;
320dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    }
321dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
3222c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if ((cur->nsTab == NULL) && (cur->nodeTab == NULL)) {
323dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin        cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
3242c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        cur->nodeTab = (xmlNodePtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
3252c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if ((cur->nsTab == NULL) || (cur->nodeTab == NULL)) {
326d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	    xmlC14NErrMemory("adding node to stack");
327dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    return;
328dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	}
329dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
3302c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	memset(cur->nodeTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
331dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin        cur->nsMax = XML_NAMESPACES_DEFAULT;
332f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    } else if(cur->nsMax == cur->nsCurEnd) {
333f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	void *tmp;
334dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	int tmpSize;
335f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
336dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	tmpSize = 2 * cur->nsMax;
3372c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	tmp = xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
338dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	if (tmp == NULL) {
339d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	    xmlC14NErrMemory("adding node to stack");
340dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    return;
341dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	}
3422c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	cur->nsTab = (xmlNsPtr*)tmp;
3432c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
3442c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	tmp = xmlRealloc(cur->nodeTab, tmpSize * sizeof(xmlNodePtr));
3452c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if (tmp == NULL) {
346d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	    xmlC14NErrMemory("adding node to stack");
3472c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    return;
3482c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
3492c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	cur->nodeTab = (xmlNodePtr*)tmp;
3502c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
351dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	cur->nsMax = tmpSize;
352dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin    }
3532c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    cur->nsTab[cur->nsCurEnd] = ns;
3542c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    cur->nodeTab[cur->nsCurEnd] = node;
3552c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
3562c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    ++cur->nsCurEnd;
357f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
358f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
359f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninstatic void
360f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
361f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if((cur == NULL) || (state == NULL)) {
3629e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("saving namespaces stack");
363f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	return;
364f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
365f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
366f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    state->nsCurEnd = cur->nsCurEnd;
367f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    state->nsPrevStart = cur->nsPrevStart;
368f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    state->nsPrevEnd = cur->nsPrevEnd;
369f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
370f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
371f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninstatic void
372f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
373f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if((cur == NULL) || (state == NULL)) {
3749e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("restoring namespaces stack");
375f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	return;
376f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
377f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    cur->nsCurEnd = state->nsCurEnd;
378f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    cur->nsPrevStart = state->nsPrevStart;
379f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    cur->nsPrevEnd = state->nsPrevEnd;
380f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
381f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
382f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void
383f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
384f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if(cur == NULL) {
3859e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("shifting namespaces stack");
386f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	return;
387f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
388f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    cur->nsPrevStart = cur->nsPrevEnd;
389f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    cur->nsPrevEnd = cur->nsCurEnd;
390f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
391f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
392f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninstatic int
393f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NStrEqual(const xmlChar *str1, const xmlChar *str2) {
394f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if (str1 == str2) return(1);
395f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if (str1 == NULL) return((*str2) == '\0');
396f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if (str2 == NULL) return((*str1) == '\0');
397f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    do {
398f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	if (*str1++ != *str2) return(0);
399f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    } while (*str2++);
400f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    return(1);
401f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
402f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
403f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin/**
404f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin * xmlC14NVisibleNsStackFind:
405f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
40601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * @ns:			the namespace to check
407f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin *
408f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin * Checks whether the given namespace was already rendered or not
409f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin *
410f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin * Returns 1 if we already wrote this namespace or 0 otherwise
411f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin */
412f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninstatic int
4132c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns)
414f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin{
415f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    int i;
416f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    const xmlChar *prefix;
417f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    const xmlChar *href;
4182c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_empty_ns;
419f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
420f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if(cur == NULL) {
4219e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("searching namespaces stack (c14n)");
422f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        return (0);
423f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
424f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
425f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    /*
426f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * if the default namespace xmlns="" is not defined yet then
427f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin     * we do not want to print it out
428f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin     */
429f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
430f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
4312c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
4322c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
433f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if (cur->nsTab != NULL) {
4342c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	int start = (has_empty_ns) ? 0 : cur->nsPrevStart;
435f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        for (i = cur->nsCurEnd - 1; i >= start; --i) {
436f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin            xmlNsPtr ns1 = cur->nsTab[i];
437f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
438f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	    if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
439f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin		return(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL));
440f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	    }
441f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        }
442f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
4432c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    return(has_empty_ns);
444dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin}
445dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
446f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int
4472c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlExcC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NCtxPtr ctx) {
4482c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int i;
4492c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    const xmlChar *prefix;
4502c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    const xmlChar *href;
4512c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_empty_ns;
452f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
4532c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if(cur == NULL) {
4549e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("searching namespaces stack (exc c14n)");
4559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (0);
4569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
457044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
4582c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /*
459f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * if the default namespace xmlns="" is not defined yet then
4602c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     * we do not want to print it out
461f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin     */
4622c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
4632c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
4642c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
465f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
4662c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if (cur->nsTab != NULL) {
4672c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	int start = 0;
4682c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        for (i = cur->nsCurEnd - 1; i >= start; --i) {
4692c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin            xmlNsPtr ns1 = cur->nsTab[i];
470f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
4712c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
4722c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		if(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL)) {
473f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		    return(xmlC14NIsVisible(ctx, ns1, cur->nodeTab[i]));
4742c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		} else {
4752c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		    return(0);
4762c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
4772c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    }
4782c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        }
4792c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    }
4802c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    return(has_empty_ns);
481f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin}
482f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
4832c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
4842c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
4852c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
486044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
487044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NIsXmlNs:
488f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ns:		the namespace to check
489f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
490044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Checks whether the given namespace is a default "xml:" namespace
491044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * with href="http://www.w3.org/XML/1998/namespace"
492044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
493044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 1 if the node is default or 0 otherwise
494044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
4959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
496044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/* todo: make it a define? */
497044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
4989ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NIsXmlNs(xmlNsPtr ns)
4999ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
5009ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return ((ns != NULL) &&
5019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
502838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            (xmlStrEqual(ns->href, XML_XML_NAMESPACE)));
503044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
504044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
505044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
506044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
507f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin * xmlC14NNsCompare:
508044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns1:		the pointer to first namespace
509f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ns2:		the pointer to second namespace
510044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
511044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Compares the namespaces by names (prefixes).
512044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
513044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2.
514044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
5159ff8817e67b286f081205000a63a897f788e42abDaniel Veillardstatic int
516f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2)
5179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
5189ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ns1 == ns2)
5199ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (0);
5209ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ns1 == NULL)
5219ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
5229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ns2 == NULL)
5239ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (1);
5249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
5259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (xmlStrcmp(ns1->prefix, ns2->prefix));
526044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
527044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
528044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
529044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
530044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NPrintNamespaces:
531044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:			the pointer to namespace
532f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
533044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
534044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints the given namespace to the output buffer from C14N context.
535044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
536044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 1 on success or 0 on fail.
537044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
538044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
5399ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
5409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
541044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
5429ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ns == NULL) || (ctx == NULL)) {
5439e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("writing namespaces");
5449ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return 0;
545044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
546044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
5479ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ns->prefix != NULL) {
5489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, " xmlns:");
5499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
5501ba80b7b6f1c89873fa319461954727a7bef2441Aleksey Sanin        xmlOutputBufferWriteString(ctx->buf, "=");
551044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else {
5521ba80b7b6f1c89873fa319461954727a7bef2441Aleksey Sanin        xmlOutputBufferWriteString(ctx->buf, " xmlns=");
553044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
554f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if(ns->href != NULL) {
5551ba80b7b6f1c89873fa319461954727a7bef2441Aleksey Sanin	xmlBufWriteQuotedString(ctx->buf->buffer, ns->href);
5561ba80b7b6f1c89873fa319461954727a7bef2441Aleksey Sanin    } else {
5571ba80b7b6f1c89873fa319461954727a7bef2441Aleksey Sanin    	xmlOutputBufferWriteString(ctx->buf, "\"\"");
558f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
5599ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (1);
560044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
561044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
562044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
563044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NProcessNamespacesAxis:
564f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
565044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:		the current node
566044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
567044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints out canonical namespace axis of the current node to the
568f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * buffer from C14N context as follows
569044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
570044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
571044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
572044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace Axis
573f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Consider a list L containing only namespace nodes in the
574f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * axis and in the node-set in lexicographic order (ascending). To begin
575f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * processing L, if the first node is not the default namespace node (a node
576f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * with no namespace URI and no local name), then generate a space followed
577044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * by xmlns="" if and only if the following conditions are met:
578044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *    - the element E that owns the axis is in the node-set
579f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *    - The nearest ancestor element of E in the node-set has a default
580f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *	    namespace node in the node-set (default namespace nodes always
581044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *      have non-empty values in XPath)
582f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * The latter condition eliminates unnecessary occurrences of xmlns="" in
583f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * the canonical form since an element only receives an xmlns="" if its
584f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * default namespace is empty and if it has an immediate parent in the
585f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * canonical form that has a non-empty default namespace. To finish
586f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * processing  L, simply process every namespace node in L, except omit
587f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * namespace node with local name xml, which defines the xml prefix,
588044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * if its string value is http://www.w3.org/XML/1998/namespace.
589044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
590044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
591f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Canonical XML applied to a document subset requires the search of the
592f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * ancestor nodes of each orphan element node for attributes in the xml
593f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * namespace, such as xml:lang and xml:space. These are copied into the
594f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * element node except if a declaration of the same attribute is already
595f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * in the attribute axis of the element (whether or not it is included in
596f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * the document subset). This search and copying are omitted from the
597044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Exclusive XML Canonicalization method.
598044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
599044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 0 on success or -1 on fail.
600044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
601044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
602f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
6039ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
6042c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    xmlNodePtr n;
6052c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    xmlNsPtr ns, tmp;
606044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlListPtr list;
6072c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int already_rendered;
6082c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_empty_ns = 0;
609f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
6109ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
6119e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing namespaces axis (c14n)");
6129ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
6139ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
614044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
615044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
616044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Create a sorted list to store element namespaces
617044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
6182c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
6199ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (list == NULL) {
6209e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("creating namespaces list (c14n)");
6219ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
6229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
6239ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
6242c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /* check all namespaces */
6252c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    for(n = cur; n != NULL; n = n->parent) {
6262c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	for(ns = n->nsDef; ns != NULL; ns = ns->next) {
6272c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    tmp = xmlSearchNs(cur->doc, cur, ns->prefix);
628f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
6292c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
6302c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
6312c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		if(visible) {
632f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
6332c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
6342c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		if(!already_rendered) {
635f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		    xmlListInsert(list, ns);
636c57f9c12100ecea40faadaceb02899e9a5792571Aleksey Sanin		}
637f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		if(xmlStrlen(ns->prefix) == 0) {
6382c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		    has_empty_ns = 1;
6392c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
640c57f9c12100ecea40faadaceb02899e9a5792571Aleksey Sanin	    }
641dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	}
6422c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    }
643f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
6442c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /**
645f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * if the first node is not the default namespace node (a node with no
646f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * namespace URI and no local name), then generate a space followed by
6472c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     * xmlns="" if and only if the following conditions are met:
6482c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     *  - the element E that owns the axis is in the node-set
649f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     *  - the nearest ancestor element of E in the node-set has a default
650f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     *     namespace node in the node-set (default namespace nodes always
6512c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     *     have non-empty values in XPath)
6522c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     */
6532c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if(visible && !has_empty_ns) {
6542c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        static xmlNs ns_default;
6552c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
6562c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        memset(&ns_default, 0, sizeof(ns_default));
6572c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
658f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NPrintNamespaces(&ns_default, ctx);
659f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	}
660044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
661f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
662f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
663f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
664f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * print out all elements from list
665044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
666f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
6679ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
668f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
669044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Cleanup
670044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
671044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlListDelete(list);
6729ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (0);
673044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
674044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
675dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin
676044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
677044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlExcC14NProcessNamespacesAxis:
678f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
679044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:		the current node
680044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
681044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints out exclusive canonical namespace axis of the current node to the
682f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * buffer from C14N context as follows
683044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
684044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Exclusive XML Canonicalization
685044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * http://www.w3.org/TR/xml-exc-c14n
686044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
687f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * If the element node is in the XPath subset then output the node in
688f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * accordance with Canonical XML except for namespace nodes which are
689044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * rendered as follows:
690044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
691044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1. Render each namespace node iff:
692f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *    * it is visibly utilized by the immediate parent element or one of
693044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *      its attributes, or is present in InclusiveNamespaces PrefixList, and
694f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *    * its prefix and value do not appear in ns_rendered. ns_rendered is
695f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *      obtained by popping the state stack in order to obtain a list of
696f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *      prefixes and their values which have already been rendered by
697044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *      an output ancestor of the namespace node's parent element.
698f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 2. Append the rendered namespace node to the list ns_rendered of namespace
699f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * nodes rendered by output ancestors. Push ns_rendered on state stack and
700044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * recurse.
701044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 3. After the recursion returns, pop thestate stack.
702044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
703044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
704044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 0 on success or -1 on fail.
705044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
706044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
707f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey SaninxmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
7089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
7092c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    xmlNsPtr ns;
710044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlListPtr list;
711044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlAttrPtr attr;
7122c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int already_rendered;
7132c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_empty_ns = 0;
7142c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_visibly_utilized_empty_ns = 0;
7152c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    int has_empty_ns_in_inclusive_list = 0;
716f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
7179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
7189e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing namespaces axis (exc c14n)");
7199ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
7209ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
7219ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
722838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if(!xmlC14NIsExclusive(ctx)) {
7239e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing namespaces axis (exc c14n)");
7249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
7259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
726044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
7279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
728044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
729044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Create a sorted list to store element namespaces
730044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
731f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
7329ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (list == NULL) {
7339e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("creating namespaces list (exc c14n)");
7349ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
7359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
736044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
737f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
7382c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     * process inclusive namespaces:
739f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * All namespace nodes appearing on inclusive ns list are
7402c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     * handled as provided in Canonical XML
741044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
7422c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if(ctx->inclusive_ns_prefixes != NULL) {
743f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	xmlChar *prefix;
7442c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	int i;
745f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
7462c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	for (i = 0; ctx->inclusive_ns_prefixes[i] != NULL; ++i) {
7472c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    prefix = ctx->inclusive_ns_prefixes[i];
7482c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    /*
7492c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	     * Special values for namespace with empty prefix
7502c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	     */
7512c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin            if (xmlStrEqual(prefix, BAD_CAST "#default")
7522c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin                || xmlStrEqual(prefix, BAD_CAST "")) {
7532c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin                prefix = NULL;
7542c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		has_empty_ns_in_inclusive_list = 1;
7552c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin            }
756f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
757f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    ns = xmlSearchNs(cur->doc, cur, prefix);
7582c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
7592c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
7602c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		if(visible) {
761f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
7622c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
7632c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		if(!already_rendered) {
764f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		    xmlListInsert(list, ns);
7652c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
766f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		if(xmlStrlen(ns->prefix) == 0) {
7672c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		    has_empty_ns = 1;
7682c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		}
769f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	    }
7702c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
7712c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    }
772f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
7732c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /* add node namespace */
7742c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if(cur->ns != NULL) {
7752c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	ns = cur->ns;
7762c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    } else {
7772c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        ns = xmlSearchNs(cur->doc, cur, NULL);
7782c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	has_visibly_utilized_empty_ns = 1;
7792c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    }
7802c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    if((ns != NULL) && !xmlC14NIsXmlNs(ns)) {
781f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	if(visible && xmlC14NIsVisible(ctx, ns, cur)) {
7822c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if(!xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, ns, ctx)) {
7832c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		xmlListInsert(list, ns);
784f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	    }
785c57f9c12100ecea40faadaceb02899e9a5792571Aleksey Sanin	}
7862c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if(visible) {
787f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
7882c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
7892c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if(xmlStrlen(ns->prefix) == 0) {
7902c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    has_empty_ns = 1;
7912c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
792044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
793f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
794f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
7952c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /* add attributes */
7962c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    for(attr = cur->properties; attr != NULL; attr = attr->next) {
797f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /*
7982d347fac9815f5c4a1c9073b4e04c892a5245c8aDaniel Veillard         * we need to check that attribute is visible and has non
799f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * default namespace (XML Namespaces: "default namespaces
800f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	 * do not apply directly to attributes")
8019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard         */
8022650df1a68d1659922e5069df6d12fd0373c0ad8Aleksey Sanin	if((attr->ns != NULL) && !xmlC14NIsXmlNs(attr->ns) && xmlC14NIsVisible(ctx, attr, cur)) {
8032c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);
804f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur);
8052c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if(!already_rendered && visible) {
806f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		xmlListInsert(list, attr->ns);
8072c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    }
8082c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    if(xmlStrlen(attr->ns->prefix) == 0) {
8092c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin		has_empty_ns = 1;
8102c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    }
811b2eabc0c441733835663f9b667ee4d8706708535Aleksey Sanin	} else if((attr->ns != NULL) && (xmlStrlen(attr->ns->prefix) == 0) && (xmlStrlen(attr->ns->href) == 0)) {
8122c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    has_visibly_utilized_empty_ns = 1;
8132c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
814044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
8159ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
8162c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    /*
8172c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin     * Process xmlns=""
818044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
819f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if(visible && has_visibly_utilized_empty_ns &&
8202c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	    !has_empty_ns && !has_empty_ns_in_inclusive_list) {
8212c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        static xmlNs ns_default;
8229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
8232c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        memset(&ns_default, 0, sizeof(ns_default));
824f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
8252c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default, ctx);
8262c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	if(!already_rendered) {
827f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NPrintNamespaces(&ns_default, ctx);
8282c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
8292c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    } else if(visible && !has_empty_ns && has_empty_ns_in_inclusive_list) {
8302c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        static xmlNs ns_default;
8312c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
8322c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        memset(&ns_default, 0, sizeof(ns_default));
8332c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
834f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    xmlC14NPrintNamespaces(&ns_default, ctx);
8352c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	}
836044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
8379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
8382c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
839f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
840f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
841f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * print out all elements from list
842044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
843f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
8449ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
845f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
846044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Cleanup
847044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
848044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlListDelete(list);
8499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (0);
850044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
851044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
852044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
853044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
854838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * xmlC14NIsXmlAttr:
855f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @attr:		the attr to check
856f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
857838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Checks whether the given attribute is a default "xml:" namespace
858838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * with href="http://www.w3.org/XML/1998/namespace"
859838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin *
860838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Returns 1 if the node is default or 0 otherwise
861838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin */
862838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
863838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin/* todo: make it a define? */
864838682478cf89ddcbda294d9557c72813135fc7aAleksey Saninstatic int
865838682478cf89ddcbda294d9557c72813135fc7aAleksey SaninxmlC14NIsXmlAttr(xmlAttrPtr attr)
866838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin{
867f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    return ((attr->ns != NULL) &&
868838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin           (xmlC14NIsXmlNs(attr->ns) != 0));
869838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin}
870838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
871838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
872838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin/**
873044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NAttrsCompare:
874f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin * @attr1:		the pointer tls o first attr
875f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @attr2:		the pointer to second attr
876044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
877044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints the given attribute to the output buffer from C14N context.
878044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
879044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2.
880044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
881044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
8829ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2)
8839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
884044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret = 0;
885044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
886044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
887044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Simple cases
888044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
8899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr1 == attr2)
8909ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (0);
8919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr1 == NULL)
8929ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
8939ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr2 == NULL)
8949ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (1);
8959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr1->ns == attr2->ns) {
8969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (xmlStrcmp(attr1->name, attr2->name));
897044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
898044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
899f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
900044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Attributes in the default namespace are first
901044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * because the default namespace is not applied to
902044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * unqualified attributes
903044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
9049ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr1->ns == NULL)
9059ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
9069ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr2->ns == NULL)
9079ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (1);
9089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr1->ns->prefix == NULL)
9099ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
9109ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr2->ns->prefix == NULL)
9119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (1);
9129ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
913044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ret = xmlStrcmp(attr1->ns->href, attr2->ns->href);
9149ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ret == 0) {
9159ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        ret = xmlStrcmp(attr1->name, attr2->name);
916044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
9179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
918044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
919044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
920044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
921044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
922044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NPrintAttrs:
923044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @attr:		the pointer to attr
924f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
925044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
926044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints out canonical attribute urrent node to the
927f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * buffer from C14N context as follows
928044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
929044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
930044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
931044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 1 on success or 0 on fail.
932044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
933044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
9349ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
9359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
936044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlChar *value;
937044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlChar *buffer;
938044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
9399ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((attr == NULL) || (ctx == NULL)) {
9409e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("writing attributes");
9419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (0);
942044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
943044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
944044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlOutputBufferWriteString(ctx->buf, " ");
9459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (attr->ns != NULL && xmlStrlen(attr->ns->prefix) > 0) {
9469ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf,
9479ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                   (const char *) attr->ns->prefix);
9489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, ":");
949044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
950044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
951044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlOutputBufferWriteString(ctx->buf, "=\"");
952044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
953838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    value = xmlNodeListGetString(ctx->doc, attr->children, 1);
954044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /* todo: should we log an error if value==NULL ? */
9559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (value != NULL) {
9569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        buffer = xmlC11NNormalizeAttr(value);
9579ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlFree(value);
9589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if (buffer != NULL) {
9599ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);
9609ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlFree(buffer);
9619ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else {
9629e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInternal("normalizing attributes axis");
9639ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (0);
9649ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
965044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
966044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlOutputBufferWriteString(ctx->buf, "\"");
9679ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (1);
968044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
969044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
970044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
971838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * xmlC14NFindHiddenParentAttr:
972838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin *
973838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Finds an attribute in a hidden parent node.
974f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
975838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Returns a pointer to the attribute node (if found) or NULL otherwise.
976838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin */
977838682478cf89ddcbda294d9557c72813135fc7aAleksey Saninstatic xmlAttrPtr
978838682478cf89ddcbda294d9557c72813135fc7aAleksey SaninxmlC14NFindHiddenParentAttr(xmlC14NCtxPtr ctx, xmlNodePtr cur, const xmlChar * name, const xmlChar * ns)
979838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin{
980838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr res;
981838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
982838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        res = xmlHasNsProp(cur, name, ns);
983838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        if(res != NULL) {
984838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            return res;
985838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        }
986838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
987838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        cur = cur->parent;
988838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
989838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
990838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    return NULL;
991838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin}
992838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
993838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin/**
994838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * xmlC14NFixupBaseAttr:
995838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin *
996838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Fixes up the xml:base attribute
997838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin *
998838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * Returns the newly created attribute or NULL
999838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin */
1000838682478cf89ddcbda294d9557c72813135fc7aAleksey Saninstatic xmlAttrPtr
1001838682478cf89ddcbda294d9557c72813135fc7aAleksey SaninxmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
1002f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard{
1003838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlChar * res = NULL;
1004838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlNodePtr cur;
1005838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr attr;
1006838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlChar * tmp_str;
1007838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlChar * tmp_str2;
1008838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    int tmp_str_len;
1009838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1010838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
1011838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        xmlC14NErrParam("processing xml:base attribute");
1012838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        return (NULL);
1013838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
1014838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1015838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* start from current value */
1016838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
1017838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if(res == NULL) {
1018838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
1019838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        return (NULL);
1020838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
1021838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1022838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* go up the stack until we find a node that we rendered already */
1023838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    cur = xml_base_attr->parent->parent;
1024838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
1025838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        attr = xmlHasNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
1026838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        if(attr != NULL) {
1027838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* get attr value */
1028838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            tmp_str = xmlNodeListGetString(ctx->doc, attr->children, 1);
1029838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(tmp_str == NULL) {
1030838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlFree(res);
1031838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1032838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
1033838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                return (NULL);
1034f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            }
1035838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1036f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            /* we need to add '/' if our current base uri ends with '..' or '.'
1037838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            to ensure that we are forced to go "up" all the time */
1038838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            tmp_str_len = xmlStrlen(tmp_str);
1039838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(tmp_str_len > 1 && tmp_str[tmp_str_len - 2] == '.') {
1040838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                tmp_str2 = xmlStrcat(tmp_str, BAD_CAST "/");
1041838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if(tmp_str2 == NULL) {
1042838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlFree(tmp_str);
1043838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlFree(res);
1044838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1045838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlC14NErrInternal("processing xml:base attribute - can't modify uri");
1046838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    return (NULL);
1047838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1048838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1049838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                tmp_str = tmp_str2;
1050838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1051838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1052838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* build uri */
1053f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            tmp_str2 = xmlBuildURI(res, tmp_str);
1054838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(tmp_str2 == NULL) {
1055838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlFree(tmp_str);
1056838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlFree(res);
1057838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1058838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
1059838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                return (NULL);
1060838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1061838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1062838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* cleanup and set the new res */
1063838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            xmlFree(tmp_str);
1064838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            xmlFree(res);
1065838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            res = tmp_str2;
1066838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        }
1067838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1068838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        /* next */
1069838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        cur = cur->parent;
1070838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
1071838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1072838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* check if result uri is empty or not */
1073838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if((res == NULL) || xmlStrEqual(res, BAD_CAST "")) {
1074838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        xmlFree(res);
1075838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        return (NULL);
1076838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
1077838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1078838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* create and return the new attribute node */
1079838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    attr = xmlNewNsProp(NULL, xml_base_attr->ns, BAD_CAST "base", res);
1080838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if(attr == NULL) {
1081838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        xmlFree(res);
1082838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1083838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
1084838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        return (NULL);
1085838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    }
1086f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1087838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* done */
1088838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlFree(res);
1089838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    return (attr);
1090838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin}
1091838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1092838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin/**
1093044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NProcessAttrsAxis:
1094f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the C14N context
1095044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:		the current node
10963ea201cedbe0842eedf3d2216b14cf8d356f8453Aleksey Sanin * @parent_visible:	the visibility of parent node
1097838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @all_parents_visible: the visibility of all parent nodes
1098044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1099044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Prints out canonical attribute axis of the current node to the
1100f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * buffer from C14N context as follows
1101044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1102044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
1103044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1104f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Attribute Axis
1105f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * In lexicographic order (ascending), process each node that
1106044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * is in the element's attribute axis and in the node-set.
1107f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1108f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * The processing of an element node E MUST be modified slightly
1109f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * when an XPath node-set is given as input and the element's
1110044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent is omitted from the node-set.
1111044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1112044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1113044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
1114044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1115f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Canonical XML applied to a document subset requires the search of the
1116f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * ancestor nodes of each orphan element node for attributes in the xml
1117f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * namespace, such as xml:lang and xml:space. These are copied into the
1118f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * element node except if a declaration of the same attribute is already
1119f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * in the attribute axis of the element (whether or not it is included in
1120f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * the document subset). This search and copying are omitted from the
1121044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Exclusive XML Canonicalization method.
1122044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1123044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 0 on success or -1 on fail.
1124044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1125044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
11263ea201cedbe0842eedf3d2216b14cf8d356f8453Aleksey SaninxmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
11279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1128044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlAttrPtr attr;
1129f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    xmlListPtr list;
1130838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr attrs_to_delete = NULL;
1131f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1132838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    /* special processing for 1.1 spec */
1133838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr xml_base_attr = NULL;
1134838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr xml_lang_attr = NULL;
1135838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlAttrPtr xml_space_attr = NULL;
11369ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
11379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
11389e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing attributes axis");
11399ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
11409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
1141044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1142044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1143044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Create a sorted list to store element attributes
1144044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
11459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NAttrsCompare);
11469ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (list == NULL) {
11479e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("creating attributes list");
11489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1149044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1150044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1151838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    switch(ctx->mode) {
1152838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    case XML_C14N_1_0:
1153f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /* The processing of an element node E MUST be modified slightly when an XPath node-set is
1154f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * given as input and the element's parent is omitted from the node-set. The method for processing
1155f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * the attribute axis of an element E in the node-set is enhanced. All element nodes along E's
1156f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * ancestor axis are examined for nearest occurrences of attributes in the xml namespace, such
1157f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * as xml:lang and xml:space (whether or not they are in the node-set). From this list of attributes,
1158f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * remove any that are in E's attribute axis (whether or not they are in the node-set). Then,
1159f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
1160f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * the node-set. The result of visiting the attribute axis is computed by processing the attribute
1161f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * nodes in this merged attribute list.
1162838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1163f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1164f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /*
1165f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * Add all visible attributes from current node.
1166838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1167838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        attr = cur->properties;
1168838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        while (attr != NULL) {
1169838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* check that attribute is visible */
1170838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if (xmlC14NIsVisible(ctx, attr, cur)) {
1171838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlListInsert(list, attr);
1172838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1173838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            attr = attr->next;
11749ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
11759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1176f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /*
1177838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * Handle xml attributes
11789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard         */
1179f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        if (parent_visible && (cur->parent != NULL) &&
1180f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent)))
1181838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        {
1182838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            xmlNodePtr tmp;
1183838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1184838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /*
1185f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * If XPath node-set is not specified then the parent is always
1186838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin             * visible!
1187838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin             */
1188838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            tmp = cur->parent;
1189838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            while (tmp != NULL) {
1190838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                attr = tmp->properties;
1191838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                while (attr != NULL) {
1192838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    if (xmlC14NIsXmlAttr(attr) != 0) {
1193838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                        if (xmlListSearch(list, attr) == NULL) {
1194838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                            xmlListInsert(list, attr);
1195838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                        }
11969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    }
1197838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    attr = attr->next;
1198838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1199838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                tmp = tmp->parent;
1200838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1201838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        }
1202838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1203838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        /* done */
1204838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        break;
1205838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    case XML_C14N_EXCLUSIVE_1_0:
1206f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /* attributes in the XML namespace, such as xml:lang and xml:space
1207f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * are not imported into orphan nodes of the document subset
1208838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1209838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1210f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /*
1211f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * Add all visible attributes from current node.
1212838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1213838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        attr = cur->properties;
1214838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        while (attr != NULL) {
1215838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* check that attribute is visible */
1216838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if (xmlC14NIsVisible(ctx, attr, cur)) {
1217838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlListInsert(list, attr);
1218838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1219838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            attr = attr->next;
1220838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        }
1221838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1222838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        /* do nothing special for xml attributes */
1223838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        break;
1224838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    case XML_C14N_1_1:
1225f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /* The processing of an element node E MUST be modified slightly when an XPath node-set is
1226f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * given as input and some of the element's ancestors are omitted from the node-set.
1227838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         *
1228f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * Simple inheritable attributes are attributes that have a value that requires at most a simple
1229f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * redeclaration. This redeclaration is done by supplying a new value in the child axis. The
1230f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * redeclaration of a simple inheritable attribute A contained in one of E's ancestors is done
1231f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * by supplying a value to an attribute Ae inside E with the same name. Simple inheritable attributes
1232838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * are xml:lang and xml:space.
1233f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         *
1234f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * The method for processing the attribute axis of an element E in the node-set is hence enhanced.
1235f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * All element nodes along E's ancestor axis are examined for the nearest occurrences of simple
1236f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * inheritable attributes in the xml namespace, such as xml:lang and xml:space (whether or not they
1237f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * are in the node-set). From this list of attributes, any simple inheritable attributes that are
1238f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * already in E's attribute axis (whether or not they are in the node-set) are removed. Then,
1239f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
1240f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * the node-set. The result of visiting the attribute axis is computed by processing the attribute
1241838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * nodes in this merged attribute list.
1242f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         *
1243f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * The xml:id attribute is not a simple inheritable attribute and no processing of these attributes is
1244838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * performed.
1245f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         *
1246f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * The xml:base attribute is not a simple inheritable attribute and requires special processing beyond
1247838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * a simple redeclaration.
1248f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         *
1249f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * Attributes in the XML namespace other than xml:base, xml:id, xml:lang, and xml:space MUST be processed
1250838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         * as ordinary attributes.
1251838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1252838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1253f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard        /*
1254f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard         * Add all visible attributes from current node.
1255838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin         */
1256838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        attr = cur->properties;
1257838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        while (attr != NULL) {
1258838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* special processing for XML attribute kiks in only when we have invisible parents */
1259838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if ((!parent_visible) || (xmlC14NIsXmlAttr(attr) == 0)) {
1260838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                /* check that attribute is visible */
1261838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if (xmlC14NIsVisible(ctx, attr, cur)) {
1262838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlListInsert(list, attr);
1263838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1264838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            } else {
1265838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                int matched = 0;
1266838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1267838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                /* check for simple inheritance attributes */
1268838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if((!matched) && (xml_lang_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "lang")) {
1269838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xml_lang_attr = attr;
1270838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    matched = 1;
1271f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard                }
1272838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if((!matched) && (xml_space_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "space")) {
1273838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xml_space_attr = attr;
1274838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    matched = 1;
1275838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1276838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1277838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                /* check for base attr */
1278838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if((!matched) && (xml_base_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "base")) {
1279838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xml_base_attr = attr;
1280838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    matched = 1;
1281838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1282838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1283838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                /* otherwise, it is a normal attribute, so just check if it is visible */
1284838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                if((!matched) && xmlC14NIsVisible(ctx, attr, cur)) {
1285838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlListInsert(list, attr);
12869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
12879ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
1288f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1289838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* move to the next one */
1290838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            attr = attr->next;
12919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
1292f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
1293838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        /* special processing for XML attribute kiks in only when we have invisible parents */
1294838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        if ((parent_visible)) {
1295838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1296838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* simple inheritance attributes - copy */
1297838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_lang_attr == NULL) {
1298838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xml_lang_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "lang", XML_XML_NAMESPACE);
1299838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1300838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_lang_attr != NULL) {
1301838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlListInsert(list, xml_lang_attr);
1302838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1303838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_space_attr == NULL) {
1304838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xml_space_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "space", XML_XML_NAMESPACE);
1305838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1306838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_space_attr != NULL) {
1307838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xmlListInsert(list, xml_space_attr);
1308838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1309838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1310838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            /* base uri attribute - fix up */
1311838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_base_attr == NULL) {
1312838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                /* if we don't have base uri attribute, check if we have a "hidden" one above */
1313838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xml_base_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "base", XML_XML_NAMESPACE);
1314838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1315838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            if(xml_base_attr != NULL) {
1316838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                xml_base_attr = xmlC14NFixupBaseAttr(ctx, xml_base_attr);
1317f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard                if(xml_base_attr != NULL) {
1318838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xmlListInsert(list, xml_base_attr);
1319838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1320838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    /* note that we MUST delete returned attr node ourselves! */
1321838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    xml_base_attr->next = attrs_to_delete;
1322838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                    attrs_to_delete = xml_base_attr;
1323838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                }
1324838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin            }
1325838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        }
1326838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin
1327838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        /* done */
1328838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin        break;
1329044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
13309ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1331f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1332f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * print out all elements from list
1333044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1334f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx);
13359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1336f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1337044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Cleanup
1338044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1339838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    xmlFreePropList(attrs_to_delete);
13409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlListDelete(list);
13419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (0);
1342044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1343044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1344f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard/**
1345044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NCheckForRelativeNamespaces:
1346044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ctx:		the C14N context
1347044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:		the current element node
1348044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1349044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Checks that current element node has no relative namespaces defined
1350044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1351044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns 0 if the node has no relative namespaces or -1 otherwise.
1352044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1353044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
13549ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
13559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1356044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlNsPtr ns;
13579ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
13589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
13599e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("checking for relative namespaces");
13609ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1361044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
13629ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
13639ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    ns = cur->nsDef;
13649ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    while (ns != NULL) {
13659ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if (xmlStrlen(ns->href) > 0) {
13669ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlURIPtr uri;
13679ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
13689ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            uri = xmlParseURI((const char *) ns->href);
13699ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if (uri == NULL) {
13709e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                xmlC14NErrInternal("parsing namespace uri");
13719ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                return (-1);
13729ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
13739ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {
13749e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                xmlC14NErrRelativeNamespace(uri->scheme);
13759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                xmlFreeURI(uri);
13769ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                return (-1);
13779ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
13789e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            if ((xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "urn") != 0)
13799e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                && (xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "dav") !=0)
13809ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                && (xmlStrlen((const xmlChar *) uri->server) == 0)) {
13819e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                xmlC14NErrRelativeNamespace(uri->scheme);
13829ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                xmlFreeURI(uri);
13839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                return (-1);
13849ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
13859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlFreeURI(uri);
13869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
13879ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        ns = ns->next;
13889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
13899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (0);
1390044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1391044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1392044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
1393044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NProcessElementNode:
1394f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the pointer to C14N context object
1395044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:		the node to process
1396838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @visible:    this node is visible
1397838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @all_parents_visible: whether all the parents of this node are visible
1398f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1399044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
1400044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1401044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Element Nodes
1402f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * If the element is not in the node-set, then the result is obtained
1403f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * by processing the namespace axis, then the attribute axis, then
1404f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * processing the child nodes of the element that are in the node-set
1405f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * (in document order). If the element is in the node-set, then the result
1406f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * is an open angle bracket (<), the element QName, the result of
1407f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * processing the namespace axis, the result of processing the attribute
1408f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * axis, a close angle bracket (>), the result of processing the child
1409f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * nodes of the element that are in the node-set (in document order), an
1410f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * open angle bracket, a forward slash (/), the element QName, and a close
1411044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * angle bracket.
1412044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1413044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns non-negative value on success or negative value on fail
1414044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1415044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
14169ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
14179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1418044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret;
1419f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlC14NVisibleNsStack state;
14206f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard    int parent_is_doc = 0;
1421044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
14229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
14239e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing element node");
14249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
14259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
1426044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1427f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1428044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Check relative relative namespaces:
1429044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * implementations of XML canonicalization MUST report an operation
1430044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * failure on documents containing relative namespace URIs.
1431044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
14329ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {
14339e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("checking for relative namespaces");
14349ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1435044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1436044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1437044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1438f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1439f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin     * Save ns_rendered stack position
1440044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1441aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard    memset(&state, 0, sizeof(state));
1442f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);
14439ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1444f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (visible) {
14459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if (ctx->parent_is_doc) {
14466f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard	    /* save this flag into the stack */
14476f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard	    parent_is_doc = ctx->parent_is_doc;
14486f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard	    ctx->parent_is_doc = 0;
14499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            ctx->pos = XMLC14N_INSIDE_DOCUMENT_ELEMENT;
14509ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
14519ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, "<");
14529ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
14539ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
14549ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlOutputBufferWriteString(ctx->buf,
14559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                       (const char *) cur->ns->prefix);
14569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlOutputBufferWriteString(ctx->buf, ":");
14579ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
14589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
1459f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
14609ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1461838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if (!xmlC14NIsExclusive(ctx)) {
1462f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
1463f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    } else {
1464f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
1465f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
1466f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if (ret < 0) {
14679e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("processing namespaces axis");
1468f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        return (-1);
1469f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
1470f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    /* todo: shouldn't this go to "visible only"? */
1471f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if(visible) {
1472f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	xmlC14NVisibleNsStackShift(ctx->ns_rendered);
1473f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
1474f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
14753ea201cedbe0842eedf3d2216b14cf8d356f8453Aleksey Sanin    ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);
14763ea201cedbe0842eedf3d2216b14cf8d356f8453Aleksey Sanin    if (ret < 0) {
14773ea201cedbe0842eedf3d2216b14cf8d356f8453Aleksey Sanin	xmlC14NErrInternal("processing attributes axis");
1478f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	return (-1);
1479f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
14809ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1481f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    if (visible) {
14829ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, ">");
1483044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1484044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (cur->children != NULL) {
14859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        ret = xmlC14NProcessNodeList(ctx, cur->children);
14869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if (ret < 0) {
14879e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInternal("processing childrens list");
14889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
14899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
1490044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
14919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (visible) {
14929ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, "</");
14939ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
14949ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlOutputBufferWriteString(ctx->buf,
14959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                       (const char *) cur->ns->prefix);
14969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlOutputBufferWriteString(ctx->buf, ":");
14979ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
14989ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
14999ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlOutputBufferWriteString(ctx->buf, ">");
15006f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard        if (parent_is_doc) {
15016f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard	    /* restore this flag from the stack for next node */
15026f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard            ctx->parent_is_doc = parent_is_doc;
15036f293b1cde7c3b52bc8f9c4f453b7d5c683adbbcDaniel Veillard	    ctx->pos = XMLC14N_AFTER_DOCUMENT_ELEMENT;
15049ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
1505044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1506044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1507f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1508f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin     * Restore ns_rendered stack position
1509044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1510f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);
15119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (0);
1512044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1513044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1514044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
1515044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NProcessNode:
1516f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the pointer to C14N context object
1517044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:		the node to process
1518f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1519044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Processes the given node
1520044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1521044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns non-negative value on success or negative value on fail
1522044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1523044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
15249ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
15259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1526044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret = 0;
1527044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int visible;
15289ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
15299ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((ctx == NULL) || (cur == NULL)) {
15309e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing node");
15319ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1532044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1533044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
15342c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    visible = xmlC14NIsVisible(ctx, cur, cur->parent);
15359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    switch (cur->type) {
15369ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ELEMENT_NODE:
15379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            ret = xmlC14NProcessElementNode(ctx, cur, visible);
15389ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
15399ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_CDATA_SECTION_NODE:
15409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_TEXT_NODE:
15419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            /*
15429ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * Text Nodes
1543f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * the string value, except all ampersands are replaced
1544f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * by &amp;, all open angle brackets (<) are replaced by &lt;, all closing
1545f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * angle brackets (>) are replaced by &gt;, and all #xD characters are
15469ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * replaced by &#xD;.
15479ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             */
15489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            /* cdata sections are processed as text nodes */
15499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            /* todo: verify that cdata sections are included in XPath nodes set */
15509ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if ((visible) && (cur->content != NULL)) {
15519ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                xmlChar *buffer;
15529ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
15539ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                buffer = xmlC11NNormalizeText(cur->content);
15549ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (buffer != NULL) {
15559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf,
15569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                               (const char *) buffer);
15579ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlFree(buffer);
15589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                } else {
15599e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                    xmlC14NErrInternal("normalizing text node");
15609ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    return (-1);
15619ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
15629ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
15639ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
15649ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_PI_NODE:
1565f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            /*
1566f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * Processing Instruction (PI) Nodes-
1567f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * The opening PI symbol (<?), the PI target name of the node,
1568f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * a leading space and the string value if it is not empty, and
1569f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * the closing PI symbol (?>). If the string value is empty,
1570f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * then the leading space is not added. Also, a trailing #xA is
1571f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * rendered after the closing PI symbol for PI children of the
1572f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * root node with a lesser document order than the document
1573f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * element, and a leading #xA is rendered before the opening PI
1574f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * symbol of PI children of the root node with a greater document
15759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * order than the document element.
15769ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             */
15779ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if (visible) {
15789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
15799ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "\x0A<?");
15809ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                } else {
15819ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "<?");
15829ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
15839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
15849ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                xmlOutputBufferWriteString(ctx->buf,
15859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                           (const char *) cur->name);
15869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if ((cur->content != NULL) && (*(cur->content) != '\0')) {
15879ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlChar *buffer;
15889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
15899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, " ");
15909ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
15919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    /* todo: do we need to normalize pi? */
15929ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    buffer = xmlC11NNormalizePI(cur->content);
15939ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    if (buffer != NULL) {
15949ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        xmlOutputBufferWriteString(ctx->buf,
15959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                                   (const char *) buffer);
15969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        xmlFree(buffer);
15979ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    } else {
15989e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                        xmlC14NErrInternal("normalizing pi node");
15999ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        return (-1);
16009ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    }
16019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
16029ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16039ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
16049ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "?>\x0A");
16059ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                } else {
16069ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "?>");
16079ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
16089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
16099ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
16109ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_COMMENT_NODE:
16119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            /*
16129ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * Comment Nodes
1613f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * Nothing if generating canonical XML without  comments. For
1614f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * canonical XML with comments, generate the opening comment
1615f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * symbol (<!--), the string value of the node, and the
1616f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * closing comment symbol (-->). Also, a trailing #xA is rendered
1617f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * after the closing comment symbol for comment children of the
1618f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * root node with a lesser document order than the document
1619f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * element, and a leading #xA is rendered before the opening
1620f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * comment symbol of comment children of the root node with a
1621f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * greater document order than the document element. (Comment
1622f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * children of the root node represent comments outside of the
1623f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * top-level document element and outside of the document type
16249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * declaration).
16259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             */
16269ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if (visible && ctx->with_comments) {
16279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
16289ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "\x0A<!--");
16299ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                } else {
16309ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "<!--");
16319ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
16329ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16339ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (cur->content != NULL) {
16349ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlChar *buffer;
16359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16369ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    /* todo: do we need to normalize comment? */
16379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    buffer = xmlC11NNormalizeComment(cur->content);
16389ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    if (buffer != NULL) {
16399ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        xmlOutputBufferWriteString(ctx->buf,
16409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                                   (const char *) buffer);
16419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        xmlFree(buffer);
16429ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    } else {
16439e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin                        xmlC14NErrInternal("normalizing comment node");
16449ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                        return (-1);
16459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    }
16469ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
16479ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
16499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "-->\x0A");
16509ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                } else {
16519ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                    xmlOutputBufferWriteString(ctx->buf, "-->");
16529ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                }
16539ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
16549ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
16559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_DOCUMENT_NODE:
16569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_DOCUMENT_FRAG_NODE:   /* should be processed as document? */
16571840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
16589ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:   /* should be processed as document? */
16591840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#endif
16601840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#ifdef LIBXML_HTML_ENABLED
16619ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_HTML_DOCUMENT_NODE:   /* should be processed as document? */
16621840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#endif
16639ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            if (cur->children != NULL) {
16649ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
16659ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                ctx->parent_is_doc = 1;
16669ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                ret = xmlC14NProcessNodeList(ctx, cur->children);
16679ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            }
16689ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
16699ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16709ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ATTRIBUTE_NODE:
16719e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInvalidNode("XML_ATTRIBUTE_NODE", "processing node");
16729ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
16739ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_NAMESPACE_DECL:
16749e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInvalidNode("XML_NAMESPACE_DECL", "processing node");
16759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
16769ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ENTITY_REF_NODE:
16779e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInvalidNode("XML_ENTITY_REF_NODE", "processing node");
16789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
16799ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ENTITY_NODE:
16809e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInvalidNode("XML_ENTITY_NODE", "processing node");
16819ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
16829ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
16839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_DOCUMENT_TYPE_NODE:
16849ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_NOTATION_NODE:
16859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_DTD_NODE:
16869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ELEMENT_DECL:
16879ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ATTRIBUTE_DECL:
16889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_ENTITY_DECL:
16891840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#ifdef LIBXML_XINCLUDE_ENABLED
16909ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_XINCLUDE_START:
16919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        case XML_XINCLUDE_END:
16921840ef0827005e5460791e5b49427b41359f4620Daniel Veillard#endif
1693f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard            /*
1694f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard             * should be ignored according to "W3C Canonical XML"
16959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             */
16969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            break;
16979ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        default:
16989e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrUnknownNode(cur->type, "processing node");
16999ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
1700044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1701044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
17029ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
1703044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1704044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1705044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
1706044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NProcessNodeList:
1707f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @ctx:		the pointer to C14N context object
1708044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:		the node to start from
1709f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1710044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Processes all nodes in the row starting from cur.
1711044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1712044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns non-negative value on success or negative value on fail
1713044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1714044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic int
17159ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
17169ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1717044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret;
17189ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
17199ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ctx == NULL) {
17209e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("processing node list");
17219ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1722044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1723044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
17249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {
17259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        ret = xmlC14NProcessNode(ctx, cur);
17269ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
17279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
1728044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1729044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1730044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1731044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
1732044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NFreeCtx:
1733044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ctx: the pointer to C14N context object
1734f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1735044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Cleanups the C14N context object.
1736044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1737044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1738044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic void
17399ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NFreeCtx(xmlC14NCtxPtr ctx)
17409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
17419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ctx == NULL) {
17429e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("freeing context");
17439ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return;
1744044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
17459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
17469ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ctx->ns_rendered != NULL) {
1747f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);
1748044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1749044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlFree(ctx);
1750044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1751044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1752044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
1753044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NNewCtx:
1754f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc:		the XML document for canonization
1755f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @is_visible_callback:the function to use to determine is node visible
17562c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			or not
1757f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @user_data:		the first parameter for @is_visible_callback function
17582c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			(in most cases, it is nodes set)
1759838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @mode:   the c14n mode (see @xmlC14NMode)
1760f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @inclusive_ns_prefixe the list of inclusive namespace prefixes
1761044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			ended with a NULL or NULL if there is no
1762f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			inclusive namespaces (only for `
1763044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			canonicalization)
1764f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @with_comments:	include comments in the result (!=0) or not (==0)
1765f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @buf:		the output buffer to store canonical XML; this
1766044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			buffer MUST have encoder==NULL because C14N requires
1767044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			UTF-8 output
1768f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1769044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Creates new C14N context object to store C14N parameters.
1770044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1771044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns pointer to newly created object (success) or NULL (fail)
1772044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1773044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlC14NCtxPtr
1774f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlC14NNewCtx(xmlDocPtr doc,
17752c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	      xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
1776838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin              xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
17779ff8817e67b286f081205000a63a897f788e42abDaniel Veillard              int with_comments, xmlOutputBufferPtr buf)
17789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
1779659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlC14NCtxPtr ctx = NULL;
1780044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
17819ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((doc == NULL) || (buf == NULL)) {
17829e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("creating new context");
17839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
1784044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1785044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1786044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1787044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     *  Validate the encoding output buffer encoding
1788044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
17899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (buf->encoder != NULL) {
1790d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
1791d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard"xmlC14NNewCtx: output buffer encoder != NULL but C14N requires UTF8 output\n");
17929ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
1793044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1794044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1795044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1796044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     *  Validate the XML document encoding value, if provided.
1797044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
17989ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (doc->charset != XML_CHAR_ENCODING_UTF8) {
1799d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
1800d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		   "xmlC14NNewCtx: source document not in UTF8\n");
18019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
18029ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
1803044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1804044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1805044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Allocate a new xmlC14NCtxPtr and fill the fields.
1806044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1807044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx = (xmlC14NCtxPtr) xmlMalloc(sizeof(xmlC14NCtx));
1808044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (ctx == NULL) {
1809d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	xmlC14NErrMemory("creating context");
18109ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
1811044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1812044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    memset(ctx, 0, sizeof(xmlC14NCtx));
1813044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1814044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1815044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * initialize C14N context
18169ff8817e67b286f081205000a63a897f788e42abDaniel Veillard     */
1817044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx->doc = doc;
1818044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx->with_comments = with_comments;
18192c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    ctx->is_visible_callback = is_visible_callback;
18202c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin    ctx->user_data = user_data;
1821044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx->buf = buf;
1822044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx->parent_is_doc = 1;
1823044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
1824f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
1825f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin
1826f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    if(ctx->ns_rendered == NULL) {
1827d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_CREATE_STACK,
1828d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		   "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
1829f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin	xmlC14NFreeCtx(ctx);
1830f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin        return (NULL);
1831f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin    }
1832044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1833044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1834838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin     * Set "mode" flag and remember list of incluseve prefixes
1835838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin     * for exclusive c14n
1836044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1837838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    ctx->mode = mode;
1838838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    if(xmlC14NIsExclusive(ctx)) {
1839044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
1840044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
18419ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ctx);
1842044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1843044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1844044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
18452c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin * xmlC14NExecute:
1846f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc:		the XML document for canonization
1847f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @is_visible_callback:the function to use to determine is node visible
18482c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			or not
1849f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @user_data:		the first parameter for @is_visible_callback function
18502c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			(in most cases, it is nodes set)
1851838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @mode:	the c14n mode (see @xmlC14NMode)
1852f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
1853044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			ended with a NULL or NULL if there is no
1854f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			inclusive namespaces (only for exclusive
1855044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			canonicalization, ignored otherwise)
1856f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @with_comments:	include comments in the result (!=0) or not (==0)
1857f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @buf:		the output buffer to store canonical XML; this
1858044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			buffer MUST have encoder==NULL because C14N requires
1859044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			UTF-8 output
1860f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1861044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Dumps the canonized image of given XML document into the provided buffer.
1862044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
1863044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
1864044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
1865f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Returns non-negative value on success or a negative value on fail
1866044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
1867f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardint
18682c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
1869175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin	 void* user_data, int mode, xmlChar **inclusive_ns_prefixes,
18702c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin	 int with_comments, xmlOutputBufferPtr buf) {
18712c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
1872044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlC14NCtxPtr ctx;
1873175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin    xmlC14NMode c14n_mode = XML_C14N_1_0;
1874044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret;
18759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
18769ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((buf == NULL) || (doc == NULL)) {
18779e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("executing c14n");
18789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1879044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1880044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1881f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /* for backward compatibility, we have to have "mode" as "int"
1882175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin       and here we check that user gives valid value */
1883175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin    switch(mode) {
1884175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin    case XML_C14N_1_0:
1885175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin    case XML_C14N_EXCLUSIVE_1_0:
1886f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    case XML_C14N_1_1:
1887175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin         c14n_mode = (xmlC14NMode)mode;
1888175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin         break;
1889f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    default:
1890175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin        xmlC14NErrParam("invalid mode for executing c14n");
1891175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin        return (-1);
1892175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin    }
1893175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin
1894044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1895044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     *  Validate the encoding output buffer encoding
1896044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
18979ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (buf->encoder != NULL) {
1898d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8,
1899d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard"xmlC14NExecute: output buffer encoder != NULL but C14N requires UTF8 output\n");
19009ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1901044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1902044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1903f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
1904175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin	            c14n_mode, inclusive_ns_prefixes,
1905175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin                    with_comments, buf);
19069ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ctx == NULL) {
1907d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard        xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
1908d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard		   "xmlC14NExecute: unable to create C14N context\n");
19099ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1910044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1911044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1912044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1913044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1914f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1915044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Root Node
1916f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * The root node is the parent of the top-level document element. The
1917f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * result of processing each of its child nodes that is in the node-set
1918f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * in document order. The root node does not generate a byte order mark,
1919f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * XML declaration, nor anything from within the document type
1920044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * declaration.
1921044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
19229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (doc->children != NULL) {
19239ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        ret = xmlC14NProcessNodeList(ctx, doc->children);
19249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if (ret < 0) {
19259e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin            xmlC14NErrInternal("processing docs children list");
19269ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            xmlC14NFreeCtx(ctx);
19279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            return (-1);
19289ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
19299ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
19309ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
1931044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
1932044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Flush buffer to get number of bytes written
1933044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
1934044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ret = xmlOutputBufferFlush(buf);
19359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ret < 0) {
19369e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("flushing output buffer");
19379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        xmlC14NFreeCtx(ctx);
19389ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
1939044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
1940044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1941f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
1942044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Cleanup
1943044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
19449ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlC14NFreeCtx(ctx);
19459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
1946044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
1947044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
1948044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
19492c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin * xmlC14NDocSaveTo:
1950f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc:		the XML document for canonization
1951f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @nodes:		the nodes set to be included in the canonized image
1952f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		or NULL if all document nodes should be included
1953838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @mode:		the c14n mode (see @xmlC14NMode)
1954f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
19552c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			ended with a NULL or NULL if there is no
1956f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			inclusive namespaces (only for exclusive
19572c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			canonicalization, ignored otherwise)
1958f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @with_comments:	include comments in the result (!=0) or not (==0)
1959f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @buf:		the output buffer to store canonical XML; this
19602c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			buffer MUST have encoder==NULL because C14N requires
19612c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *			UTF-8 output
1962f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
19632c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin * Dumps the canonized image of given XML document into the provided buffer.
19642c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
19652c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
19662c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin *
1967f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Returns non-negative value on success or a negative value on fail
19682c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin */
19692c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Saninint
19702c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey SaninxmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
1971838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin                 int mode, xmlChar ** inclusive_ns_prefixes,
19722c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin                 int with_comments, xmlOutputBufferPtr buf) {
1973f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    return(xmlC14NExecute(doc,
19742c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin			(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
19752c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin			nodes,
1976838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin			mode,
19772c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin			inclusive_ns_prefixes,
19782c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin			with_comments,
19792c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin			buf));
19802c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin}
19812c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
19822c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin
19832c135a1cf1aa69e87e0995ad614e8abc5650f54aAleksey Sanin/**
1984044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NDocDumpMemory:
1985f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc:		the XML document for canonization
1986f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @nodes:		the nodes set to be included in the canonized image
1987f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		or NULL if all document nodes should be included
1988838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @mode:		the c14n mode (see @xmlC14NMode)
1989f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
1990044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			ended with a NULL or NULL if there is no
1991f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			inclusive namespaces (only for exclusive
1992044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			canonicalization, ignored otherwise)
1993f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @with_comments:	include comments in the result (!=0) or not (==0)
1994f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc_txt_ptr:	the memory pointer for allocated canonical XML text;
1995044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			the caller of this functions is responsible for calling
1996f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			xmlFree() to free allocated memory
1997f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
1998044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Dumps the canonized image of given XML document into memory.
1999044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
2000044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
2001044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
2002f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Returns the number of bytes written on success or a negative value on fail
2003044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
2004044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardint
20059ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
2006175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin                     int mode, xmlChar ** inclusive_ns_prefixes,
20079ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                     int with_comments, xmlChar ** doc_txt_ptr)
20089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
2009044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret;
2010044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlOutputBufferPtr buf;
2011044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2012044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (doc_txt_ptr == NULL) {
20139e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("dumping doc to memory");
20149ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2015044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
2016044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2017044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    *doc_txt_ptr = NULL;
20189ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
2019044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
2020f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * create memory buffer with UTF8 (default) encoding
2021044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2022044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    buf = xmlAllocOutputBuffer(NULL);
20239ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (buf == NULL) {
20249e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrMemory("creating output buffer");
20259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2026044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
2027044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2028044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
2029044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * canonize document and write to buffer
2030044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2031838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
20329ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                           with_comments, buf);
20339ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ret < 0) {
20349e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("saving doc to output buffer");
20359ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        (void) xmlOutputBufferClose(buf);
20369ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
20379ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    }
20389ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
203953aa293dd3f6ec8f09fcb38cda4467e38c50f22fDaniel Veillard    ret = xmlBufUse(buf->buffer);
20409ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ret > 0) {
204153aa293dd3f6ec8f09fcb38cda4467e38c50f22fDaniel Veillard        *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), ret);
2042044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
20439ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    (void) xmlOutputBufferClose(buf);
2044044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
20459ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if ((*doc_txt_ptr == NULL) && (ret > 0)) {
20469e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrMemory("coping canonicanized document");
20479ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2048044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
20499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
2050044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
2051044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2052044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
2053044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC14NDocSave:
2054f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @doc:		the XML document for canonization
2055f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @nodes:		the nodes set to be included in the canonized image
2056f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		or NULL if all document nodes should be included
2057838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin * @mode:		the c14n mode (see @xmlC14NMode)
2058f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
2059044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			ended with a NULL or NULL if there is no
2060f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			inclusive namespaces (only for exclusive
2061044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *			canonicalization, ignored otherwise)
2062f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @with_comments:	include comments in the result (!=0) or not (==0)
2063f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @filename:		the filename to store canonical XML image
2064f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @compression:	the compression level (zlib requred):
2065044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *				-1 - libxml default,
2066f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *				 0 - uncompressed,
2067044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *				>0 - compression level
2068f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *
2069044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Dumps the canonized image of given XML document into the file.
2070044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
2071044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
2072044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
2073f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Returns the number of bytes written success or a negative value on fail
2074044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
2075044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardint
20769ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
2077175beba061288d777dd3c022885c05500aa3c377Aleksey Sanin               int mode, xmlChar ** inclusive_ns_prefixes,
20789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard               int with_comments, const char *filename, int compression)
20799ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
20809ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    xmlOutputBufferPtr buf;
2081044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int ret;
2082044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
20839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (filename == NULL) {
20849e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrParam("saving doc");
20859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2086044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
2087044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#ifdef HAVE_ZLIB_H
20889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (compression < 0)
20899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        compression = xmlGetCompressMode();
20909ff8817e67b286f081205000a63a897f788e42abDaniel Veillard#endif
2091044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2092f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
2093044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * save the content to a temp buffer, use default UTF8 encoding.
2094044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2095044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
2096044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (buf == NULL) {
20979e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("creating temporary filename");
20989ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2099044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
21009ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
2101044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
2102044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * canonize document and write to buffer
2103044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2104838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
21059ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                           with_comments, buf);
21069ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (ret < 0) {
21079e75e9fe95922a1b7c9f76957ac74bcac85f1517Aleksey Sanin        xmlC14NErrInternal("cannicanize document to buffer");
21089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        (void) xmlOutputBufferClose(buf);
21099ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (-1);
2110044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
21119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
2112f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard    /*
2113f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard     * get the numbers of bytes written
2114044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2115044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    ret = xmlOutputBufferClose(buf);
21169ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (ret);
2117044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
2118044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2119044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2120044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2121044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/*
2122044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Macro used to grow the current buffer.
2123044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
2124044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#define growBufferReentrant() {						\
2125044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    buffer_size *= 2;							\
2126044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    buffer = (xmlChar *)						\
2127f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard		xmlRealloc(buffer, buffer_size * sizeof(xmlChar));	\
2128044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (buffer == NULL) {						\
2129d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	xmlC14NErrMemory("growing buffer");				\
2130044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return(NULL);							\
2131044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }									\
2132044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
2133044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2134f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard/**
2135044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlC11NNormalizeString:
2136044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @input:		the input string
2137044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @mode:		the normalization mode (attribute, comment, PI or text)
2138044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
2139044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Converts a string to a canonical (normalized) format. The code is stolen
2140044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * from xmlEncodeEntitiesReentrant(). Added normalization of \x09, \x0a, \x0A
2141044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * and the @mode parameter
2142044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
2143044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns a normalized string (caller is responsible for calling xmlFree())
2144044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * or NULL if an error occurs
2145044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
2146044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlChar *
21479ff8817e67b286f081205000a63a897f788e42abDaniel VeillardxmlC11NNormalizeString(const xmlChar * input,
21489ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                       xmlC14NNormalizationMode mode)
21499ff8817e67b286f081205000a63a897f788e42abDaniel Veillard{
2150044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    const xmlChar *cur = input;
2151044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlChar *buffer = NULL;
2152044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlChar *out = NULL;
2153044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int buffer_size = 0;
2154044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
21559ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    if (input == NULL)
21569ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
2157044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2158044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
2159044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * allocate an translation buffer.
2160044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
2161044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    buffer_size = 1000;
21623c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
2163044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (buffer == NULL) {
2164d96cce1abe2cd10f10074e07c56520fbbba9f3efDaniel Veillard	xmlC14NErrMemory("allocating buffer");
21659ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        return (NULL);
2166044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
2167044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    out = buffer;
2168044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
2169044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    while (*cur != '\0') {
21709ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if ((out - buffer) > (buffer_size - 10)) {
21719ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            int indx = out - buffer;
21729ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
21739ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            growBufferReentrant();
21749ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            out = &buffer[indx];
21759ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
21769ff8817e67b286f081205000a63a897f788e42abDaniel Veillard
21779ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        if ((*cur == '<') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
21789ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                              (mode == XMLC14N_NORMALIZE_TEXT))) {
21799ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
21809ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'l';
21819ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 't';
21829ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
21839ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '>') && (mode == XMLC14N_NORMALIZE_TEXT)) {
21849ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
21859ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'g';
21869ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 't';
21879ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
21889ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '&') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
21899ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                     (mode == XMLC14N_NORMALIZE_TEXT))) {
21909ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
21919ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'a';
21929ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'm';
21939ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'p';
21949ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
21959ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '"') && (mode == XMLC14N_NORMALIZE_ATTR)) {
21969ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
21979ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'q';
21989ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'u';
21999ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'o';
22009ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 't';
22019ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
22029ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '\x09') && (mode == XMLC14N_NORMALIZE_ATTR)) {
22039ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
22049ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '#';
22059ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'x';
22069ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '9';
22079ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
22089ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '\x0A') && (mode == XMLC14N_NORMALIZE_ATTR)) {
22099ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
22109ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '#';
22119ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'x';
22129ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'A';
22139ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
22149ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else if ((*cur == '\x0D') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
22159ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                        (mode == XMLC14N_NORMALIZE_TEXT) ||
22169ff8817e67b286f081205000a63a897f788e42abDaniel Veillard                                        (mode == XMLC14N_NORMALIZE_COMMENT) ||
22179ff8817e67b286f081205000a63a897f788e42abDaniel Veillard					(mode == XMLC14N_NORMALIZE_PI))) {
22189ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '&';
22199ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = '#';
22209ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'x';
22219ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = 'D';
22229ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = ';';
22239ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        } else {
22249ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            /*
22259ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * Works because on UTF-8, all extended sequences cannot
22269ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             * result in bytes in the ASCII range.
22279ff8817e67b286f081205000a63a897f788e42abDaniel Veillard             */
22289ff8817e67b286f081205000a63a897f788e42abDaniel Veillard            *out++ = *cur;
22299ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        }
22309ff8817e67b286f081205000a63a897f788e42abDaniel Veillard        cur++;
2231044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
223213cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard    *out = 0;
22339ff8817e67b286f081205000a63a897f788e42abDaniel Veillard    return (buffer);
2234044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
2235a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
22365d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_c14n
22375d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
2238044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#endif /* LIBXML_C14N_ENABLED */
2239