[xml] c14n 1.1 support (patch)
- From: Aleksey Sanin <aleksey aleksey com>
- To: xml gnome org
- Subject: [xml] c14n 1.1 support (patch)
- Date: Thu, 25 Jun 2009 20:06:41 -0000
Daniel,
Please find attached a patch that adds support for the new
version of c14n (http://www.w3.org/TR/xml-c14n11/). I am
getting questions about it in the xmlsec mailing list and
I finally decided to implement it. I would greatly appreciate
if you can accept this patch and push it into the gnome git
repository (note, that there are some new files/folders added
for the new test cases).
Thank you in advance,
Aleksey Sanin
diff --git a/Makefile.am b/Makefile.am
index 800a766..236c26b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -923,7 +923,7 @@ VTimingtests: xmllint$(EXEEXT)
C14Ntests : testC14N$(EXEEXT)
@echo "## C14N and XPath regression tests"
- -@(for m in with-comments without-comments exc-without-comments ; do \
+ -@(for m in with-comments without-comments 1-1-without-comments exc-without-comments ; do \
for i in $(srcdir)/test/c14n/$$m/*.xml ; do \
if [ ! -d $$i ] ; then \
name=`basename $$i .xml`; \
diff --git a/c14n.c b/c14n.c
index f333297..5ebaeca 100644
--- a/c14n.c
+++ b/c14n.c
@@ -60,9 +60,11 @@ typedef struct _xmlC14NCtx {
xmlC14NPosition pos;
int parent_is_doc;
xmlC14NVisibleNsStackPtr ns_rendered;
+
+ /* C14N mode */
+ xmlC14NMode mode;
/* exclusive canonicalization */
- int exclusive;
xmlChar **inclusive_ns_prefixes;
/* error number */
@@ -91,8 +93,8 @@ static int xmlC14NIsNodeInNodeset (xmlNodeSetPtr nodes,
-static int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur);
-static int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur);
+static int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int all_parents_visible);
+static int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur, int all_parents_visible);
typedef enum {
XMLC14N_NORMALIZE_ATTR = 0,
XMLC14N_NORMALIZE_COMMENT = 1,
@@ -117,6 +119,9 @@ static xmlChar *xmlC11NNormalizeString(const xmlChar * input,
(ctx)->is_visible_callback((ctx)->user_data, \
(xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
+#define xmlC14NIsExclusive( ctx ) \
+ ( (ctx)->mode == XML_C14N_EXCLUSIVE_1_0 )
+
/************************************************************************
* *
* Some factorized error routines *
@@ -492,9 +497,7 @@ xmlC14NIsXmlNs(xmlNsPtr ns)
{
return ((ns != NULL) &&
(xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
- (xmlStrEqual(ns->href,
- BAD_CAST
- "http://www.w3.org/XML/1998/namespace")));
+ (xmlStrEqual(ns->href, XML_XML_NAMESPACE)));
}
@@ -713,7 +716,7 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
return (-1);
}
- if(!ctx->exclusive) {
+ if(!xmlC14NIsExclusive(ctx)) {
xmlC14NErrParam("processing namespaces axis (exc c14n)");
return (-1);
@@ -845,6 +848,25 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
/**
+ * xmlC14NIsXmlAttr:
+ * @attr: the attr to check
+ *
+ * Checks whether the given attribute is a default "xml:" namespace
+ * with href="http://www.w3.org/XML/1998/namespace"
+ *
+ * Returns 1 if the node is default or 0 otherwise
+ */
+
+/* todo: make it a define? */
+static int
+xmlC14NIsXmlAttr(xmlAttrPtr attr)
+{
+ return ((attr->ns != NULL) &&
+ (xmlC14NIsXmlNs(attr->ns) != 0));
+}
+
+
+/**
* xmlC14NAttrsCompare:
* @attr1: the pointer tls o first attr
* @attr2: the pointer to second attr
@@ -925,7 +947,7 @@ xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
xmlOutputBufferWriteString(ctx->buf, "=\"");
- value = xmlNodeListGetString(attr->doc, attr->children, 1);
+ value = xmlNodeListGetString(ctx->doc, attr->children, 1);
/* todo: should we log an error if value==NULL ? */
if (value != NULL) {
buffer = xmlC11NNormalizeAttr(value);
@@ -942,11 +964,125 @@ xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
return (1);
}
+
+/**
+ * xmlC14NAttrsCompare:
+ * @attr1: the pointer tls o first attr
+ * @attr2: the pointer to second attr
+ *
+ * Prints the given attribute to the output buffer from C14N context.
+ *
+ * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2.
+ */
+static xmlAttrPtr
+xmlC14NFindParentAttr(xmlNodePtr cur, const xmlChar * name, const xmlChar * ns)
+{
+ xmlAttrPtr res;
+ while(cur != NULL) {
+ res = xmlHasNsProp(cur, name, ns);
+ if(res != NULL) {
+ return res;
+ }
+
+ cur = cur->parent;
+ }
+
+ return NULL;
+}
+
+/**
+ * xmlC14NFixupBaseAttr:
+ *
+ * Fixes up the xml:base attribute
+ *
+ * Returns the newly created attribute or NULL
+ */
+static xmlAttrPtr
+xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
+{
+ xmlChar * res = NULL;
+ xmlNodePtr cur;
+ xmlAttrPtr attr;
+ xmlChar * tmp_str;
+ xmlChar * tmp_str2;
+
+ if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
+ xmlC14NErrParam("processing xml:base attribute");
+ return (NULL);
+ }
+
+ /* start from current value */
+ res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
+ if(res == NULL) {
+ xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ return (NULL);
+ }
+
+ /* go up the stack */
+ cur = xml_base_attr->parent->parent;
+ while(cur != NULL) {
+ attr = xmlHasNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+ if(attr != NULL){
+ /* check if we found a visible xml:base attribute and stop */
+ if(xmlC14NIsVisible(ctx, attr, cur)) {
+ break;
+ }
+
+ /* get attr value */
+ tmp_str = xmlNodeListGetString(ctx->doc, attr->children, 1);
+ if(tmp_str == NULL) {
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ return (NULL);
+ }
+
+ /* build uri */
+ tmp_str2 = xmlBuildURI(res, tmp_str);
+ if(tmp_str2 == NULL) {
+ xmlFree(tmp_str);
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
+ return (NULL);
+ }
+
+ /* cleanup and set the new res */
+ xmlFree(tmp_str);
+ xmlFree(res);
+ res = tmp_str2;
+ }
+
+ /* next */
+ cur = cur->parent;
+ }
+
+ /* check if result uri is empty or not */
+ if((res == NULL) || xmlStrEqual(res, BAD_CAST "")) {
+ xmlFree(res);
+ return (NULL);
+ }
+
+ /* create and return the new attribute node */
+ attr = xmlNewNsProp(NULL, xml_base_attr->ns, BAD_CAST "base", res);
+ if(attr == NULL) {
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
+ return (NULL);
+ }
+
+ /* done */
+ xmlFree(res);
+ return (attr);
+}
+
/**
* xmlC14NProcessAttrsAxis:
* @ctx: the C14N context
* @cur: the current node
* @parent_visible: the visibility of parent node
+ * @all_parents_visible: the visibility of all parent nodes
*
* Prints out canonical attribute axis of the current node to the
* buffer from C14N context as follows
@@ -975,10 +1111,16 @@ xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
* Returns 0 on success or -1 on fail.
*/
static int
-xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
+xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible, int all_parents_visible)
{
xmlAttrPtr attr;
- xmlListPtr list;
+ xmlListPtr list;
+ xmlAttrPtr attrs_to_delete = NULL;
+
+ /* special processing for 1.1 spec */
+ xmlAttrPtr xml_base_attr = NULL;
+ xmlAttrPtr xml_lang_attr = NULL;
+ xmlAttrPtr xml_space_attr = NULL;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
xmlC14NErrParam("processing attributes axis");
@@ -994,42 +1136,183 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
return (-1);
}
- /*
- * Add all visible attributes from current node.
- */
- attr = cur->properties;
- while (attr != NULL) {
- /* check that attribute is visible */
- if (xmlC14NIsVisible(ctx, attr, cur)) {
- xmlListInsert(list, attr);
+ switch(ctx->mode) {
+ case XML_C14N_1_0:
+ /* The processing of an element node E MUST be modified slightly when an XPath node-set is
+ * given as input and the element's parent is omitted from the node-set. The method for processing
+ * the attribute axis of an element E in the node-set is enhanced. All element nodes along E's
+ * ancestor axis are examined for nearest occurrences of attributes in the xml namespace, such
+ * as xml:lang and xml:space (whether or not they are in the node-set). From this list of
attributes,
+ * remove any that are in E's attribute axis (whether or not they are in the node-set). Then,
+ * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
+ * the node-set. The result of visiting the attribute axis is computed by processing the attribute
+ * nodes in this merged attribute list.
+ */
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ attr = attr->next;
}
- attr = attr->next;
- }
- /*
- * include attributes in "xml" namespace defined in ancestors
- * (only for non-exclusive XML Canonicalization)
- */
- if (parent_visible && (!ctx->exclusive) && (cur->parent != NULL)
- && (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) {
- /*
- * If XPath node-set is not specified then the parent is always
- * visible!
+ /*
+ * Handle xml attributes
*/
- cur = cur->parent;
- while (cur != NULL) {
- attr = cur->properties;
- while (attr != NULL) {
- if ((attr->ns != NULL)
- && (xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {
- if (xmlListSearch(list, attr) == NULL) {
- xmlListInsert(list, attr);
+ if (parent_visible && (cur->parent != NULL) &&
+ (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent)))
+ {
+ xmlNodePtr tmp;
+
+ /*
+ * If XPath node-set is not specified then the parent is always
+ * visible!
+ */
+ tmp = cur->parent;
+ while (tmp != NULL) {
+ attr = tmp->properties;
+ while (attr != NULL) {
+ if (xmlC14NIsXmlAttr(attr) != 0) {
+ if (xmlListSearch(list, attr) == NULL) {
+ xmlListInsert(list, attr);
+ }
}
+ attr = attr->next;
}
- attr = attr->next;
+ tmp = tmp->parent;
}
- cur = cur->parent;
}
+
+ /* done */
+ break;
+ case XML_C14N_EXCLUSIVE_1_0:
+ /* attributes in the XML namespace, such as xml:lang and xml:space
+ * are not imported into orphan nodes of the document subset
+ */
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ attr = attr->next;
+ }
+
+ /* do nothing special for xml attributes */
+ break;
+ case XML_C14N_1_1:
+ /* The processing of an element node E MUST be modified slightly when an XPath node-set is
+ * given as input and some of the element's ancestors are omitted from the node-set.
+ *
+ * Simple inheritable attributes are attributes that have a value that requires at most a simple
+ * redeclaration. This redeclaration is done by supplying a new value in the child axis. The
+ * redeclaration of a simple inheritable attribute A contained in one of E's ancestors is done
+ * by supplying a value to an attribute Ae inside E with the same name. Simple inheritable
attributes
+ * are xml:lang and xml:space.
+ *
+ * The method for processing the attribute axis of an element E in the node-set is hence enhanced.
+ * All element nodes along E's ancestor axis are examined for the nearest occurrences of simple
+ * inheritable attributes in the xml namespace, such as xml:lang and xml:space (whether or not they
+ * are in the node-set). From this list of attributes, any simple inheritable attributes that are
+ * already in E's attribute axis (whether or not they are in the node-set) are removed. Then,
+ * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
+ * the node-set. The result of visiting the attribute axis is computed by processing the attribute
+ * nodes in this merged attribute list.
+ *
+ * The xml:id attribute is not a simple inheritable attribute and no processing of these attributes
is
+ * performed.
+ *
+ * The xml:base attribute is not a simple inheritable attribute and requires special processing
beyond
+ * a simple redeclaration.
+ *
+ * Attributes in the XML namespace other than xml:base, xml:id, xml:lang, and xml:space MUST be
processed
+ * as ordinary attributes.
+ */
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* special processing for XML attribute kiks in only when we have invisible parents */
+ if ((all_parents_visible) || (!parent_visible) || (xmlC14NIsXmlAttr(attr) == 0)) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ } else {
+ int matched = 0;
+
+ /* check for simple inheritance attributes */
+ if((!matched) && (xml_lang_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "lang")) {
+ xml_lang_attr = attr;
+ matched = 1;
+ }
+ if((!matched) && (xml_space_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "space")) {
+ xml_space_attr = attr;
+ matched = 1;
+ }
+
+ /* check for base attr */
+ if((!matched) && (xml_base_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "base")) {
+ xml_base_attr = attr;
+ matched = 1;
+ }
+
+ /* otherwise, it is a normal attribute, so just check if it is visible */
+ if((!matched) && xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ }
+
+ /* move to the next one */
+ attr = attr->next;
+ }
+
+ /* special processing for XML attribute kiks in only when we have invisible parents */
+ if ((!all_parents_visible) && (parent_visible)) {
+
+ /* simple inheritance attributes - copy */
+ if(xml_lang_attr == NULL) {
+ xml_lang_attr = xmlC14NFindParentAttr(cur->parent, BAD_CAST "lang", XML_XML_NAMESPACE);
+ }
+ if(xml_lang_attr != NULL) {
+ xmlListInsert(list, xml_lang_attr);
+ }
+ if(xml_space_attr == NULL) {
+ xml_space_attr = xmlC14NFindParentAttr(cur->parent, BAD_CAST "space", XML_XML_NAMESPACE);
+ }
+ if(xml_space_attr != NULL) {
+ xmlListInsert(list, xml_space_attr);
+ }
+
+ /* base uri attribute - fix up */
+ if(xml_base_attr == NULL) {
+ xml_base_attr = xmlC14NFindParentAttr(cur->parent, BAD_CAST "base", XML_XML_NAMESPACE);
+ }
+ if(xml_base_attr != NULL) {
+ xml_base_attr = xmlC14NFixupBaseAttr(ctx, xml_base_attr);
+ if(xml_base_attr != NULL) {
+ xmlListInsert(list, xml_base_attr);
+
+ /* note that we MUST delete returned attr node ourselves! */
+ xml_base_attr->next = attrs_to_delete;
+ attrs_to_delete = xml_base_attr;
+ }
+ }
+ }
+
+ /* done */
+ break;
}
/*
@@ -1040,6 +1323,7 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
/*
* Cleanup
*/
+ xmlFreePropList(attrs_to_delete);
xmlListDelete(list);
return (0);
}
@@ -1096,6 +1380,8 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
* xmlC14NProcessElementNode:
* @ctx: the pointer to C14N context object
* @cur: the node to process
+ * @visible: this node is visible
+ * @all_parents_visible: whether all the parents of this node are visible
*
* Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
*
@@ -1114,7 +1400,7 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
* Returns non-negative value on success or negative value on fail
*/
static int
-xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
+xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible, int all_parents_visible)
{
int ret;
xmlC14NVisibleNsStack state;
@@ -1159,7 +1445,7 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
}
- if (!ctx->exclusive) {
+ if (!xmlC14NIsExclusive(ctx)) {
ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
} else {
ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
@@ -1173,7 +1459,7 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
xmlC14NVisibleNsStackShift(ctx->ns_rendered);
}
- ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);
+ ret = xmlC14NProcessAttrsAxis(ctx, cur, visible, (visible && all_parents_visible));
if (ret < 0) {
xmlC14NErrInternal("processing attributes axis");
return (-1);
@@ -1183,7 +1469,7 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
xmlOutputBufferWriteString(ctx->buf, ">");
}
if (cur->children != NULL) {
- ret = xmlC14NProcessNodeList(ctx, cur->children);
+ ret = xmlC14NProcessNodeList(ctx, cur->children, (visible && all_parents_visible));
if (ret < 0) {
xmlC14NErrInternal("processing childrens list");
return (-1);
@@ -1222,7 +1508,7 @@ xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
* Returns non-negative value on success or negative value on fail
*/
static int
-xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int all_parents_visible)
{
int ret = 0;
int visible;
@@ -1235,7 +1521,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
visible = xmlC14NIsVisible(ctx, cur, cur->parent);
switch (cur->type) {
case XML_ELEMENT_NODE:
- ret = xmlC14NProcessElementNode(ctx, cur, visible);
+ ret = xmlC14NProcessElementNode(ctx, cur, visible, all_parents_visible);
break;
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
@@ -1364,7 +1650,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
if (cur->children != NULL) {
ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
ctx->parent_is_doc = 1;
- ret = xmlC14NProcessNodeList(ctx, cur->children);
+ ret = xmlC14NProcessNodeList(ctx, cur->children, (visible && all_parents_visible));
}
break;
@@ -1413,7 +1699,7 @@ xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
* Returns non-negative value on success or negative value on fail
*/
static int
-xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
+xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur, int all_parents_visible)
{
int ret;
@@ -1423,7 +1709,7 @@ xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
}
for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {
- ret = xmlC14NProcessNode(ctx, cur);
+ ret = xmlC14NProcessNode(ctx, cur, all_parents_visible);
}
return (ret);
}
@@ -1457,9 +1743,10 @@ xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
* or not
* @user_data: the first parameter for @is_visible_callback function
* (in most cases, it is nodes set)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixe the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
+ * inclusive namespaces (only for `
* canonicalization)
* @with_comments: include comments in the result (!=0) or not (==0)
* @buf: the output buffer to store canonical XML; this
@@ -1473,7 +1760,7 @@ xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
static xmlC14NCtxPtr
xmlC14NNewCtx(xmlDocPtr doc,
xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf)
{
xmlC14NCtxPtr ctx = NULL;
@@ -1531,11 +1818,11 @@ xmlC14NNewCtx(xmlDocPtr doc,
}
/*
- * Set "exclusive" flag, create a nodes set for namespaces
- * stack and remember list of incluseve prefixes
+ * Set "mode" flag and remember list of incluseve prefixes
+ * for exclusive c14n
*/
- if (exclusive) {
- ctx->exclusive = 1;
+ ctx->mode = mode;
+ if(xmlC14NIsExclusive(ctx)) {
ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
}
return (ctx);
@@ -1548,8 +1835,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
* or not
* @user_data: the first parameter for @is_visible_callback function
* (in most cases, it is nodes set)
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1567,7 +1853,7 @@ xmlC14NNewCtx(xmlDocPtr doc,
*/
int
xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
- void* user_data, int exclusive, xmlChar **inclusive_ns_prefixes,
+ void* user_data, xmlC14NMode mode, xmlChar **inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
xmlC14NCtxPtr ctx;
@@ -1588,7 +1874,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
}
ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
- exclusive, inclusive_ns_prefixes,
+ mode, inclusive_ns_prefixes,
with_comments, buf);
if (ctx == NULL) {
xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
@@ -1607,7 +1893,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
* declaration.
*/
if (doc->children != NULL) {
- ret = xmlC14NProcessNodeList(ctx, doc->children);
+ ret = xmlC14NProcessNodeList(ctx, doc->children, 1);
if (ret < 0) {
xmlC14NErrInternal("processing docs children list");
xmlC14NFreeCtx(ctx);
@@ -1637,8 +1923,7 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1656,12 +1941,12 @@ xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
*/
int
xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
return(xmlC14NExecute(doc,
(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
nodes,
- exclusive,
+ mode,
inclusive_ns_prefixes,
with_comments,
buf));
@@ -1673,8 +1958,7 @@ xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1692,7 +1976,7 @@ xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
*/
int
xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlChar ** doc_txt_ptr)
{
int ret;
@@ -1717,7 +2001,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
/*
* canonize document and write to buffer
*/
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+ ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("saving doc to output buffer");
@@ -1743,8 +2027,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1764,7 +2047,7 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
*/
int
xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, const char *filename, int compression)
{
xmlOutputBufferPtr buf;
@@ -1791,7 +2074,7 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
/*
* canonize document and write to buffer
*/
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+ ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("cannicanize document to buffer");
diff --git a/include/libxml/c14n.h b/include/libxml/c14n.h
index a8aa737..0480a70 100644
--- a/include/libxml/c14n.h
+++ b/include/libxml/c14n.h
@@ -52,11 +52,22 @@ extern "C" {
* ...
*/
+/*
+ * xmlC14NMode:
+ *
+ * Predefined values for C14N modes
+ *
+ */
+typedef enum {
+ XML_C14N_1_0 = 0, /* Origianal C14N 1.0 spec */
+ XML_C14N_EXCLUSIVE_1_0 = 1, /* Exclusive C14N 1.0 spec */
+ XML_C14N_1_1 = 2 /* C14N 1.1 spec */
+} xmlC14NMode;
XMLPUBFUN int XMLCALL
xmlC14NDocSaveTo (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ xmlC14NMode mode,
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlOutputBufferPtr buf);
@@ -64,7 +75,7 @@ XMLPUBFUN int XMLCALL
XMLPUBFUN int XMLCALL
xmlC14NDocDumpMemory (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ xmlC14NMode mode,
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlChar **doc_txt_ptr);
@@ -72,7 +83,7 @@ XMLPUBFUN int XMLCALL
XMLPUBFUN int XMLCALL
xmlC14NDocSave (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ xmlC14NMode mode,
xmlChar **inclusive_ns_prefixes,
int with_comments,
const char* filename,
@@ -100,7 +111,7 @@ XMLPUBFUN int XMLCALL
xmlC14NExecute (xmlDocPtr doc,
xmlC14NIsVisibleCallback is_visible_callback,
void* user_data,
- int exclusive,
+ xmlC14NMode mode,
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlOutputBufferPtr buf);
diff --git a/result/c14n/1-1-without-comments/example-1 b/result/c14n/1-1-without-comments/example-1
index e69de29..af9a977 100755
--- a/result/c14n/1-1-without-comments/example-1
+++ b/result/c14n/1-1-without-comments/example-1
@@ -0,0 +1,4 @@
+<?xml-stylesheet href="doc.xsl"
+ type="text/xsl" ?>
+<doc>Hello, world!</doc>
+<?pi-without-data?>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-2 b/result/c14n/1-1-without-comments/example-2
index e69de29..2afa15c 100755
--- a/result/c14n/1-1-without-comments/example-2
+++ b/result/c14n/1-1-without-comments/example-2
@@ -0,0 +1,11 @@
+<doc>
+ <clean> </clean>
+ <dirty> A B </dirty>
+ <mixed>
+ A
+ <clean> </clean>
+ B
+ <dirty> A B </dirty>
+ C
+ </mixed>
+</doc>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-3 b/result/c14n/1-1-without-comments/example-3
index e69de29..4c287e6 100755
--- a/result/c14n/1-1-without-comments/example-3
+++ b/result/c14n/1-1-without-comments/example-3
@@ -0,0 +1,14 @@
+<doc>
+ <e1></e1>
+ <e2></e2>
+ <e3 id="elem3" name="elem3"></e3>
+ <e4 id="elem4" name="elem4"></e4>
+ <e5 xmlns="http://www.uvic.ca" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm"
attr2="all" b:attr="sorted" a:attr="out"></e5>
+ <e6 xmlns:a="http://www.w3.org">
+ <e7 xmlns="http://www.ietf.org">
+ <e8 xmlns="">
+ <e9 xmlns:a="http://www.ietf.org" attr="default"></e9>
+ </e8>
+ </e7>
+ </e6>
+</doc>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-4 b/result/c14n/1-1-without-comments/example-4
index e69de29..19a2559 100755
--- a/result/c14n/1-1-without-comments/example-4
+++ b/result/c14n/1-1-without-comments/example-4
@@ -0,0 +1,9 @@
+<doc>
+ <text>First line
+Second line</text>
+ <value>2</value>
+ <compute>value>"0" && value<"10" ?"valid":"error"</compute>
+ <compute expr="value>"0" && value<"10"
?"valid":"error"">valid</compute>
+ <norm attr=" ' 
	 ' "></norm>
+ <normId id="' 
	 '"></normId>
+</doc>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-5 b/result/c14n/1-1-without-comments/example-5
index e69de29..c232e74 100755
--- a/result/c14n/1-1-without-comments/example-5
+++ b/result/c14n/1-1-without-comments/example-5
@@ -0,0 +1,3 @@
+<doc attrExtEnt="entExt">
+ Hello, world!
+</doc>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-6 b/result/c14n/1-1-without-comments/example-6
index e69de29..0be38f9 100755
--- a/result/c14n/1-1-without-comments/example-6
+++ b/result/c14n/1-1-without-comments/example-6
@@ -0,0 +1 @@
+<doc>©</doc>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-7 b/result/c14n/1-1-without-comments/example-7
index e69de29..0a96cc4 100755
--- a/result/c14n/1-1-without-comments/example-7
+++ b/result/c14n/1-1-without-comments/example-7
@@ -0,0 +1 @@
+<e1 xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org"><e3 xmlns="" id="E3"
xml:space="preserve"></e3></e1>
\ No newline at end of file
diff --git a/result/c14n/1-1-without-comments/example-8 b/result/c14n/1-1-without-comments/example-8
index e69de29..4dcf5d5 100755
--- a/result/c14n/1-1-without-comments/example-8
+++ b/result/c14n/1-1-without-comments/example-8
@@ -0,0 +1 @@
+<e1 xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org"
xml:base="http://www.example.com/something/else"><e3 xmlns="" id="E3"
xml:base="http://www.example.com/bar/foo" xml:space="preserve"></e3></e1>
\ No newline at end of file
diff --git a/runtest.c b/runtest.c
index c7d11fa..5cf1320 100644
--- a/runtest.c
+++ b/runtest.c
@@ -3671,7 +3671,7 @@ parse_list(xmlChar *str) {
}
static int
-c14nRunTest(const char* xml_filename, int with_comments, int exclusive,
+c14nRunTest(const char* xml_filename, int with_comments, int mode,
const char* xpath_filename, const char *ns_filename,
const char* result_file) {
xmlDocPtr doc;
@@ -3733,7 +3733,7 @@ c14nRunTest(const char* xml_filename, int with_comments, int exclusive,
/* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
ret = xmlC14NDocDumpMemory(doc,
(xpath) ? xpath->nodesetval : NULL,
- exclusive, inclusive_namespaces,
+ mode, inclusive_namespaces,
with_comments, &result);
if (ret >= 0) {
if(result != NULL) {
@@ -3760,7 +3760,7 @@ c14nRunTest(const char* xml_filename, int with_comments, int exclusive,
}
static int
-c14nCommonTest(const char *filename, int with_comments, int exclusive,
+c14nCommonTest(const char *filename, int with_comments, int mode,
const char *subdir) {
char buf[500];
char prefix[500];
@@ -3793,7 +3793,7 @@ c14nCommonTest(const char *filename, int with_comments, int exclusive,
}
nb_tests++;
- if (c14nRunTest(filename, with_comments, exclusive,
+ if (c14nRunTest(filename, with_comments, mode,
xpath, ns, result) < 0)
ret = 1;
@@ -3808,21 +3808,28 @@ c14nWithCommentTest(const char *filename,
const char *resul ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
- return(c14nCommonTest(filename, 1, 0, "with-comments"));
+ return(c14nCommonTest(filename, 1, XML_C14N_1_0, "with-comments"));
}
static int
c14nWithoutCommentTest(const char *filename,
const char *resul ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
- return(c14nCommonTest(filename, 0, 0, "without-comments"));
+ return(c14nCommonTest(filename, 0, XML_C14N_1_0, "without-comments"));
}
static int
c14nExcWithoutCommentTest(const char *filename,
const char *resul ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
- return(c14nCommonTest(filename, 0, 1, "exc-without-comments"));
+ return(c14nCommonTest(filename, 0, XML_C14N_EXCLUSIVE_1_0, "exc-without-comments"));
+}
+static int
+c14n11WithoutCommentTest(const char *filename,
+ const char *resul ATTRIBUTE_UNUSED,
+ const char *err ATTRIBUTE_UNUSED,
+ int options ATTRIBUTE_UNUSED) {
+ return(c14nCommonTest(filename, 0, XML_C14N_1_1, "1-1-without-comments"));
}
#endif
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined (LIBXML_SAX1_ENABLED)
@@ -4257,6 +4264,9 @@ testDesc testDescriptions[] = {
{ "C14N exclusive without comments regression tests" ,
c14nExcWithoutCommentTest, "./test/c14n/exc-without-comments/*.xml", NULL, NULL, NULL,
0 },
+ { "C14N 1.1 without comments regression tests" ,
+ c14n11WithoutCommentTest, "./test/c14n/1-1-without-comments/*.xml", NULL, NULL, NULL,
+ 0 },
#endif
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_ENABLED)
{ "Catalog and Threads regression tests" ,
diff --git a/test/.cvsignore b/test/.cvsignore
deleted file mode 100644
index c038ed7..0000000
--- a/test/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
\ No newline at end of file
diff --git a/test/c14n/1-1-without-comments/doc.dtd b/test/c14n/1-1-without-comments/doc.dtd
index e69de29..c460239 100755
--- a/test/c14n/1-1-without-comments/doc.dtd
+++ b/test/c14n/1-1-without-comments/doc.dtd
@@ -0,0 +1 @@
+<!-- Empty DTD -->
\ No newline at end of file
diff --git a/test/c14n/1-1-without-comments/example-1.xml b/test/c14n/1-1-without-comments/example-1.xml
index e69de29..ed450c7 100755
--- a/test/c14n/1-1-without-comments/example-1.xml
+++ b/test/c14n/1-1-without-comments/example-1.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+
+<?xml-stylesheet href="doc.xsl"
+ type="text/xsl" ?>
+
+<!DOCTYPE doc SYSTEM "doc.dtd">
+
+<doc>Hello, world!<!-- Comment 1 --></doc>
+
+<?pi-without-data ?>
+
+<!-- Comment 2 -->
+
+<!-- Comment 3 -->
diff --git a/test/c14n/1-1-without-comments/example-2.xml b/test/c14n/1-1-without-comments/example-2.xml
index e69de29..74eeea1 100755
--- a/test/c14n/1-1-without-comments/example-2.xml
+++ b/test/c14n/1-1-without-comments/example-2.xml
@@ -0,0 +1,11 @@
+<doc>
+ <clean> </clean>
+ <dirty> A B </dirty>
+ <mixed>
+ A
+ <clean> </clean>
+ B
+ <dirty> A B </dirty>
+ C
+ </mixed>
+</doc>
diff --git a/test/c14n/1-1-without-comments/example-3.xml b/test/c14n/1-1-without-comments/example-3.xml
index e69de29..a7a1950 100755
--- a/test/c14n/1-1-without-comments/example-3.xml
+++ b/test/c14n/1-1-without-comments/example-3.xml
@@ -0,0 +1,18 @@
+<!DOCTYPE doc [<!ATTLIST e9 attr CDATA "default">]>
+<doc>
+ <e1 />
+ <e2 ></e2>
+ <e3 name = "elem3" id="elem3" />
+ <e4 name="elem4" id="elem4" ></e4>
+ <e5 a:attr="out" b:attr="sorted" attr2="all" attr="I'm"
+ xmlns:b="http://www.ietf.org"
+ xmlns:a="http://www.w3.org"
+ xmlns="http://www.uvic.ca"/>
+ <e6 xmlns="" xmlns:a="http://www.w3.org">
+ <e7 xmlns="http://www.ietf.org">
+ <e8 xmlns="" xmlns:a="http://www.w3.org">
+ <e9 xmlns="" xmlns:a="http://www.ietf.org"/>
+ </e8>
+ </e7>
+ </e6>
+</doc>
diff --git a/test/c14n/1-1-without-comments/example-4.xml b/test/c14n/1-1-without-comments/example-4.xml
index e69de29..3fba138 100755
--- a/test/c14n/1-1-without-comments/example-4.xml
+++ b/test/c14n/1-1-without-comments/example-4.xml
@@ -0,0 +1,9 @@
+<!DOCTYPE doc [<!ATTLIST normId id ID #IMPLIED>]>
+<doc>
+ <text>First line
 Second line</text>
+ <value>2</value>
+ <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
+ <compute expr='value>"0" && value<"10" ?"valid":"error"'>valid</compute>
+ <norm attr=' '   
	 ' '/>
+ <normId id=' '   
	 ' '/>
+</doc>
diff --git a/test/c14n/1-1-without-comments/example-5.xml b/test/c14n/1-1-without-comments/example-5.xml
index e69de29..92c5322 100755
--- a/test/c14n/1-1-without-comments/example-5.xml
+++ b/test/c14n/1-1-without-comments/example-5.xml
@@ -0,0 +1,12 @@
+<!DOCTYPE doc [
+<!ATTLIST doc attrExtEnt ENTITY #IMPLIED>
+<!ENTITY ent1 "Hello">
+<!ENTITY ent2 SYSTEM "world.txt">
+<!ENTITY entExt SYSTEM "earth.gif" NDATA gif>
+<!NOTATION gif SYSTEM "viewgif.exe">
+]>
+<doc attrExtEnt="entExt">
+ &ent1;, &ent2;!
+</doc>
+
+<!-- Let world.txt contain "world" (excluding the quotes) -->
diff --git a/test/c14n/1-1-without-comments/example-6.xml b/test/c14n/1-1-without-comments/example-6.xml
index e69de29..31e2071 100755
--- a/test/c14n/1-1-without-comments/example-6.xml
+++ b/test/c14n/1-1-without-comments/example-6.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<doc>©</doc>
diff --git a/test/c14n/1-1-without-comments/example-7.xml b/test/c14n/1-1-without-comments/example-7.xml
index e69de29..41171cb 100755
--- a/test/c14n/1-1-without-comments/example-7.xml
+++ b/test/c14n/1-1-without-comments/example-7.xml
@@ -0,0 +1,11 @@
+<!DOCTYPE doc [
+<!ATTLIST e2 xml:space (default|preserve) 'preserve'>
+<!ATTLIST e3 id ID #IMPLIED>
+]>
+<doc xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org">
+ <e1>
+ <e2 xmlns="">
+ <e3 id="E3"/>
+ </e2>
+ </e1>
+</doc>
diff --git a/test/c14n/1-1-without-comments/example-7.xpath b/test/c14n/1-1-without-comments/example-7.xpath
index e69de29..84ddb08 100755
--- a/test/c14n/1-1-without-comments/example-7.xpath
+++ b/test/c14n/1-1-without-comments/example-7.xpath
@@ -0,0 +1,10 @@
+<XPath xmlns:ietf="http://www.ietf.org" >
+ (//.|//@*|//namespace::*)
+ [
+ self::ietf:e1
+ or
+ (parent::ietf:e1 and not(self::text() or self::e2))
+ or
+ count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node())
+ ]
+</XPath>
\ No newline at end of file
diff --git a/test/c14n/1-1-without-comments/example-8.xml b/test/c14n/1-1-without-comments/example-8.xml
index e69de29..49568be 100755
--- a/test/c14n/1-1-without-comments/example-8.xml
+++ b/test/c14n/1-1-without-comments/example-8.xml
@@ -0,0 +1,11 @@
+<!DOCTYPE doc [
+<!ATTLIST e2 xml:space (default|preserve) 'preserve'>
+<!ATTLIST e3 id ID #IMPLIED>
+]>
+<doc xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org"
xml:base="http://www.example.com/something/else">
+ <e1>
+ <e2 xmlns="" xml:id="abc" xml:base="../bar/">
+ <e3 id="E3" xml:base="foo"/>
+ </e2>
+ </e1>
+</doc>
diff --git a/test/c14n/1-1-without-comments/example-8.xpath b/test/c14n/1-1-without-comments/example-8.xpath
index e69de29..84ddb08 100755
--- a/test/c14n/1-1-without-comments/example-8.xpath
+++ b/test/c14n/1-1-without-comments/example-8.xpath
@@ -0,0 +1,10 @@
+<XPath xmlns:ietf="http://www.ietf.org" >
+ (//.|//@*|//namespace::*)
+ [
+ self::ietf:e1
+ or
+ (parent::ietf:e1 and not(self::text() or self::e2))
+ or
+ count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node())
+ ]
+</XPath>
\ No newline at end of file
diff --git a/test/c14n/1-1-without-comments/world.txt b/test/c14n/1-1-without-comments/world.txt
index e69de29..04fea06 100755
--- a/test/c14n/1-1-without-comments/world.txt
+++ b/test/c14n/1-1-without-comments/world.txt
@@ -0,0 +1 @@
+world
\ No newline at end of file
diff --git a/test/c14n/with-comments/doc.dtd b/test/c14n/with-comments/doc.dtd
index e69de29..c460239 100644
--- a/test/c14n/with-comments/doc.dtd
+++ b/test/c14n/with-comments/doc.dtd
@@ -0,0 +1 @@
+<!-- Empty DTD -->
\ No newline at end of file
diff --git a/test/c14n/without-comments/doc.dtd b/test/c14n/without-comments/doc.dtd
index e69de29..c460239 100644
--- a/test/c14n/without-comments/doc.dtd
+++ b/test/c14n/without-comments/doc.dtd
@@ -0,0 +1 @@
+<!-- Empty DTD -->
\ No newline at end of file
diff --git a/testC14N.c b/testC14N.c
index 674fc71..ba70127 100644
--- a/testC14N.c
+++ b/testC14N.c
@@ -32,13 +32,17 @@ static void usage(const char *name) {
name);
fprintf(stderr, "where <mode> is one of following:\n");
fprintf(stderr,
- "--with-comments \t XML file canonization w comments\n");
+ "--with-comments \t XML file canonicalization v1.0 w comments \n");
fprintf(stderr,
- "--without-comments \t XML file canonization w/o comments\n");
+ "--without-comments \t XML file canonicalization v1.0 w/o comments\n");
fprintf(stderr,
- "--exc-with-comments \t Exclusive XML file canonization w comments\n");
+ "--1-1-with-comments \t XML file canonicalization v1.1 w comments\n");
fprintf(stderr,
- "--exc-without-comments\t Exclusive XML file canonization w/o comments\n");
+ "--1-1-without-comments \t XML file canonicalization v1.1 w/o comments\n");
+ fprintf(stderr,
+ "--exc-with-comments \t Exclusive XML file canonicalization v1.0 w comments\n");
+ fprintf(stderr,
+ "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n");
}
static xmlXPathObjectPtr
@@ -49,7 +53,7 @@ static xmlChar **parse_list(xmlChar *str);
/* static void print_xpath_nodes(xmlNodeSetPtr nodes); */
static int
-test_c14n(const char* xml_filename, int with_comments, int exclusive,
+test_c14n(const char* xml_filename, int with_comments, int mode,
const char* xpath_filename, xmlChar **inclusive_namespaces) {
xmlDocPtr doc;
xmlXPathObjectPtr xpath = NULL;
@@ -96,7 +100,7 @@ test_c14n(const char* xml_filename, int with_comments, int exclusive,
/* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
ret = xmlC14NDocDumpMemory(doc,
(xpath) ? xpath->nodesetval : NULL,
- exclusive, inclusive_namespaces,
+ mode, inclusive_namespaces,
with_comments, &result);
if(ret >= 0) {
if(result != NULL) {
@@ -135,22 +139,26 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error: wrong number of arguments.\n");
usage(argv[0]);
} else if(strcmp(argv[1], "--with-comments") == 0) {
- ret = test_c14n(argv[2], 1, 0, (argc > 3) ? argv[3] : NULL, NULL);
+ ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
} else if(strcmp(argv[1], "--without-comments") == 0) {
- ret = test_c14n(argv[2], 0, 0, (argc > 3) ? argv[3] : NULL, NULL);
+ ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
+ } else if(strcmp(argv[1], "--1-1-with-comments") == 0) {
+ ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
+ } else if(strcmp(argv[1], "--1-1-without-comments") == 0) {
+ ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
} else if(strcmp(argv[1], "--exc-with-comments") == 0) {
xmlChar **list;
/* load exclusive namespace from command line */
list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
- ret = test_c14n(argv[2], 1, 1, (argc > 3) ? argv[3] : NULL, list);
+ ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
if(list != NULL) xmlFree(list);
} else if(strcmp(argv[1], "--exc-without-comments") == 0) {
xmlChar **list;
/* load exclusive namespace from command line */
list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
- ret = test_c14n(argv[2], 0, 1, (argc > 3) ? argv[3] : NULL, list);
+ ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
if(list != NULL) xmlFree(list);
} else {
fprintf(stderr, "Error: bad option.\n");
diff --git a/xmllint.c b/xmllint.c
index 77c1e62..a668570 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -184,6 +184,7 @@ static int nocatalogs = 0;
#endif
#ifdef LIBXML_C14N_ENABLED
static int canonical = 0;
+static int canonical_11 = 0;
static int exc_canonical = 0;
#endif
#ifdef LIBXML_READER_ENABLED
@@ -2429,7 +2430,19 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlChar *result = NULL;
int size;
- size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
+ if (size >= 0) {
+ write(1, result, size);
+ xmlFree(result);
+ } else {
+ fprintf(stderr, "Failed to canonicalize\n");
+ progresult = XMLLINT_ERR_OUT;
+ }
+ } else if (canonical) {
+ xmlChar *result = NULL;
+ int size;
+
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
if (size >= 0) {
write(1, result, size);
xmlFree(result);
@@ -2442,7 +2455,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlChar *result = NULL;
int size;
- size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
if (size >= 0) {
write(1, result, size);
xmlFree(result);
@@ -2878,7 +2891,8 @@ static void usage(const char *name) {
printf("\t--encode encoding : output in the given encoding\n");
printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
#endif /* LIBXML_OUTPUT_ENABLED */
- printf("\t--c14n : save in W3C canonical format (with comments)\n");
+ printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
+ printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
#ifdef LIBXML_C14N_ENABLED
#endif /* LIBXML_C14N_ENABLED */
@@ -3141,6 +3155,11 @@ main(int argc, char **argv) {
canonical++;
options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
}
+ else if ((!strcmp(argv[i], "-c14n11")) ||
+ (!strcmp(argv[i], "--c14n11"))) {
+ canonical_11++;
+ options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+ }
else if ((!strcmp(argv[i], "-exc-c14n")) ||
(!strcmp(argv[i], "--exc-c14n"))) {
exc_canonical++;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]