Destroy xpath callbacks at the time when the reconstruction happens

This commit is contained in:
Niels Dossche 2024-02-22 23:56:49 +01:00
parent 01f1c60008
commit 657167f17b
3 changed files with 58 additions and 0 deletions

View file

@ -0,0 +1,53 @@
--TEST--
DOMXPath: Calling __construct() again when functions were already registered
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (!class_exists('DOMXPath')) die('skip no xpath support');
?>
--FILE--
<?php
$dom = new DOMDocument;
$dom->loadXML('<root/>');
class Test {
public function __destruct() {
echo "destruct\n";
}
public function test() {
echo "test\n";
}
}
echo "=== First run ===\n";
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('foo', 'urn:foo');
$xpath->registerPhpFunctionNS('urn:foo', 'test', [new Test, 'test']);
echo "=== Reconstruct ===\n";
$xpath->__construct($dom, true);
echo "=== Second run ===\n";
$xpath->registerNamespace('foo', 'urn:foo');
$xpath->query('//*[foo:test()]');
$xpath->registerPhpFunctionNS('urn:foo', 'test', [new Test, 'test']);
$xpath->query('//*[foo:test()]');
?>
--EXPECTF--
=== First run ===
=== Reconstruct ===
destruct
=== Second run ===
Warning: DOMXPath::query(): xmlXPathCompOpEval: function test not found in %s on line %d
Warning: DOMXPath::query(): Unregistered function in %s on line %d
test
destruct

View file

@ -137,6 +137,8 @@ PHP_METHOD(DOMXPath, __construct)
if (oldctx != NULL) { if (oldctx != NULL) {
php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom); php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom);
xmlXPathFreeContext(oldctx); xmlXPathFreeContext(oldctx);
php_dom_xpath_callbacks_dtor(&intern->xpath_callbacks);
php_dom_xpath_callbacks_ctor(&intern->xpath_callbacks);
} }
xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString", xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString",

View file

@ -46,6 +46,9 @@ PHP_DOM_EXPORT void php_dom_xpath_callback_ns_dtor(php_dom_xpath_callback_ns *ns
PHP_DOM_EXPORT void php_dom_xpath_callbacks_ctor(php_dom_xpath_callbacks *registry) PHP_DOM_EXPORT void php_dom_xpath_callbacks_ctor(php_dom_xpath_callbacks *registry)
{ {
registry->php_ns = NULL;
registry->namespaces = NULL;
registry->node_list = NULL;
} }
PHP_DOM_EXPORT void php_dom_xpath_callbacks_clean_node_list(php_dom_xpath_callbacks *registry) PHP_DOM_EXPORT void php_dom_xpath_callbacks_clean_node_list(php_dom_xpath_callbacks *registry)