diff options
author | Benjamin Eberlei <kontakt@beberlei.de> | 2019-09-23 22:08:21 +0200 |
---|---|---|
committer | Benjamin Eberlei <kontakt@beberlei.de> | 2019-10-05 18:56:58 +0200 |
commit | 6c963694b1399aeb4171b933767be92555c2927a (patch) | |
tree | 1e9b39eeb8e3e09eaab080ab88eed374108d7e88 | |
parent | 375ceefec00df23c71bbc164e272ff41f68c91bc (diff) | |
download | php-git-6c963694b1399aeb4171b933767be92555c2927a.tar.gz |
ext/dom: Add global registerNodeNS flag on DOMXPath ctor and property.
-rw-r--r-- | ext/dom/dom_properties.h | 2 | ||||
-rw-r--r-- | ext/dom/php_dom.c | 2 | ||||
-rw-r--r-- | ext/dom/php_dom.h | 1 | ||||
-rw-r--r-- | ext/dom/tests/bug55700.phpt | 40 | ||||
-rw-r--r-- | ext/dom/xpath.c | 32 |
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, ®ister_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, ®ister_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"); |