summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Eberlei <kontakt@beberlei.de>2019-09-23 22:08:21 +0200
committerBenjamin Eberlei <kontakt@beberlei.de>2019-10-05 18:56:58 +0200
commit6c963694b1399aeb4171b933767be92555c2927a (patch)
tree1e9b39eeb8e3e09eaab080ab88eed374108d7e88
parent375ceefec00df23c71bbc164e272ff41f68c91bc (diff)
downloadphp-git-6c963694b1399aeb4171b933767be92555c2927a.tar.gz
ext/dom: Add global registerNodeNS flag on DOMXPath ctor and property.
-rw-r--r--ext/dom/dom_properties.h2
-rw-r--r--ext/dom/php_dom.c2
-rw-r--r--ext/dom/php_dom.h1
-rw-r--r--ext/dom/tests/bug55700.phpt40
-rw-r--r--ext/dom/xpath.c32
5 files changed, 73 insertions, 4 deletions
diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h
index 8fb2872b6d..793e18c363 100644
--- a/ext/dom/dom_properties.h
+++ b/ext/dom/dom_properties.h
@@ -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 */
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 6fa3b920cd..cdde529e2f 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -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
@@ -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;
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
index db9b112e29..11ca442df2 100644
--- a/ext/dom/php_dom.h
+++ b/ext/dom/php_dom.h
@@ -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;
diff --git a/ext/dom/tests/bug55700.phpt b/ext/dom/tests/bug55700.phpt
new file mode 100644
index 0000000000..9e00beb53e
--- /dev/null
+++ b/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)
+}
diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c
index bef74a7fb3..5582831698 100644
--- a/ext/dom/xpath.c
+++ b/ext/dom/xpath.c
@@ -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)
@@ -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;
}
@@ -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);
}
}
@@ -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)
{
@@ -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");