libxml2 r3703 - in trunk: . python python/tests



Author: veillard
Date: Wed Mar 12 09:32:04 2008
New Revision: 3703
URL: http://svn.gnome.org/viewvc/libxml2?rev=3703&view=rev

Log:
* python/types.c: fix a memory errro when using namespace nodes
  returned from XPath queries, should fix #521699
* python/tests/Makefile.am python/tests/xpathns.py: add a specific
  regression test for it
Daniel


Added:
   trunk/python/tests/xpathns.py   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/python/tests/Makefile.am
   trunk/python/types.c

Modified: trunk/python/tests/Makefile.am
==============================================================================
--- trunk/python/tests/Makefile.am	(original)
+++ trunk/python/tests/Makefile.am	Wed Mar 12 09:32:04 2008
@@ -45,7 +45,8 @@
     validDTD.py	\
     validSchemas.py \
     validRNG.py \
-    compareNodes.py
+    compareNodes.py \
+    xpathns.py
 
 XMLS=		\
     tst.xml	\

Added: trunk/python/tests/xpathns.py
==============================================================================
--- (empty file)
+++ trunk/python/tests/xpathns.py	Wed Mar 12 09:32:04 2008
@@ -0,0 +1,29 @@
+#!/usr/bin/python -u
+#
+import libxml2
+
+expect=' xmlns:a="urn:whatevar"'
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+d = libxml2.parseDoc("<a:a xmlns:a='urn:whatevar'/>")
+res=""
+for n in d.xpathEval("//namespace::*"):
+    res = res + n.serialize()
+d.freeDoc()
+
+if res != expect:
+    print "test5 failed: unexpected output"
+    print res
+del res
+del d
+del n
+# Memory debug specific
+libxml2.cleanupParser()
+
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()

Modified: trunk/python/types.c
==============================================================================
--- trunk/python/types.c	(original)
+++ trunk/python/types.c	Wed Mar 12 09:32:04 2008
@@ -7,6 +7,7 @@
  * daniel veillard com
  */
 #include "libxml_wrap.h"
+#include <libxml/xpathInternals.h>
 
 PyObject *
 libxml_intWrap(int val)
@@ -330,6 +331,24 @@
     return (ret);
 }
 
+/**
+ * libxml_xmlXPathDestructNsNode:
+ * cobj: xmlNsPtr namespace node
+ * desc: ignored string
+ *
+ * This function is called if and when a namespace node returned in
+ * an XPath node set is to be destroyed. That's the only kind of
+ * object returned in node set not directly linked to the original
+ * xmlDoc document, see xmlXPathNodeSetDupNs.
+ */
+static void
+libxml_xmlXPathDestructNsNode(void *cobj, void *desc ATTRIBUTE_UNUSED) {
+#ifdef DEBUG
+    fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cobj);
+#endif
+    xmlXPathNodeSetFreeNs((xmlNsPtr) cobj);
+}
+
 PyObject *
 libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
 {
@@ -380,8 +399,17 @@
                 ret = PyList_New(obj->nodesetval->nodeNr);
                 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
                     node = obj->nodesetval->nodeTab[i];
-                    /* TODO: try to cast directly to the proper node type */
-                    PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
+                    if (node->type == XML_NAMESPACE_DECL) {
+		        PyObject *ns = 
+			    PyCObject_FromVoidPtrAndDesc((void *) node,
+                                     (char *) "xmlNsPtr",
+				     libxml_xmlXPathDestructNsNode);
+			PyList_SetItem(ret, i, ns);
+			/* make sure the xmlNsPtr is not destroyed now */
+			obj->nodesetval->nodeTab[i] = NULL;
+		    } else {
+			PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
+		    }
                 }
             }
             break;



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