@@ -150,6 +150,22 @@ static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
150
150
}
151
151
}
152
152
153
+ /* Citing from the docs (https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlAddChild):
154
+ * "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)".
155
+ * So we must use a custom way of adding that does not merge. */
156
+ static void dom_add_child_without_merging (xmlNodePtr parent , xmlNodePtr child )
157
+ {
158
+ if (parent -> children == NULL ) {
159
+ parent -> children = child ;
160
+ } else {
161
+ xmlNodePtr last = parent -> last ;
162
+ last -> next = child ;
163
+ child -> prev = last ;
164
+ }
165
+ parent -> last = child ;
166
+ child -> parent = parent ;
167
+ }
168
+
153
169
xmlNode * dom_zvals_to_fragment (php_libxml_ref_obj * document , xmlNode * contextNode , zval * nodes , int nodesc )
154
170
{
155
171
int i ;
@@ -183,7 +199,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
183
199
* So we must take a copy if this situation arises to prevent a use-after-free. */
184
200
bool will_free = newNode -> type == XML_TEXT_NODE && fragment -> last && fragment -> last -> type == XML_TEXT_NODE ;
185
201
if (will_free ) {
186
- newNode = xmlCopyNode (newNode , 1 );
202
+ newNode = xmlCopyNode (newNode , 0 );
187
203
}
188
204
189
205
if (newNode -> type == XML_DOCUMENT_FRAG_NODE ) {
@@ -192,9 +208,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
192
208
while (newNode ) {
193
209
xmlNodePtr next = newNode -> next ;
194
210
xmlUnlinkNode (newNode );
195
- if (!xmlAddChild (fragment , newNode )) {
196
- goto err ;
197
- }
211
+ dom_add_child_without_merging (fragment , newNode );
198
212
newNode = next ;
199
213
}
200
214
} else if (!xmlAddChild (fragment , newNode )) {
0 commit comments