diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4f84404919fa..5ef6bbddc3bf 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -47,8 +47,6 @@ static zend_module_entry **module_request_shutdown_handlers; static zend_module_entry **module_post_deactivate_handlers; static zend_module_entry **modules_dl_loaded; -static zend_class_entry **class_cleanup_handlers; - ZEND_API void zend_set_dl_use_deepbind(bool use_deepbind) { zend_dl_use_deepbind = use_deepbind; @@ -2561,8 +2559,6 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ int shutdown_count = 0; int post_deactivate_count = 0; int dl_loaded_count = 0; - zend_class_entry *ce; - int class_count = 0; /* Collect extensions with request startup/shutdown handlers */ ZEND_HASH_MAP_FOREACH_PTR(&module_registry, module) { @@ -2609,29 +2605,6 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ modules_dl_loaded[--dl_loaded_count] = module; } } ZEND_HASH_FOREACH_END(); - - /* Collect internal classes with static members */ - ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) { - if (ce->type == ZEND_INTERNAL_CLASS && - ce->default_static_members_count > 0) { - class_count++; - } - } ZEND_HASH_FOREACH_END(); - - class_cleanup_handlers = (zend_class_entry**)perealloc( - class_cleanup_handlers, - sizeof(zend_class_entry*) * - (class_count + 1), true); - class_cleanup_handlers[class_count] = NULL; - - if (class_count) { - ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) { - if (ce->type == ZEND_INTERNAL_CLASS && - ce->default_static_members_count > 0) { - class_cleanup_handlers[--class_count] = ce; - } - } ZEND_HASH_FOREACH_END(); - } } /* }}} */ @@ -2644,8 +2617,6 @@ ZEND_API void zend_startup_modules(void) /* {{{ */ ZEND_API void zend_destroy_modules(void) /* {{{ */ { - free(class_cleanup_handlers); - class_cleanup_handlers = NULL; free(module_request_startup_handlers); module_request_startup_handlers = NULL; zend_hash_graceful_reverse_destroy(&module_registry); diff --git a/ext/dom/node.c b/ext/dom/node.c index 362000792f1a..a3d40a92bfb7 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -951,6 +951,9 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj php_dom_throw_error(NOT_FOUND_ERR, stricterror); RETURN_FALSE; } + if (refp == child) { + refp = child->next; + } } if (child->doc == NULL && parentp->doc != NULL) { @@ -960,7 +963,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj php_libxml_invalidate_node_list_cache(intern->document); - if (ref != NULL) { + if (refp != NULL) { if (child->parent != NULL) { xmlUnlinkNode(child); } diff --git a/ext/dom/tests/gh23365.phpt b/ext/dom/tests/gh23365.phpt new file mode 100644 index 000000000000..bc283b0659d3 --- /dev/null +++ b/ext/dom/tests/gh23365.phpt @@ -0,0 +1,53 @@ +--TEST-- +GH-23365 (DOMNode::insertBefore($n, $n) drops the node and leaves a self-referencing sibling list) +--CREDITS-- +Alexandre Daubois +--EXTENSIONS-- +dom +--FILE-- +loadXML('text'); +$root = $doc->documentElement; + +$text = $root->firstChild; +var_dump($root->insertBefore($text, $text) === $text); +var_dump($root->childNodes->length); +var_dump($text->parentNode === $root, $text->nextSibling === $text, $text->previousSibling === $text); + +$child = $root->lastChild; +var_dump($root->insertBefore($child, $child) === $child); +var_dump($root->childNodes->length); + +echo $doc->saveXML($root), PHP_EOL; + +$doc2 = new DOMDocument(); +$doc2->loadXML(''); +$el = $doc2->documentElement; +$attr = $el->getAttributeNode('a'); +var_dump($el->insertBefore($attr, $attr) === $attr); +echo $doc2->saveXML($el), PHP_EOL; + +$doc3 = new DOMDocument(); +$root3 = $doc3->appendChild($doc3->createElement('root')); +$root3->appendChild($doc3->createTextNode('A')); +$t = $root3->appendChild($doc3->createTextNode('B')); +$root3->insertBefore($t, $t); +$root3->appendChild($t); +echo $doc3->saveXML($root3), PHP_EOL; +unset($t, $root3, $doc3); +echo "done", PHP_EOL; +?> +--EXPECT-- +bool(true) +int(2) +bool(true) +bool(false) +bool(false) +bool(true) +int(2) +text +bool(true) + +AB +done