@@ -146,6 +146,22 @@ static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
146146 }
147147}
148148
149+ /* Citing from the docs (https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlAddChild):
150+ * "Add a new node to @parent, at the end of the child (or property) list merging adjacent TEXT nodes (in which case @cur is freed)".
151+ * So we must use a custom way of adding that does not merge. */
152+ static void dom_add_child_without_merging (xmlNodePtr parent , xmlNodePtr child )
153+ {
154+ if (parent -> children == NULL ) {
155+ parent -> children = child ;
156+ } else {
157+ xmlNodePtr last = parent -> last ;
158+ last -> next = child ;
159+ child -> prev = last ;
160+ }
161+ parent -> last = child ;
162+ child -> parent = parent ;
163+ }
164+
149165xmlNode * dom_zvals_to_fragment (php_libxml_ref_obj * document , xmlNode * contextNode , zval * nodes , int nodesc )
150166{
151167 xmlDoc * documentNode ;
@@ -178,7 +194,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
178194 * So we must take a copy if this situation arises to prevent a use-after-free. */
179195 bool will_free = newNode -> type == XML_TEXT_NODE && fragment -> last && fragment -> last -> type == XML_TEXT_NODE ;
180196 if (will_free ) {
181- newNode = xmlCopyNode (newNode , 1 );
197+ newNode = xmlCopyNode (newNode , 0 );
182198 }
183199
184200 if (newNode -> type == XML_DOCUMENT_FRAG_NODE ) {
@@ -187,9 +203,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
187203 while (newNode ) {
188204 xmlNodePtr next = newNode -> next ;
189205 xmlUnlinkNode (newNode );
190- if (!xmlAddChild (fragment , newNode )) {
191- goto err ;
192- }
206+ dom_add_child_without_merging (fragment , newNode );
193207 newNode = next ;
194208 }
195209 } else if (!xmlAddChild (fragment , newNode )) {
0 commit comments