diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 828e1bd1af62f..771a2bfdc378a 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -2579,7 +2579,10 @@ xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, if (ns_mapper != NULL) { xmlNodePtr clone = dom_clone_helper(ns_mapper, node, doc, recursive); - if (EXPECTED(clone != NULL) && doc != node->doc) { + /* Defensively set doc to NULL because we should not be using it after this point. + * When cloning a document the new document will be clone->doc, not doc. */ + doc = NULL; + if (EXPECTED(clone != NULL) && clone->doc != node->doc) { /* We only need to reconcile the namespace when the document changes because the namespaces have to be * put into their respective namespace mapper. */ if (clone->type == XML_DOCUMENT_NODE || clone->type == XML_HTML_DOCUMENT_NODE || clone->type == XML_DOCUMENT_FRAG_NODE) { diff --git a/ext/dom/tests/gh15192.phpt b/ext/dom/tests/gh15192.phpt new file mode 100644 index 0000000000000..5ab5d858ecebf --- /dev/null +++ b/ext/dom/tests/gh15192.phpt @@ -0,0 +1,73 @@ +--TEST-- +GH-15192 (Segmentation fault in dom extension (html5_serializer)) +--EXTENSIONS-- +dom +--FILE-- +foo
"); +$dom2 = clone $dom; +$element = $dom2->firstChild; +$dom = new DomDocument(); +var_dump($element); +?> +--EXPECTF-- +object(Dom\HTMLElement)#3 (29) { + ["namespaceURI"]=> + string(28) "http://www.w3.org/1999/xhtml" + ["prefix"]=> + NULL + ["localName"]=> + string(4) "html" + ["tagName"]=> + string(4) "HTML" + ["id"]=> + string(0) "" + ["className"]=> + string(0) "" + ["classList"]=> + string(22) "(object value omitted)" + ["attributes"]=> + string(22) "(object value omitted)" + ["firstElementChild"]=> + string(22) "(object value omitted)" + ["lastElementChild"]=> + string(22) "(object value omitted)" + ["childElementCount"]=> + int(2) + ["previousElementSibling"]=> + NULL + ["nextElementSibling"]=> + NULL + ["innerHTML"]=> + string(36) "foo
" + ["substitutedNodeValue"]=> + string(3) "foo" + ["nodeType"]=> + int(1) + ["nodeName"]=> + string(4) "HTML" + ["baseURI"]=> + string(11) "about:blank" + ["isConnected"]=> + bool(true) + ["ownerDocument"]=> + string(22) "(object value omitted)" + ["parentNode"]=> + string(22) "(object value omitted)" + ["parentElement"]=> + NULL + ["childNodes"]=> + string(22) "(object value omitted)" + ["firstChild"]=> + string(22) "(object value omitted)" + ["lastChild"]=> + string(22) "(object value omitted)" + ["previousSibling"]=> + NULL + ["nextSibling"]=> + NULL + ["nodeValue"]=> + NULL + ["textContent"]=> + string(3) "foo" +}