summaryrefslogtreecommitdiffstats
path: root/lasso
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2012-10-08 19:28:57 +0200
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2013-01-25 18:30:55 +0100
commit8e98e432ff221a98297b177ca40d6217f581c0b4 (patch)
tree18b780ae15644a2e648f4023ffaf3bcf09b93595 /lasso
parent2663c5df950a4ad10aefaa5373fc00971534adb8 (diff)
downloadlasso-8e98e432ff221a98297b177ca40d6217f581c0b4.tar.gz
lasso-8e98e432ff221a98297b177ca40d6217f581c0b4.tar.xz
lasso-8e98e432ff221a98297b177ca40d6217f581c0b4.zip
xml: really enforce elements cardinality when parsing messages
- add a new SNIPPET_MANDATORY: we could only indicate 0-1 and 0-* cardinalities, now we can also indicate 1-1 and 1-* cardinalities. - repect cadinalities when parsing an xmlNode tree into a LassoNode tree.
Diffstat (limited to 'lasso')
-rw-r--r--lasso/xml/private.h1
-rw-r--r--lasso/xml/xml.c112
2 files changed, 78 insertions, 35 deletions
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index 629d6ca5..b1ec0979 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -62,6 +62,7 @@ typedef enum {
SNIPPET_ALLOW_TEXT = 1 << 26, /* allow text childs in list of nodes */
SNIPPET_KEEP_XMLNODE = 1 << 27, /* force keep xmlNode */
SNIPPET_PRIVATE = 1 << 28, /* means that the offset is relative to a private extension */
+ SNIPPET_MANDATORY = 1 << 29, /* means that the element cardinality is at least 1 */
} SnippetType;
typedef enum {
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index 753d8174..b7b29f95 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -1366,14 +1366,42 @@ is_snippet_type(struct XmlSnippet *snippet, SnippetType simple_type) {
}
static inline gboolean
+is_snippet_mandatory(struct XmlSnippet *snippet)
+{
+ return snippet->type & SNIPPET_MANDATORY ? TRUE : FALSE;
+}
+
+static inline gboolean
+is_snippet_multiple(struct XmlSnippet *snippet)
+{
+ switch (snippet->type & 0xff) {
+ case SNIPPET_LIST_XMLNODES:
+ case SNIPPET_LIST_CONTENT:
+ case SNIPPET_LIST_NODES:
+ case SNIPPET_EXTENSION:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static inline gboolean
node_match_snippet(xmlNode *parent, xmlNode *node, struct XmlSnippet *snippet)
{
+ gboolean rc = TRUE;
+
/* special case of ArtifactResponse */
- if (snippet->type & SNIPPET_ANY)
+ if (snippet->type & SNIPPET_ANY) {
return TRUE;
- return (lasso_strisequal(snippet->name, (char*)node->name)
- && ((!snippet->ns_uri && lasso_equal_namespace(parent->ns, node->ns)) ||
- (node->ns && lasso_strisequal((char*)node->ns->href, snippet->ns_uri))));
+ } else {
+ rc = rc && lasso_strisequal(snippet->name, (char*)node->name);
+ rc = rc &&
+ ((!snippet->ns_uri &&
+ lasso_equal_namespace(parent->ns, node->ns)) ||
+ (node->ns &&
+ lasso_strisequal((char*)node->ns->href, snippet->ns_uri)));
+ return rc;
+ }
}
/** FIXME: return a real error code */
@@ -1564,28 +1592,54 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
xmlNode *first_child = NULL;
GList **list = NULL;
xmlChar *content = NULL;
+ gboolean match = FALSE;
+ struct XmlSnippet *matched_snippet = NULL;
- /* Find a matching snippet */
- while (class_iter && ! node_match_snippet(xmlnode, t, snippet)) {
- snippet++;
+#define ADVANCE \
+ snippet++; \
next_node_snippet(&class_iter, &snippet);
+#define ERROR \
+ error("Element %s:%s cannot be parsed", \
+ t->ns != NULL ? (char*)t->ns->prefix : "<noprefix>", \
+ t->name); \
+ rc = 1; \
+ goto cleanup;
+ /* Find a matching snippet */
+ while (class_iter && snippet) {
+ gboolean mandatory = is_snippet_mandatory(snippet);
+ gboolean multiple = is_snippet_multiple(snippet);
+
+ if ((match = node_match_snippet(xmlnode, t, snippet))) {
+ matched_snippet = snippet;
+ class = class_iter->data;
+ g_type = G_TYPE_FROM_CLASS(class);
+ value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
+ list = value;
+ if (! multiple) {
+ ADVANCE;
+ }
+ break;
+ } else {
+ if (mandatory) {
+ break;
+ } else {
+ ADVANCE;
+ }
+ }
}
- if (! class_iter) {
- /* If we cannot find one, terminate here. */
- break;
+ if (! match) {
+ ERROR;
}
- class = class_iter->data;
- g_type = G_TYPE_FROM_CLASS(class);
- value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
- list = value;
+#undef ADVANCE
+#undef ERROR
- if (snippet->offset || (snippet->type & SNIPPET_PRIVATE)) {
- switch (snippet->type & 0xff) {
+ if (matched_snippet->offset || (matched_snippet->type & SNIPPET_PRIVATE)) {
+ switch (matched_snippet->type & 0xff) {
case SNIPPET_LIST_NODES:
case SNIPPET_NODE:
subnode = lasso_node_new_from_xmlNode_with_type(t,
- snippet->class_name);
- if (is_snippet_type(snippet, SNIPPET_NODE)) {
+ matched_snippet->class_name);
+ if (is_snippet_type(matched_snippet, SNIPPET_NODE)) {
lasso_assign_new_gobject(*(LassoNode**)value, subnode);
} else {
lasso_list_add_new_gobject(*list, subnode);
@@ -1595,7 +1649,7 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
first_child = xmlSecGetNextElementNode(t->children);
if (first_child) {
subnode = lasso_node_new_from_xmlNode_with_type(first_child,
- snippet->class_name);
+ matched_snippet->class_name);
lasso_assign_new_gobject(*(LassoNode**)value, subnode);
}
break;
@@ -1609,8 +1663,8 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
case SNIPPET_CONTENT:
case SNIPPET_LIST_CONTENT:
content = xmlNodeGetContent(t);
- if (is_snippet_type(snippet, SNIPPET_CONTENT)) {
- snippet_set_value(node, class, snippet, content);
+ if (is_snippet_type(matched_snippet, SNIPPET_CONTENT)) {
+ snippet_set_value(node, class, matched_snippet, content);
} else { /* only list of string-like xsd:type supported */
lasso_list_add_string(*list, (char*)content);
}
@@ -1626,22 +1680,9 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
}
/* When creating a new LassoNode and option KEEP_XMLNODE is present,
* we attached the xmlNode to the LassoNode */
- if (subnode && (snippet->type & SNIPPET_KEEP_XMLNODE)) {
+ if (subnode && (matched_snippet->type & SNIPPET_KEEP_XMLNODE)) {
lasso_node_set_original_xmlnode(subnode, t);
}
- switch (snippet->type & 0xff) {
- case SNIPPET_NODE:
- case SNIPPET_NODE_IN_CHILD:
- case SNIPPET_XMLNODE:
- case SNIPPET_CONTENT:
- case SNIPPET_SIGNATURE:
- /* Only one node to read, advance ! */
- ++snippet;
- next_node_snippet(&class_iter, &snippet);
- break;
- default:
- break;
- }
} else {
g_assert_not_reached();
}
@@ -2797,6 +2838,7 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
case SNIPPET_ANY:
case SNIPPET_KEEP_XMLNODE:
case SNIPPET_PRIVATE:
+ case SNIPPET_MANDATORY:
case SNIPPET_UNUSED1:
g_assert_not_reached();
}