diff --git a/ext/dom/node.c b/ext/dom/node.c index ee14fd158fc..172172c47f0 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -906,6 +906,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj } if (child->doc == NULL && parentp->doc != NULL) { + xmlSetTreeDoc(child, parentp->doc); dom_set_document_ref_pointers(child, intern->document); } @@ -1212,6 +1213,7 @@ static void dom_node_replace_child(INTERNAL_FUNCTION_PARAMETERS, bool modern) } if (newchild->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(newchild, nodep->doc); dom_set_document_ref_pointers(newchild, intern->document); } @@ -1320,6 +1322,7 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern, } if (child->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(child, nodep->doc); dom_set_document_ref_pointers(child, intern->document); } diff --git a/ext/dom/tests/gh16777_1.phpt b/ext/dom/tests/gh16777_1.phpt new file mode 100644 index 00000000000..d821842ace4 --- /dev/null +++ b/ext/dom/tests/gh16777_1.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16777 (Calling the constructor again on a DOM object after it is in a document causes UAF) +--EXTENSIONS-- +dom +--FILE-- +appendChild($text); +$text->__construct('my new value'); +$doc->appendChild($text); +echo $doc->saveXML(); +$dom2 = new DOMDocument(); +try { + $dom2->appendChild($text); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- + +my value +my new value +Wrong Document Error diff --git a/ext/dom/tests/gh16777_2.phpt b/ext/dom/tests/gh16777_2.phpt new file mode 100644 index 00000000000..a6f3a59621b --- /dev/null +++ b/ext/dom/tests/gh16777_2.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-16777 (Calling the constructor again on a DOM object after it is in a document causes UAF) +--EXTENSIONS-- +dom +--FILE-- +append($child = new DOMElement('child')); +$doc = new DOMDocument(); +$doc->appendChild($el); +$el->__construct('newname'); +$doc->appendChild($el); +echo $doc->saveXML(); +$dom2 = new DOMDocument(); +try { + $dom2->appendChild($el); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +var_dump($child->ownerDocument === $doc); +?> +--EXPECT-- + + + +Wrong Document Error +bool(true) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 49f3b2b4e67..2e47968e676 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -2479,7 +2479,11 @@ static zval *php_sxe_iterator_current_data(zend_object_iterator *iter) /* {{{ */ { php_sxe_iterator *iterator = (php_sxe_iterator *)iter; - return &iterator->sxe->iter.data; + zval *data = &iterator->sxe->iter.data; + if (Z_ISUNDEF_P(data)) { + return NULL; + } + return data; } /* }}} */ diff --git a/ext/simplexml/tests/gh16808.phpt b/ext/simplexml/tests/gh16808.phpt new file mode 100644 index 00000000000..be0bc59fb65 --- /dev/null +++ b/ext/simplexml/tests/gh16808.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-16808 (Segmentation fault in RecursiveIteratorIterator->current() with a xml element input) +--EXTENSIONS-- +simplexml +--FILE-- +"); +$test = new RecursiveIteratorIterator($sxe); +var_dump($test->current()); +?> +--EXPECT-- +NULL