Skip to content

Commit 7974c62

Browse files
committed
Fix using Dom\Node with Dom\XPath callbacks
This code was introduced when the Dom\Node and DOMNode classes were still aliases, so the type check was never updated. We fix this by checking if the doc pointer follows the spec and pick the right node CE based on that. Closes GH-17888.
1 parent 2c911e4 commit 7974c62

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ PHP NEWS
2424
. Fixed bug GH-17802 (\Dom\HTMLDocument querySelector attribute name is case
2525
sensitive in HTML). (nielsdos)
2626
. Fixed bug GH-17847 (xinclude destroys live node). (nielsdos)
27+
. Fix using Dom\Node with Dom\XPath callbacks. (nielsdos)
2728

2829
- GD:
2930
. Fixed bug GH-17703 (imagescale with both width and height negative values
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Returning a Dom\Node from Dom\XPath callback
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$dom = Dom\XMLDocument::createFromString('<root/>');
9+
$xpath = new Dom\XPath($dom);
10+
$xpath->registerPhpFunctionNs('urn:x', 'test', fn() => $dom->createElement('foo'));
11+
$xpath->registerNamespace('x', 'urn:x');
12+
$test = $xpath->query('x:test()');
13+
var_dump($test[0]->nodeName);
14+
15+
?>
16+
--EXPECT--
17+
string(3) "foo"

ext/dom/xpath_callbacks.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
2525

2626
#include "php_dom.h"
27+
#include "internal_helpers.h"
2728
#include <libxml/parserInternals.h>
2829

2930
static void xpath_callbacks_entry_dtor(zval *zv)
@@ -425,7 +426,8 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat
425426
}
426427

427428
if (Z_TYPE(callback_retval) != IS_UNDEF) {
428-
if (Z_TYPE(callback_retval) == IS_OBJECT && instanceof_function(Z_OBJCE(callback_retval), dom_node_class_entry)) {
429+
if (Z_TYPE(callback_retval) == IS_OBJECT
430+
&& (instanceof_function(Z_OBJCE(callback_retval), dom_get_node_ce(php_dom_follow_spec_node((const xmlNode *) ctxt->context->doc))))) {
429431
xmlNode *nodep;
430432
dom_object *obj;
431433
if (xpath_callbacks->node_list == NULL) {
@@ -439,7 +441,7 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat
439441
} else if (Z_TYPE(callback_retval) == IS_FALSE || Z_TYPE(callback_retval) == IS_TRUE) {
440442
valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(callback_retval) == IS_TRUE));
441443
} else if (Z_TYPE(callback_retval) == IS_OBJECT) {
442-
zend_type_error("Only objects that are instances of DOMNode can be converted to an XPath expression");
444+
zend_type_error("Only objects that are instances of DOM nodes can be converted to an XPath expression");
443445
zval_ptr_dtor(&callback_retval);
444446
return FAILURE;
445447
} else {

ext/xsl/tests/xslt_non_dom_node.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ try {
2828
}
2929
?>
3030
--EXPECT--
31-
Only objects that are instances of DOMNode can be converted to an XPath expression
31+
Only objects that are instances of DOM nodes can be converted to an XPath expression

0 commit comments

Comments
 (0)