Skip to content

Commit a2deee2

Browse files
committed
Fix bug #69168: DomNode::getNodePath() returns invalid path
Upon freeing libxslt's context, every document which is not the *main* document will be freed by libxslt. If a node of a document which is not the main document gets returned to userland, we'd free the node twice: - first by the cleanup of the xslt context - and then by our own refcounting mechanism. This was reported in bug #49634, and was fixed by always copying the node (and later re-fixed in bug #70078). The original fix is not entirely correct unfortunately because of the following two main reasons: - modifications to the node will only modify the copy, and not the original - accesses to the parent, path, ... will not work This patch fixes it properly by only copying the node if it origins from a document other than the main document.
1 parent e951202 commit a2deee2

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

ext/xsl/xsltprocessor.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,19 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
194194
node->parent = nsparent;
195195
node->ns = curns;
196196
} else {
197-
node = xmlDocCopyNode(node, domintern->document->ptr, 1);
197+
/**
198+
* Upon freeing libxslt's context, every document which is not the *main* document will be freed by libxslt.
199+
* If a node of a document which is *not the main* document gets returned to userland, we'd free the node twice:
200+
* first by the cleanup of the xslt context, and then by our own refcounting mechanism.
201+
* To prevent this, we'll take a copy if the node is not from the main document.
202+
* It is important that we do not copy the node unconditionally, because that means that:
203+
* - modifications to the node will only modify the copy, and not the original
204+
* - accesses to the parent, path, ... will not work
205+
*/
206+
xsltTransformContextPtr transform_ctxt = (xsltTransformContextPtr) ctxt->context->extra;
207+
if (node->doc != transform_ctxt->document->doc) {
208+
node = xmlDocCopyNode(node, domintern->document->ptr, 1);
209+
}
198210
}
199211

200212
php_dom_create_object(node, &child, domintern);

0 commit comments

Comments
 (0)