diff --git a/NEWS b/NEWS index 36c49a8635a..08ad143e4e9 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,7 @@ PHP NEWS . Fixed bug #79701 (getElementById does not correctly work with duplicate definitions). (nielsdos) . Implemented "New ext-dom features in PHP 8.4" RFC. (nielsdos) + . Fixed GH-14698 (segfault on DOM node dereference). (David Carlier) - Fileinfo: . Update to libmagic 5.45. (nielsdos) diff --git a/ext/dom/tests/gh14698.phpt b/ext/dom/tests/gh14698.phpt new file mode 100644 index 00000000000..b4d61b5daa6 --- /dev/null +++ b/ext/dom/tests/gh14698.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-14698 crash on DOM node dereference +--EXTENSIONS-- +dom +--CREDITS-- +YuanchengJiang +--FILE-- +loadHTML('xx'); + $html = simplexml_import_dom($dom); + foreach ($html->body->span as $obj) { + } + $script1_dataflow = $html; + $array = ['foo']; + foreach ($array as $key => &$value) { + unset($script1_dataflow[$key]); + } + echo "DONE"; +?> +--EXPECTF-- +DONE diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 8a6c5dec88a..26e0c289183 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -329,9 +329,13 @@ PHP_LIBXML_API void php_libxml_node_free_list(xmlNodePtr node) /* This ensures that namespace references in this subtree are defined within this subtree, * otherwise a use-after-free would be possible when the original namespace holder gets freed. */ php_libxml_node_ptr *ptr = curnode->_private; - php_libxml_node_object *obj = ptr->_private; - if (!obj->document || obj->document->class_type < PHP_LIBXML_CLASS_MODERN) { - xmlReconciliateNs(curnode->doc, curnode); + + /* Checking in case it runs out of reference */ + if (ptr->_private) { + php_libxml_node_object *obj = ptr->_private; + if (!obj->document || obj->document->class_type < PHP_LIBXML_CLASS_MODERN) { + xmlReconciliateNs(curnode->doc, curnode); + } } } /* Skip freeing */