Skip to content

Commit

Permalink
ext/dom: Add global registerNodeNS flag on DOMXPath ctor and property.
Browse files Browse the repository at this point in the history
  • Loading branch information
beberlei committed Oct 5, 2019
1 parent 375ceef commit 6c96369
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
2 changes: 2 additions & 0 deletions ext/dom/dom_properties.h
Expand Up @@ -128,6 +128,8 @@ int dom_text_whole_text_read(dom_object *obj, zval *retval);
#if defined(LIBXML_XPATH_ENABLED)
/* xpath properties */
int dom_xpath_document_read(dom_object *obj, zval *retval);
int dom_xpath_register_node_ns_read(dom_object *obj, zval *retval);
int dom_xpath_register_node_ns_write(dom_object *obj, zval *newval);
#endif

#endif /* DOM_PROPERTIERS_H */
2 changes: 2 additions & 0 deletions ext/dom/php_dom.c
Expand Up @@ -768,6 +768,7 @@ PHP_MINIT_FUNCTION(dom)

zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1);
dom_register_prop_handler(&dom_xpath_prop_handlers, "document", sizeof("document")-1, dom_xpath_document_read, NULL);
dom_register_prop_handler(&dom_xpath_prop_handlers, "registerNodeNamespaces", sizeof("registerNodeNamespaces")-1, dom_xpath_register_node_ns_read, dom_xpath_register_node_ns_write);
zend_hash_add_ptr(&classes, ce.name, &dom_xpath_prop_handlers);
#endif

Expand Down Expand Up @@ -1017,6 +1018,7 @@ zend_object *dom_xpath_objects_new(zend_class_entry *class_type)
dom_xpath_object *intern = zend_object_alloc(sizeof(dom_xpath_object), class_type);

intern->registered_phpfunctions = zend_new_array(0);
intern->register_node_ns = 1;

intern->dom.prop_handler = &dom_xpath_prop_handlers;
intern->dom.std.handlers = &dom_xpath_object_handlers;
Expand Down
1 change: 1 addition & 0 deletions ext/dom/php_dom.h
Expand Up @@ -65,6 +65,7 @@ extern zend_module_entry dom_module_entry;

typedef struct _dom_xpath_object {
int registerPhpFunctions;
int register_node_ns;
HashTable *registered_phpfunctions;
HashTable *node_list;
dom_object dom;
Expand Down
40 changes: 40 additions & 0 deletions ext/dom/tests/bug55700.phpt
@@ -0,0 +1,40 @@
--TEST--
Bug #55700 (XPath namespace prefix conflict, global registerNodeNS flag)
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$doc = new DOMDocument();
$doc->loadXML('<prefix:root xmlns:prefix="urn:a" />');

$xp = new DOMXPath($doc, true);
$xp->registerNamespace('prefix', 'urn:b');

echo($xp->query('//prefix:root')->length . "\n");

$xp = new DOMXPath($doc, false);
$xp->registerNamespace('prefix', 'urn:b');

echo($xp->query('//prefix:root')->length . "\n");

var_dump($xp->registerNodeNamespaces);
$xp->registerNodeNamespaces = true;

var_dump($xp->registerNodeNamespaces);

echo($xp->query('//prefix:root')->length . "\n");

var_dump($xp);
?>
--EXPECT--
1
0
bool(false)
bool(true)
1
object(DOMXPath)#4 (2) {
["document"]=>
string(22) "(object value omitted)"
["registerNodeNamespaces"]=>
bool(true)
}
32 changes: 28 additions & 4 deletions ext/dom/xpath.c
Expand Up @@ -35,6 +35,7 @@
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_construct, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, doc, DOMDocument, 0)
ZEND_ARG_INFO(0, registerNodeNS)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_ns, 0, 0, 2)
Expand Down Expand Up @@ -249,12 +250,13 @@ static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt, int
PHP_METHOD(domxpath, __construct)
{
zval *doc;
zend_bool register_node_ns = 1;
xmlDocPtr docp = NULL;
dom_object *docobj;
dom_xpath_object *intern;
xmlXPathContextPtr ctx, oldctx;

if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &doc, dom_document_class_entry) == FAILURE) {
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O|b", &doc, dom_document_class_entry, &register_node_ns) == FAILURE) {
return;
}

Expand Down Expand Up @@ -284,6 +286,7 @@ PHP_METHOD(domxpath, __construct)
intern->dom.ptr = ctx;
ctx->userData = (void *)intern;
intern->dom.document = docobj->document;
intern->register_node_ns = register_node_ns;
php_libxml_increment_doc_ref((php_libxml_node_object *) &intern->dom, docp);
}
}
Expand All @@ -304,6 +307,26 @@ int dom_xpath_document_read(dom_object *obj, zval *retval)
}
/* }}} */

/* {{{ registerNodeNamespaces bool*/
static inline dom_xpath_object *php_xpath_obj_from_dom_obj(dom_object *obj) {
return (dom_xpath_object*)((char*)(obj) - XtOffsetOf(dom_xpath_object, dom));
}

int dom_xpath_register_node_ns_read(dom_object *obj, zval *retval)
{
ZVAL_BOOL(retval, php_xpath_obj_from_dom_obj(obj)->register_node_ns);

return SUCCESS;
}

int dom_xpath_register_node_ns_write(dom_object *obj, zval *newval)
{
php_xpath_obj_from_dom_obj(obj)->register_node_ns = zend_is_true(newval);

return SUCCESS;
}
/* }}} */

/* {{{ proto bool dom_xpath_register_ns(string prefix, string uri) */
PHP_FUNCTION(dom_xpath_register_ns)
{
Expand Down Expand Up @@ -354,15 +377,16 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
char *expr;
xmlDoc *docp = NULL;
xmlNsPtr *ns = NULL;
zend_bool register_node_ns = 1;
zend_bool register_node_ns;

id = ZEND_THIS;
intern = Z_XPATHOBJ_P(id);
register_node_ns = intern->register_node_ns;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|O!b", &expr, &expr_len, &context, dom_node_class_entry, &register_node_ns) == FAILURE) {
return;
}

intern = Z_XPATHOBJ_P(id);

ctxp = (xmlXPathContextPtr) intern->dom.ptr;
if (ctxp == NULL) {
php_error_docref(NULL, E_WARNING, "Invalid XPath Context");
Expand Down

0 comments on commit 6c96369

Please sign in to comment.