[libgsf] xml: fix parsing problem affecting unknown contents.



commit eebd958d05b5c2e7ae33835468cb5c5023a7bef0
Author: Morten Welinder <terra gnome org>
Date:   Fri Feb 6 14:01:29 2015 -0500

    xml: fix parsing problem affecting unknown contents.

 ChangeLog        |    8 ++++++++
 NEWS             |    3 +++
 gsf/gsf-libxml.c |   52 ++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 47 insertions(+), 16 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 637c865..a363142 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-02-06  Morten Welinder  <terra gnome org>
+
+       * gsf/gsf-libxml.c (gsf_xml_in_start_element): Nodes inside
+       unknown nodes are themselves unknown, even if they would appear to
+       be known had the intervening unknown nodes not been there.  In
+       other words: don't lookup nodes while we are parsing an unknown
+       tag's contents.
+
 2015-02-04  Morten Welinder <terra gnome org>
 
        * configure.ac: Post-release bump.
diff --git a/NEWS b/NEWS
index 4645118..ec69e9a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 libgsf 1.14.32
 
+Morten:
+       * Fix obscure problem with xml parser.
+
 --------------------------------------------------------------------------
 libgsf 1.14.31
 
diff --git a/gsf/gsf-libxml.c b/gsf/gsf-libxml.c
index 810bfe6..c741032 100644
--- a/gsf/gsf-libxml.c
+++ b/gsf/gsf-libxml.c
@@ -28,6 +28,8 @@
 #include <math.h>
 #include <string.h>
 
+#undef DEBUG_PUSH_POP
+
 /* Dead kittens.  */
 #ifndef HAVE_G_VALUE_SET_SCHAR
 #define g_value_set_schar(v_,sc_) g_value_set_char((v_),(char)(sc_))
@@ -617,6 +619,12 @@ static void
 push_child (GsfXMLInInternal *state, GsfXMLInNode const *node, int default_ns_id,
            xmlChar const **attrs, GsfXMLInExtension *ext)
 {
+#ifdef DEBUG_PUSH_POP
+       g_printerr ("push: %-*s%s\n",
+                   (int)g_slist_length (state->pub.node_stack), "",
+                   node->name);
+#endif
+
        if (node->has_content == GSF_XML_CONTENT) {
                if (state->pub.content->len) {
                        state->contents_stack = g_slist_prepend
@@ -756,23 +764,29 @@ gsf_xml_in_start_element (GsfXMLInInternal *state, xmlChar const *name, xmlChar
        }
 
        node = (GsfXMLInNodeInternal const *) state->pub.node;
-       if (lookup_child (state, default_ns_id, node->groups, name, attrs, NULL))
-               return;
 
-       /* useful for <Data><b><i><u></u></i></b></Data> where all of the markup can nest */
-       ptr = state->pub.node_stack;
-       for (; ptr != NULL && node->pub.share_children_with_parent; ptr = ptr->next) {
-               node = ptr->data;
+       if (state->unknown_depth == 0) {
                if (lookup_child (state, default_ns_id, node->groups, name, attrs, NULL))
                        return;
-       }
 
-       /* Check for extensions */
-       for (ptr = node->extensions; ptr != NULL ; ptr = ptr->next) {
-               GsfXMLInExtension *ext = ptr->data;
-               if (lookup_child (state, default_ns_id,
-                       ext->doc->root_node->groups, name, attrs, ext))
-                       return;
+               /*
+                * useful for <Data><b><i><u></u></i></b></Data> where all of
+                * the markup can nest
+                */
+               ptr = state->pub.node_stack;
+               for (; ptr != NULL && node->pub.share_children_with_parent; ptr = ptr->next) {
+                       node = ptr->data;
+                       if (lookup_child (state, default_ns_id, node->groups, name, attrs, NULL))
+                               return;
+               }
+
+               /* Check for extensions */
+               for (ptr = node->extensions; ptr != NULL ; ptr = ptr->next) {
+                       GsfXMLInExtension *ext = ptr->data;
+                       if (lookup_child (state, default_ns_id,
+                                         ext->doc->root_node->groups, name, attrs, ext))
+                               return;
+               }
        }
 
        if (state->pub.doc->unknown_handler != NULL) {
@@ -866,13 +880,19 @@ gsf_xml_in_end_element (GsfXMLInInternal *state,
        g_slist_free (node->extensions);
        node->extensions = NULL;
 
+#ifdef DEBUG_PUSH_POP
+       g_printerr (" pop: %-*s%s\n",
+                   (int)g_slist_length (state->pub.node_stack) - 1, "",
+                   node->pub.name);
+#endif
+
        /* pop the state stack */
        ext = state->extension_stack->data;
-       state->extension_stack  = g_slist_remove (state->extension_stack, ext);
+       state->extension_stack  = g_slist_delete_link (state->extension_stack, state->extension_stack);
        state->pub.node         = state->pub.node_stack->data;
-       state->pub.node_stack   = g_slist_remove (state->pub.node_stack, state->pub.node);
+       state->pub.node_stack   = g_slist_delete_link (state->pub.node_stack, state->pub.node_stack);
        state->default_ns_id    = GPOINTER_TO_INT (state->ns_stack->data);
-       state->ns_stack         = g_slist_remove (state->ns_stack, GINT_TO_POINTER (state->default_ns_id));
+       state->ns_stack         = g_slist_delete_link (state->ns_stack, state->ns_stack);
 
        if (NULL != ext) {
                GsfXMLInDoc const *ext_doc = state->pub.doc;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]