diff --git a/ext/xsl/tests/bug69168.phpt b/ext/xsl/tests/bug69168.phpt
new file mode 100644
index 0000000000000..41fc3aafd8209
--- /dev/null
+++ b/ext/xsl/tests/bug69168.phpt
@@ -0,0 +1,43 @@
+--TEST--
+bug #69168 (DomNode::getNodePath() returns invalid path)
+--EXTENSIONS--
+xsl
+--FILE--
+bobjoe
+EOB;
+$xsl = <<
+
+
+
+
+
+
+
+EOB;
+
+function getPath($input){
+ $input[0]->nodeValue .= 'a';
+ return $input[0]->getNodePath() . ' = ' . $input[0]->nodeValue;
+}
+
+$proc = new XSLTProcessor();
+$proc->registerPHPFunctions();
+$xslDoc = new DOMDocument();
+$xslDoc->loadXML($xsl);
+@$proc->importStyleSheet($xslDoc);
+$xmlDoc = new DOMDocument();
+$xmlDoc->loadXML($xml);
+echo @$proc->transformToXML($xmlDoc);
+
+// Tests modification of the nodes
+var_dump($xmlDoc->firstChild->firstChild->firstChild->getNodePath());
+var_dump($xmlDoc->firstChild->firstChild->firstChild->nodeValue);
+?>
+--EXPECT--
+
+/allusers/user[1]/uid = boba
/allusers/user[2]/uid = joea
+string(21) "/allusers/user[1]/uid"
+string(4) "boba"
diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c
index c62c0a13ceaec..8dbe6b27a113b 100644
--- a/ext/xsl/xsltprocessor.c
+++ b/ext/xsl/xsltprocessor.c
@@ -194,7 +194,19 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
node->parent = nsparent;
node->ns = curns;
} else {
- node = xmlDocCopyNode(node, domintern->document->ptr, 1);
+ /**
+ * 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.
+ * To prevent this, we'll take a copy if the node is not from the main document.
+ * It is important that we do not copy the node unconditionally, because that means that:
+ * - modifications to the node will only modify the copy, and not the original
+ * - accesses to the parent, path, ... will not work
+ */
+ xsltTransformContextPtr transform_ctxt = (xsltTransformContextPtr) ctxt->context->extra;
+ if (node->doc != transform_ctxt->document->doc) {
+ node = xmlDocCopyNode(node, domintern->document->ptr, 1);
+ }
}
php_dom_create_object(node, &child, domintern);