[libgsf] xml: fix parsing problem affecting unknown contents.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] xml: fix parsing problem affecting unknown contents.
- Date: Fri, 6 Feb 2015 19:03:36 +0000 (UTC)
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]