diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2019-02-05 21:31:02 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2019-02-05 21:31:02 +0100 |
commit | 201b712edf0478e6a94ace984c1e8435bf3bc3c3 (patch) | |
tree | 1ebf9a07fd10d3f17aa423d11294bdb58b7627f0 /src/lxml/proxy.pxi | |
parent | 7303cadd01b81fceb40f74148a5b9b6178936768 (diff) | |
download | python-lxml-201b712edf0478e6a94ace984c1e8435bf3bc3c3.tar.gz |
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.
Diffstat (limited to 'src/lxml/proxy.pxi')
-rw-r--r-- | src/lxml/proxy.pxi | 14 |
1 files changed, 14 insertions, 0 deletions
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 = <xmlNode*>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 = <tree.xmlAttr*>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 |