@@ -146,6 +146,22 @@ static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
146
146
}
147
147
}
148
148
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
+
149
165
xmlNode * dom_zvals_to_fragment (php_libxml_ref_obj * document , xmlNode * contextNode , zval * nodes , int nodesc )
150
166
{
151
167
xmlDoc * documentNode ;
@@ -178,7 +194,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
178
194
* So we must take a copy if this situation arises to prevent a use-after-free. */
179
195
bool will_free = newNode -> type == XML_TEXT_NODE && fragment -> last && fragment -> last -> type == XML_TEXT_NODE ;
180
196
if (will_free ) {
181
- newNode = xmlCopyNode (newNode , 1 );
197
+ newNode = xmlCopyNode (newNode , 0 );
182
198
}
183
199
184
200
if (newNode -> type == XML_DOCUMENT_FRAG_NODE ) {
@@ -187,9 +203,7 @@ xmlNode* dom_zvals_to_fragment(php_libxml_ref_obj *document, xmlNode *contextNod
187
203
while (newNode ) {
188
204
xmlNodePtr next = newNode -> next ;
189
205
xmlUnlinkNode (newNode );
190
- if (!xmlAddChild (fragment , newNode )) {
191
- goto err ;
192
- }
206
+ dom_add_child_without_merging (fragment , newNode );
193
207
newNode = next ;
194
208
}
195
209
} else if (!xmlAddChild (fragment , newNode )) {
0 commit comments