diff options
author | Paul Aurich <darkrain42@pidgin.im> | 2011-09-04 18:52:18 +0000 |
---|---|---|
committer | Paul Aurich <darkrain42@pidgin.im> | 2011-09-04 18:52:18 +0000 |
commit | 21fcd59fca9c751dc09c371ff2dc75eba842e883 (patch) | |
tree | 2949c7532f85554a0f76f34524d5d8c461b8781d /libpurple/xmlnode.c | |
parent | 412d538131d208038f44cc20d25e07685a70c86e (diff) | |
download | pidgin-21fcd59fca9c751dc09c371ff2dc75eba842e883.tar.gz |
xmlnode: Fix some brokeness in xmlnode serialization with prefixed elements.
Basically we were treating node->xmlns as the default namespace, but
that isn't the case with prefexed elements. In our serialization,
I believe we were adding an extraneous xmlns='' to a prefixed element,
which changes the (default) namespace for its children. (It's been
a bit too long with this in my tree, so I've forgotten the exact details)
Diffstat (limited to 'libpurple/xmlnode.c')
-rw-r--r-- | libpurple/xmlnode.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c index 32b9c9d038..c335247875 100644 --- a/libpurple/xmlnode.c +++ b/libpurple/xmlnode.c @@ -78,6 +78,19 @@ xmlnode_new_child(xmlnode *parent, const char *name) node = new_node(name, XMLNODE_TYPE_TAG); xmlnode_insert_child(parent, node); +#if 0 + /* This would give xmlnodes more appropriate namespacing + * when creating them. Otherwise, unless an explicit namespace + * is set, xmlnode_get_namespace() will return NULL, when + * there may be a default namespace. + * + * I'm unconvinced that it's useful, and concerned it may break things. + * + * _insert_child would need the same thing, probably (assuming + * xmlns->node == NULL) + */ + xmlnode_set_namespace(node, xmlnode_get_default_namespace(node)) +#endif return node; } @@ -255,13 +268,34 @@ void xmlnode_set_namespace(xmlnode *node, const char *xmlns) node->xmlns = g_strdup(xmlns); } -const char *xmlnode_get_namespace(xmlnode *node) +const char *xmlnode_get_namespace(const xmlnode *node) { g_return_val_if_fail(node != NULL, NULL); return node->xmlns; } +const char *xmlnode_get_default_namespace(const xmlnode *node) +{ + const char *ns = NULL; + g_return_val_if_fail(node != NULL, NULL); + + /* If this node does *not* have a prefix, node->xmlns is the default + * namespace. Otherwise, it's the prefix namespace. + */ + if (!node->prefix && node->xmlns) { + return node->xmlns; + } else if (node->namespace_map) { + ns = g_hash_table_lookup(node->namespace_map, ""); + } + + /* No default ns found? Walk up the tree looking for one */ + if (!(ns && *ns) && node->parent) + ns = xmlnode_get_default_namespace(node->parent); + + return ns; +} + void xmlnode_set_prefix(xmlnode *node, const char *prefix) { g_return_if_fail(node != NULL); @@ -443,12 +477,22 @@ xmlnode_to_str_helper(const xmlnode *node, int *len, gboolean formatting, int de if (node->namespace_map) { g_hash_table_foreach(node->namespace_map, (GHFunc)xmlnode_to_str_foreach_append_ns, text); - } else if (node->xmlns) { - if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns)) + } else { + /* Figure out if this node has a different default namespace from parent */ + const char *xmlns = NULL; + const char *parent_xmlns = NULL; + if (!prefix) + xmlns = node->xmlns; + + if (!xmlns) + xmlns = xmlnode_get_default_namespace(node); + if (node->parent) + parent_xmlns = xmlnode_get_default_namespace(node->parent); + if (!purple_strequal(xmlns, parent_xmlns)) { - char *xmlns = g_markup_escape_text(node->xmlns, -1); - g_string_append_printf(text, " xmlns='%s'", xmlns); - g_free(xmlns); + char *escaped_xmlns = g_markup_escape_text(xmlns, -1); + g_string_append_printf(text, " xmlns='%s'", escaped_xmlns); + g_free(escaped_xmlns); } } for(c = node->child; c; c = c->next) |