From 201b712edf0478e6a94ace984c1e8435bf3bc3c3 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Tue, 5 Feb 2019 21:31:02 +0100 Subject: LP#1814522: Fix a crash when appending a child subtree that contains unsubstituted entity references. This is a work-around for a (supposed) bug in libxml2 (https://gitlab.gnome.org/GNOME/libxml2/issues/42), which crashes by running into an infinite recursive loop while traversing the child nodes of the entity reference. A lucky side effect is that the previously duplicated cleanup traversal to a) update the .doc pointers in libxml2 and b) update the dict names in lxml is now replaced by a single traversal, which should speed things up for large subtrees. --- src/lxml/proxy.pxi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/lxml/proxy.pxi') diff --git a/src/lxml/proxy.pxi b/src/lxml/proxy.pxi index 2b948f26..bc803c22 100644 --- a/src/lxml/proxy.pxi +++ b/src/lxml/proxy.pxi @@ -324,6 +324,8 @@ cdef int moveNodeToDocument(_Document doc, xmlDoc* c_source_doc, """ cdef xmlNode* c_start_node cdef xmlNode* c_node + cdef xmlDoc* c_doc = doc._c_doc + cdef tree.xmlAttr* c_attr cdef char* c_name cdef _nscache c_ns_cache = [NULL, 0, 0] cdef xmlNs* c_ns @@ -339,6 +341,9 @@ cdef int moveNodeToDocument(_Document doc, xmlDoc* c_source_doc, c_start_node = c_element tree.BEGIN_FOR_EACH_FROM(c_element, c_element, 1) + # 0) set C doc link + c_element.doc = c_doc + if tree._isElementOrXInclude(c_element): if hasProxy(c_element): proxy_count += 1 @@ -387,6 +392,15 @@ cdef int moveNodeToDocument(_Document doc, xmlDoc* c_source_doc, c_node = c_element.properties else: c_node = c_node.next + + if c_node: + # set C doc link also for properties + c_node.doc = c_doc + # remove attribute from ID table (see xmlSetTreeDoc() in libxml2's tree.c) + c_attr = c_node + if c_attr.atype == tree.XML_ATTRIBUTE_ID: + tree.xmlRemoveID(c_source_doc, c_attr) + tree.END_FOR_EACH_FROM(c_element) # free now unused namespace declarations -- cgit v1.2.1