From 043b9e1f13c4fd522b92e6a245a08278e14118ee Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:36:39 +0200 Subject: [PATCH] Fix GH-16039: Segmentation fault (access null pointer) in ext/dom/parentnode/tree.c dom_object_get_node() can fail if we don't have a user object associated. Closes GH-16056. --- NEWS | 4 ++++ ext/dom/parentnode.c | 5 +++++ ext/dom/tests/gh16039.phpt | 31 +++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 ext/dom/tests/gh16039.phpt diff --git a/NEWS b/NEWS index f127cce068f..90c4c40d53a 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ PHP NEWS . Fixed regression where signs after the first one were ignored while parsing a signed integer, with the DateTimeInterface::modify() function. (Derick) +- DOM: + . Fixed bug GH-16039 (Segmentation fault (access null pointer) in + ext/dom/parentnode/tree.c). (nielsdos) + - PHPDBG: . Fixed bug GH-15901 (phpdbg: Assertion failure on i funcs). (cmb) diff --git a/ext/dom/parentnode.c b/ext/dom/parentnode.c index c30db6fcd74..ea4edb07743 100644 --- a/ext/dom/parentnode.c +++ b/ext/dom/parentnode.c @@ -272,6 +272,11 @@ static zend_result dom_sanity_check_node_list_for_insertion(php_libxml_ref_obj * if (instanceof_function(ce, dom_node_class_entry)) { xmlNodePtr node = dom_object_get_node(Z_DOMOBJ_P(nodes + i)); + if (!node) { + php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); + return FAILURE; + } + if (node->doc != documentNode) { php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(document)); return FAILURE; diff --git a/ext/dom/tests/gh16039.phpt b/ext/dom/tests/gh16039.phpt new file mode 100644 index 00000000000..48a862eda7b --- /dev/null +++ b/ext/dom/tests/gh16039.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-16039 (Segmentation fault (access null pointer) in ext/dom/parentnode/tree.c) +--EXTENSIONS-- +dom +--FILE-- +appendChild($dom->createElement('root')); +try { + $element->prepend('x', new DOMEntity); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +echo $dom->saveXML(); +$dom->strictErrorChecking = false; // Should not have influence +try { + $element->prepend('x', new DOMEntity); +} catch (DOMException $e) { + echo $e->getMessage(), "\n"; +} +echo $dom->saveXML(); + +?> +--EXPECT-- +Invalid State Error + + +Invalid State Error + +