added merlin-c14n-two.tar.gz tests for c14n/exc-c14n and slightly modified
* result/c14n/exc-without-comments/merlin-c14n-two-*
result/c14n/without-comments/merlin-c14n-two-*
test/c14n/exc-without-comments/merlin-c14n-two-*
test/c14n/without-comments/merlin-c14n-two-*
testC14N.c Makefile.am: added merlin-c14n-two.tar.gz tests for
c14n/exc-c14n and slightly modified test script to handle
these test cases
* c14n.c: fixed bugs for complicated nodes set (namespace
without node and others from merlin-c14n-two.tar.gz)
* include/libxml/xpathInternals.h win32/dsp/libxml2.def.src
win32/libxml2.def.src: "opened" xmlXPathNodeSetFreeNs() function
for xmlsec performance patch
* xpath.c: fixed self::node() for namespaces and attributes
diff --git a/c14n.c b/c14n.c
index 3ab4a2f..9d42fa3 100644
--- a/c14n.c
+++ b/c14n.c
@@ -38,12 +38,25 @@
XMLC14N_AFTER_DOCUMENT_ELEMENT = 2
} xmlC14NPosition;
-typedef struct _xmlC14NNamespaces {
- int nsNr; /* number of nodes in the set */
+typedef struct _xmlC14NVisibleNsStack {
+ int nsCurEnd; /* number of nodes in the set */
+ int nsPrevStart; /* the begginning of the stack for previous visible node */
+ int nsPrevEnd; /* the end of the stack for previous visible node */
int nsMax; /* size of the array as allocated */
- int nsPos; /* the begginning of the stack for this node */
xmlNsPtr *nsTab; /* array of nodes in no particular order */
-} xmlC14NNamespaces, *xmlC14NNamespacesPtr;
+} xmlC14NVisibleNsStack, *xmlC14NVisibleNsStackPtr;
+static xmlC14NVisibleNsStackPtr xmlC14NVisibleNsStackCreate (void);
+static void xmlC14NVisibleNsStackDestroy (xmlC14NVisibleNsStackPtr cur);
+static void xmlC14NVisibleNsStackAdd (xmlC14NVisibleNsStackPtr cur,
+ xmlNsPtr ns);
+static void xmlC14NVisibleNsStackSave (xmlC14NVisibleNsStackPtr cur,
+ xmlC14NVisibleNsStackPtr state);
+static void xmlC14NVisibleNsStackRestore (xmlC14NVisibleNsStackPtr cur,
+ xmlC14NVisibleNsStackPtr state);
+static void xmlC14NVisibleNsStackShift (xmlC14NVisibleNsStackPtr cur);
+static int xmlC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur,
+ xmlNsPtr ns,
+ int exclusive);
typedef struct _xmlC14NCtx {
/* input parameters */
@@ -55,7 +68,7 @@
/* position in the XML document */
xmlC14NPosition pos;
int parent_is_doc;
- xmlC14NNamespacesPtr ns_rendered;
+ xmlC14NVisibleNsStackPtr ns_rendered;
/* exclusive canonicalization */
int exclusive;
@@ -91,36 +104,45 @@
************************************************************************/
#define XML_NAMESPACES_DEFAULT 16
-static xmlC14NNamespacesPtr
-xmlC14NNamespacesCreate() {
- xmlC14NNamespacesPtr ret;
+static xmlC14NVisibleNsStackPtr
+xmlC14NVisibleNsStackCreate(void) {
+ xmlC14NVisibleNsStackPtr ret;
- ret = (xmlC14NNamespacesPtr) xmlMalloc(sizeof(xmlC14NNamespaces));
+ ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNamespacesCreate: out of memory\n");
+ "xmlC14NVisibleNsStackCreate: out of memory\n");
return(NULL);
}
- memset(ret, 0 , (size_t) sizeof(xmlC14NNamespaces));
+ memset(ret, 0 , (size_t) sizeof(xmlC14NVisibleNsStack));
return(ret);
}
static void
-xmlC14NNamespacesDestroy(xmlC14NNamespacesPtr cur) {
+xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
if(cur == NULL) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackAdd: cur is null.\n");
+#endif
return;
}
if(cur->nsTab != NULL) {
memset(cur->nsTab, 0, cur->nsMax * sizeof(xmlNsPtr));
xmlFree(cur->nsTab);
}
- memset(cur, 0, sizeof(xmlC14NNamespaces));
+ memset(cur, 0, sizeof(xmlC14NVisibleNsStack));
xmlFree(cur);
}
-static void xmlC14NNamespacesAdd(xmlC14NNamespacesPtr cur, xmlNsPtr ns) {
- if((cur == NULL) || (ns == NULL)) {
+static void
+xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns) {
+ if(cur == NULL) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackAdd: cur is null.\n");
+#endif
return;
}
@@ -128,12 +150,12 @@
cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
if (cur->nsTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNamespacesAdd: out of memory\n");
+ "xmlC14NVisibleNsStackAdd: out of memory\n");
return;
}
memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
cur->nsMax = XML_NAMESPACES_DEFAULT;
- } else if(cur->nsMax == cur->nsNr) {
+ } else if(cur->nsMax == cur->nsCurEnd) {
xmlNsPtr *tmp;
int tmpSize;
@@ -141,13 +163,111 @@
tmp = (xmlNsPtr*) xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
if (tmp == NULL) {
xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNamespacesAdd: out of memory\n");
+ "xmlC14NVisibleNsStackAdd: out of memory\n");
return;
}
cur->nsTab = tmp;
cur->nsMax = tmpSize;
}
- cur->nsTab[cur->nsNr++] = ns;
+ cur->nsTab[cur->nsCurEnd++] = ns;
+}
+
+static void
+xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
+ if((cur == NULL) || (state == NULL)) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackSave: cur or state is null.\n");
+#endif
+ return;
+ }
+
+ state->nsCurEnd = cur->nsCurEnd;
+ state->nsPrevStart = cur->nsPrevStart;
+ state->nsPrevEnd = cur->nsPrevEnd;
+}
+
+static void
+xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
+ if((cur == NULL) || (state == NULL)) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackRestore: cur or state is null.\n");
+#endif
+ return;
+ }
+ cur->nsCurEnd = state->nsCurEnd;
+ cur->nsPrevStart = state->nsPrevStart;
+ cur->nsPrevEnd = state->nsPrevEnd;
+}
+
+static void
+xmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
+ if(cur == NULL) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackRestore: cur is null.\n");
+#endif
+ return;
+ }
+ cur->nsPrevStart = cur->nsPrevEnd;
+ cur->nsPrevEnd = cur->nsCurEnd;
+}
+
+static int
+xmlC14NStrEqual(const xmlChar *str1, const xmlChar *str2) {
+ if (str1 == str2) return(1);
+ if (str1 == NULL) return((*str2) == '\0');
+ if (str2 == NULL) return((*str1) == '\0');
+ do {
+ if (*str1++ != *str2) return(0);
+ } while (*str2++);
+ return(1);
+}
+
+/**
+ * xmlC14NVisibleNsStackFind:
+ * @ctx the C14N context
+ * @ns the namespace to check
+ *
+ * Checks whether the given namespace was already rendered or not
+ *
+ * Returns 1 if we already wrote this namespace or 0 otherwise
+ */
+static int
+xmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, int exclusive)
+{
+ int i;
+ const xmlChar *prefix;
+ const xmlChar *href;
+ int emptyNs;
+
+ if(cur == NULL) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NVisibleNsStackFind: cur is null.\n");
+#endif
+ return (0);
+ }
+
+ /*
+ * if the default namespace xmlns="" is not defined yet then
+ * we do not want to print it out
+ */
+ prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
+ href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
+ emptyNs = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
+ if (cur->nsTab != NULL) {
+ int start = (exclusive || emptyNs) ? 0 : cur->nsPrevStart;
+ for (i = cur->nsCurEnd - 1; i >= start; --i) {
+ xmlNsPtr ns1 = cur->nsTab[i];
+
+ if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
+ return(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL));
+ }
+ }
+ }
+ return(emptyNs);
}
@@ -179,6 +299,30 @@
return (1);
}
+static int
+xmlC14NIsNsVisible(xmlC14NCtxPtr ctx, xmlNsPtr ns, xmlNodePtr cur)
+{
+ xmlNs ns1;
+
+ if(ns == NULL) {
+ return(1);
+ }
+ memcpy(&ns1, ns, sizeof(ns1));
+ ns1.next = (xmlNsPtr)cur;
+
+ /*
+ * If the input is an XPath node-set, then the node-set must explicitly
+ * contain every node to be rendered to the canonical form.
+ */
+ if ((ctx->visible_nodes != NULL) &&
+ (!xmlXPathNodeSetContains(ctx->visible_nodes, (xmlNodePtr) &ns1)))
+ {
+ return (0);
+ }
+
+ return (1);
+}
+
/**
* xmlC14NIsXmlNs:
* @ns: the namespace to check
@@ -200,45 +344,9 @@
"http://www.w3.org/XML/1998/namespace")));
}
-/**
- * xmlExcC14NIsRendered:
- * @ctx the C14N context
- * @ns the namespace to check
- *
- * Checks whether the given namespace was already rendered or not
- *
- * Returns 1 if we already wrote this namespace or 0 otherwise
- */
-static int
-xmlExcC14NIsRendered(xmlC14NCtxPtr ctx, xmlNsPtr ns)
-{
- int i;
- int emptyNs;
-
- if ((ctx == NULL) || (ctx->ns_rendered == NULL) || (ns == NULL)) {
- return (0);
- }
-
- /*
- * if the default namespace xmlns="" is not defined yet then
- * we do not want to print it out
- */
- emptyNs = ((xmlStrlen(ns->prefix) == 0) && (xmlStrlen(ns->href) == 0));
- if (ctx->ns_rendered->nsTab != NULL) {
- int pos = (emptyNs) ? 0 : ctx->ns_rendered->nsPos;
- for (i = ctx->ns_rendered->nsNr - 1; i >= pos; --i) {
- xmlNsPtr ns1 = ctx->ns_rendered->nsTab[i];
-
- if (xmlStrEqual(ns1->prefix, ns->prefix)) {
- return (xmlStrEqual(ns1->href, ns->href));
- }
- }
- }
- return(emptyNs);
-}
/**
- * xmlC14NNamespacesCompare:
+ * xmlC14NNsCompare:
* @ns1: the pointer to first namespace
* @ns2: the pointer to second namespace
*
@@ -247,7 +355,7 @@
* Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2.
*/
static int
-xmlC14NNamespacesCompare(xmlNsPtr ns1, xmlNsPtr ns2)
+xmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2)
{
if (ns1 == ns2)
return (0);
@@ -288,7 +396,9 @@
} else {
xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");
}
- xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
+ if(ns->href != NULL) {
+ xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
+ }
xmlOutputBufferWriteString(ctx->buf, "\"");
return (1);
}
@@ -333,7 +443,7 @@
* Returns 0 on success or -1 on fail.
*/
static int
-xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
{
xmlNsPtr ns;
xmlListPtr list;
@@ -350,7 +460,7 @@
* Create a sorted list to store element namespaces
*/
list =
- xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNamespacesCompare);
+ xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
if (list == NULL) {
#ifdef DEBUG_C14N
xmlGenericError(xmlGenericErrorContext,
@@ -374,30 +484,56 @@
}
}
} else {
+ xmlNodePtr node;
int i;
+ int emptyNs = 0;
/*
* All visible namespace nodes are in the nodes set
*/
for(i = 0; i < ctx->visible_nodes->nodeNr; i++) {
- if(ctx->visible_nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
- ns = (xmlNsPtr) ctx->visible_nodes->nodeTab[i];
+ node = ctx->visible_nodes->nodeTab[i];
+ if((node != NULL) && (node->type == XML_NAMESPACE_DECL)) {
+ ns = (xmlNsPtr)node;
- if((ns != NULL) && (ns->next == (xmlNsPtr)cur) && !xmlC14NIsXmlNs(ns)) {
- if(!xmlExcC14NIsRendered(ctx, ns)) {
+ if(((xmlNodePtr)(ns->next) == cur) && !xmlC14NIsXmlNs(ns)) {
+ if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns, 0)) {
xmlListInsert(list, ns);
}
- xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
+ if(visible) {
+ xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns);
+ }
+ if(xmlStrlen(ns->prefix) == 0) {
+ emptyNs = 1;
+ }
}
}
}
+
+ /**
+ * if the first node is not the default namespace node (a node with no
+ * namespace URI and no local name), then generate a space followed by
+ * xmlns="" if and only if the following conditions are met:
+ * - the element E that owns the axis is in the node-set
+ * - the nearest ancestor element of E in the node-set has a default
+ * namespace node in the node-set (default namespace nodes always
+ * have non-empty values in XPath)
+ */
+ if(visible && !emptyNs) {
+ xmlNs ns1;
+
+ memset(&ns1, 0, sizeof(ns1));
+ if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns1, 0)) {
+ xmlC14NPrintNamespaces(&ns1, ctx);
+ }
+ }
}
-
+
+
/*
* print out all elements from list
*/
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces,
- (const void *) ctx);
+ xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
/*
* Cleanup
@@ -438,11 +574,13 @@
* Returns 0 on success or -1 on fail.
*/
static int
-xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
{
xmlListPtr list;
xmlAttrPtr attr;
xmlNsPtr ns;
+ xmlNs default_ns;
+
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
#ifdef DEBUG_C14N
@@ -452,7 +590,7 @@
return (-1);
}
- if ((!ctx->exclusive) || (ctx->ns_rendered == NULL)) {
+ if(!ctx->exclusive) {
#ifdef DEBUG_C14N
xmlGenericError(xmlGenericErrorContext,
"xmlExcC14NProcessNamespacesAxis: called for non-exclusive canonization or rendered stack is NULL.\n");
@@ -460,12 +598,12 @@
return (-1);
}
+ memset(&default_ns, 0, sizeof(default_ns));
/*
* Create a sorted list to store element namespaces
*/
- list =
- xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNamespacesCompare);
+ list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
if (list == NULL) {
#ifdef DEBUG_C14N
xmlGenericError(xmlGenericErrorContext,
@@ -480,13 +618,19 @@
* we also need to check for default "xml:" namespace
* todo: shouldn't we check for namespaces "visibility"?
*/
- ns = (cur->ns != NULL) ? cur->ns : xmlSearchNs(ctx->doc, cur, NULL);
- if ((ns != NULL) && (!xmlC14NIsXmlNs(ns)) && (xmlListSearch(list, ns) == NULL)) {
- if(!xmlExcC14NIsRendered(ctx, ns)) {
- xmlListInsert(list, ns);
+ if(visible) {
+ ns = (cur->ns != NULL) ? cur->ns : xmlSearchNs(ctx->doc, cur, NULL);
+ if ((ns != NULL) && (!xmlC14NIsXmlNs(ns)) && (xmlListSearch(list, ns) == NULL) &&
+ xmlC14NIsNsVisible(ctx, ns, cur)) {
+ if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns, 1)) {
+ xmlListInsert(list, ns);
+ }
+ if(visible) {
+ xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns);
+ }
}
- xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
}
+
attr = cur->properties;
while (attr != NULL) {
/*
@@ -495,11 +639,14 @@
* do not apply directly to attributes")
*/
if ((attr->ns != NULL) && xmlC14NIsVisible(ctx, attr) &&
+ xmlC14NIsNsVisible(ctx, attr->ns, cur) &&
(!xmlC14NIsXmlNs(attr->ns)) && (xmlListSearch(list, attr->ns) == NULL)) {
- if(!xmlExcC14NIsRendered(ctx, attr->ns)) {
+ if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, 1)) {
xmlListInsert(list, attr->ns);
}
- xmlC14NNamespacesAdd(ctx->ns_rendered, attr->ns);
+ if(visible) {
+ xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns);
+ }
}
attr = attr->next;
}
@@ -521,12 +668,21 @@
prefix = NULL;
}
ns = xmlSearchNs(ctx->doc, cur, prefix);
- if ((ns != NULL) && (!xmlC14NIsXmlNs(ns))) {
- if (xmlListSearch(list, ns) == NULL) {
- if(!xmlExcC14NIsRendered(ctx, ns)) {
+ if((ns != NULL) && (!xmlC14NIsXmlNs(ns))) {
+ int ns_visible = xmlC14NIsNsVisible(ctx, ns, cur);
+
+ if(!ns_visible && (prefix == NULL)) {
+ ns = &default_ns;
+ ns_visible = 1;
+ }
+ if (ns_visible) {
+ if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns, 1)) {
xmlListInsert(list, ns);
}
- xmlC14NNamespacesAdd(ctx->ns_rendered, ns);
+ if(visible) {
+ xmlC14NVisibleNsStackAdd(ctx->ns_rendered,
+ (ns == &default_ns) ? NULL : ns);
+ }
}
}
}
@@ -535,8 +691,7 @@
/*
* print out all elements from list
*/
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces,
- (const void *) ctx);
+ xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
/*
* Cleanup
@@ -548,7 +703,7 @@
/**
* xmlC14NAttrsCompare:
- * @attr1: the pointer to first attr
+ * @attr1: the pointer tls o first attr
* @attr2: the pointer to second attr
*
* Prints the given attribute to the output buffer from C14N context.
@@ -748,8 +903,7 @@
/*
* print out all elements from list
*/
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs,
- (const void *) ctx);
+ xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx);
/*
* Cleanup
@@ -836,8 +990,7 @@
xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
{
int ret;
- int ns_rendered_pos = 0;
- int ns_rendered_nr = 0;
+ xmlC14NVisibleNsStack state;
int parent_is_doc = 0;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
@@ -863,13 +1016,9 @@
/*
- * Save ns_rendered stack position for exclusive
- * processing
+ * Save ns_rendered stack position
*/
- if (ctx->ns_rendered != NULL) {
- ns_rendered_pos = ctx->ns_rendered->nsPos;
- ns_rendered_nr = ctx->ns_rendered->nsNr;
- }
+ xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);
if (visible) {
if (ctx->parent_is_doc) {
@@ -886,32 +1035,37 @@
xmlOutputBufferWriteString(ctx->buf, ":");
}
xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
+ }
- if (ctx->exclusive) {
- ret = xmlExcC14NProcessNamespacesAxis(ctx, cur);
- } else {
- ret = xmlC14NProcessNamespacesAxis(ctx, cur);
- }
- if (ret < 0) {
+ if (!ctx->exclusive) {
+ ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
+ } else {
+ ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
+ }
+ if (ret < 0) {
#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NProcessNamespacesAxis failed.\n");
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NProcessElementNode: xmlC14NProcessNamespacesAxis failed.\n");
#endif
- return (-1);
- }
- if (ctx->ns_rendered != NULL) {
- ctx->ns_rendered->nsPos = ns_rendered_nr;
+ return (-1);
+ }
+ /* todo: shouldn't this go to "visible only"? */
+ if(visible) {
+ xmlC14NVisibleNsStackShift(ctx->ns_rendered);
+ }
+
+ if(visible) {
+ ret = xmlC14NProcessAttrsAxis(ctx, cur);
+ if (ret < 0) {
+#ifdef DEBUG_C14N
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NProcessElementNode: xmlC14NProcessAttrsAxis failed.\n");
+#endif
+ return (-1);
}
+ }
- ret = xmlC14NProcessAttrsAxis(ctx, cur);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NProcessAttrsAxis failed.\n");
-#endif
- return (-1);
- }
-
+ if (visible) {
xmlOutputBufferWriteString(ctx->buf, ">");
}
if (cur->children != NULL) {
@@ -941,13 +1095,9 @@
}
/*
- * Restore ns_rendered stack position for exclusive
- * processing
+ * Restore ns_rendered stack position
*/
- if (ctx->ns_rendered != NULL) {
- ctx->ns_rendered->nsPos = ns_rendered_pos;
- ctx->ns_rendered->nsNr = ns_rendered_nr;
- }
+ xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);
return (0);
}
@@ -1210,7 +1360,7 @@
}
if (ctx->ns_rendered != NULL) {
- xmlC14NNamespacesDestroy(ctx->ns_rendered);
+ xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);
}
xmlFree(ctx);
}
@@ -1288,7 +1438,14 @@
ctx->buf = buf;
ctx->parent_is_doc = 1;
ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
- ctx->ns_rendered = xmlC14NNamespacesCreate();
+ ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
+
+ if(ctx->ns_rendered == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
+ xmlC14NFreeCtx(ctx);
+ return (NULL);
+ }
/*
* Set "exclusive" flag, create a nodes set for namespaces