[libxml++] Node::find(): Cope with weird use of _private in xmlNodeSet.



commit 848687f0d2096494625599d2572bbdb29553447a
Author: Murray Cumming <murrayc murrayc com>
Date:   Sun Jun 13 23:03:20 2010 +0200

    Node::find(): Cope with weird use of _private in xmlNodeSet.
    
    * libxml++/nodes/node.cc: The xmlNodeSet seems to contain extra xmlNodes that
    were never given to on_libxml_construct(). Those xmlNodes seem to abuse
    private_, where we find our real xmlNodes containing our C++ Nodes.
    This fixes bug #386013 (Max Kirillov) though it depends on undocumented
    libxml behaviour.

 ChangeLog              |   10 ++++++++++
 libxml++/nodes/node.cc |   11 +++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index fd3c753..f53feb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-06-13  Murray Cumming  <murrayc murrayc com>
+
+	Node::find(): Cope with weird use of _private in xmlNodeSet.
+
+	* libxml++/nodes/node.cc: The xmlNodeSet seems to contain extra xmlNodes that 
+	were never given to on_libxml_construct(). Those xmlNodes seem to abuse 
+	private_, where we find our real xmlNodes containing our C++ Nodes.
+	This fixes bug #386013 (Max Kirillov) though it depends on undocumented 
+	libxml behaviour.
+
 2010-06-13  Murray Cumming  <murrayc murrayc com>>
 
 	Node::find(): Use libxml functions instead of direct C access.
diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc
index 4b53b30..fe2cf38 100644
--- a/libxml++/nodes/node.cc
+++ b/libxml++/nodes/node.cc
@@ -282,8 +282,15 @@ static NodeSet find_impl(xmlXPathContext* ctxt, const Glib::ustring& xpath)
     nodes.reserve(count);
     for (int i = 0; i != count; ++i)
     {
-      xmlNodePtr cnode = xmlXPathNodeSetItem(nodeset, i);
-      Node* cppNode = static_cast<Node*>(cnode->_private); //libxml creates a C++ instance for us here.
+      xmlNode* cnode = xmlXPathNodeSetItem(nodeset, i);
+
+      // TODO: It is _very_ strange and undocumented that _private contains a 
+      // pointer to the actual xmlNode (which has the C++ instance in _private, which we set),
+      // Maybe libxml abuses xmlNode::_private.
+      // I only discovered this through experimentation. murrayc.
+      // See bug https://bugzilla.gnome.org/show_bug.cgi?id=386013
+      xmlNode* cnodeReal = static_cast<xmlNode*>(cnode->_private); //libxml creates a C++ instance for us here.
+      Node* cppNode = static_cast<Node*>(cnodeReal->_private); //libxml creates a C++ instance for us here.
       nodes.push_back(cppNode);
     }
   }



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