summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnout Boks <arnoutboks@gmail.com>2017-01-25 21:09:03 +0100
committerJoe Watkins <krakjoe@php.net>2017-01-25 20:59:25 +0000
commit721a189742acc6fb6c2c6d98ce86eebe4e34d42a (patch)
treed21a5f709c4a12b653ca26a842df0a10465a5460
parent737ee0661c15f5eb812467c3e10ee1f784691be9 (diff)
downloadphp-git-721a189742acc6fb6c2c6d98ce86eebe4e34d42a.tar.gz
Fix bug #54382 (getAttributeNodeNS doesn't get xmlns* attributes)
The fix is based on the same strategy for handling namespace declarations as used by getAttributeNode. Note that this strategy makes these methods not return a DOMAttr for xmlns* attributes, but an instance of the (undocumented) class DOMNameSpaceNode. This is not really ideal, but at least this fix makes the behavior of getAttributeNode and getAttributeNodeNS consistent. A follow-up action would be to investigate whether DOMNameSpaceNode can be made into a subclass of DOMAttr (which may be hard due to the way libxml treats namespace declarations) or document this deviating return value for xmlns* attributes.
-rw-r--r--ext/dom/element.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/ext/dom/element.c b/ext/dom/element.c
index d9fa381717..df841b6b8a 100644
--- a/ext/dom/element.c
+++ b/ext/dom/element.c
@@ -921,7 +921,7 @@ Since: DOM Level 2
PHP_FUNCTION(dom_element_get_attribute_node_ns)
{
zval *id;
- xmlNodePtr elemp;
+ xmlNodePtr elemp, fakeAttrp;
xmlAttrPtr attrp;
dom_object *intern;
size_t uri_len, name_len;
@@ -937,10 +937,34 @@ PHP_FUNCTION(dom_element_get_attribute_node_ns)
attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
if (attrp == NULL) {
- RETURN_NULL();
- }
+ if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ xmlNsPtr nsptr;
+ nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
+ if (nsptr != NULL) {
+ xmlNsPtr curns;
+ curns = xmlNewNs(NULL, nsptr->href, NULL);
+ if (nsptr->prefix) {
+ curns->prefix = xmlStrdup((xmlChar *) nsptr->prefix);
+ }
+ if (nsptr->prefix) {
+ fakeAttrp = xmlNewDocNode(elemp->doc, NULL, (xmlChar *) nsptr->prefix, nsptr->href);
+ } else {
+ fakeAttrp = xmlNewDocNode(elemp->doc, NULL, (xmlChar *)"xmlns", nsptr->href);
+ }
+ fakeAttrp->type = XML_NAMESPACE_DECL;
+ fakeAttrp->parent = elemp;
+ fakeAttrp->ns = curns;
- DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+ DOM_RET_OBJ(fakeAttrp, &ret, intern);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+ }
}
/* }}} end dom_element_get_attribute_node_ns */