Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/dom/namednodemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ PHP_METHOD(DOMNamedNodeMap, getNamedItem)
}

dom_nnodemap_object *objmap = Z_DOMOBJ_P(ZEND_THIS)->ptr;
php_dom_obj_map_get_ns_named_item_into_zval(objmap, named, NULL, return_value);
php_dom_obj_map_get_ns_named_item_into_zval(objmap, named, NULL, false, return_value);
}
/* }}} end dom_namednodemap_get_named_item */

Expand Down Expand Up @@ -111,7 +111,7 @@ PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
if (urilen == 0 && objmap->baseobj != NULL && php_dom_follow_spec_intern(objmap->baseobj)) {
uri = NULL;
}
php_dom_obj_map_get_ns_named_item_into_zval(objmap, named, uri, return_value);
php_dom_obj_map_get_ns_named_item_into_zval(objmap, named, uri, true, return_value);
}
}
/* }}} end dom_namednodemap_get_named_item_ns */
Expand Down
43 changes: 21 additions & 22 deletions ext/dom/obj_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,9 @@ void php_dom_obj_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long i
}
}

void php_dom_obj_map_get_ns_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, const char *ns, zval *return_value)
void php_dom_obj_map_get_ns_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, const char *ns, bool use_ns, zval *return_value)
{
xmlNodePtr itemnode = objmap->handler->get_ns_named_item(objmap, named, ns);
xmlNodePtr itemnode = objmap->handler->get_ns_named_item(objmap, named, ns, use_ns);
if (itemnode) {
DOM_RET_OBJ(itemnode, objmap->baseobj);
} else {
Expand All @@ -490,17 +490,17 @@ void php_dom_obj_map_get_ns_named_item_into_zval(dom_nnodemap_object *objmap, co
* === Named item === *
**********************/

static xmlNodePtr dom_map_get_ns_named_item_entity(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static xmlNodePtr dom_map_get_ns_named_item_entity(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
return xmlHashLookup(map->ht, BAD_CAST ZSTR_VAL(named));
}

static bool dom_map_has_ns_named_item_xmlht(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static bool dom_map_has_ns_named_item_xmlht(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
return dom_map_get_ns_named_item_entity(map, named, ns) != NULL;
return dom_map_get_ns_named_item_entity(map, named, ns, use_ns) != NULL;
}

static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
xmlNotationPtr notation = xmlHashLookup(map->ht, BAD_CAST ZSTR_VAL(named));
if (notation) {
Expand All @@ -509,38 +509,37 @@ static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, c
return NULL;
}

static xmlNodePtr dom_map_get_ns_named_item_prop(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static xmlNodePtr dom_map_get_ns_named_item_prop(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
xmlNodePtr nodep = dom_object_get_node(map->baseobj);
if (nodep) {
if (ns) {
xmlNodePtr itemnode = (xmlNodePtr) xmlHasNsProp(nodep, BAD_CAST ZSTR_VAL(named), BAD_CAST ns);
if (itemnode != NULL && itemnode->type == XML_ATTRIBUTE_DECL) {
return NULL;
}
return itemnode;
xmlNodePtr itemnode;
if (use_ns) {
itemnode = (xmlNodePtr) xmlHasNsProp(nodep, BAD_CAST ZSTR_VAL(named), BAD_CAST ns);
} else if (php_dom_follow_spec_intern(map->baseobj)) {
itemnode = (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST ZSTR_VAL(named), ZSTR_LEN(named));
} else {
if (php_dom_follow_spec_intern(map->baseobj)) {
return (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST ZSTR_VAL(named), ZSTR_LEN(named));
} else {
return (xmlNodePtr) xmlHasProp(nodep, BAD_CAST ZSTR_VAL(named));
}
itemnode = (xmlNodePtr) xmlHasProp(nodep, BAD_CAST ZSTR_VAL(named));
}
if (itemnode != NULL && itemnode->type == XML_ATTRIBUTE_DECL) {
return NULL;
}
return itemnode;
}
return NULL;
}

static bool dom_map_has_ns_named_item_prop(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static bool dom_map_has_ns_named_item_prop(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
return dom_map_get_ns_named_item_prop(map, named, ns) != NULL;
return dom_map_get_ns_named_item_prop(map, named, ns, use_ns) != NULL;
}

static xmlNodePtr dom_map_get_ns_named_item_null(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static xmlNodePtr dom_map_get_ns_named_item_null(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
return NULL;
}

static bool dom_map_has_ns_named_item_null(dom_nnodemap_object *map, const zend_string *named, const char *ns)
static bool dom_map_has_ns_named_item_null(dom_nnodemap_object *map, const zend_string *named, const char *ns, bool use_ns)
{
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions ext/dom/obj_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ typedef struct php_dom_obj_map_collection_iter {
typedef struct php_dom_obj_map_handler {
zend_long (*length)(dom_nnodemap_object *);
void (*get_item)(dom_nnodemap_object *, zend_long, zval *);
xmlNodePtr (*get_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
bool (*has_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
xmlNodePtr (*get_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *, bool);
bool (*has_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *, bool);
void (*collection_named_item_iter)(dom_nnodemap_object *, php_dom_obj_map_collection_iter *);
bool use_cache;
bool nameless;
Expand Down Expand Up @@ -57,7 +57,7 @@ typedef struct dom_nnodemap_object {
} dom_nnodemap_object;

void php_dom_create_obj_map(dom_object *basenode, dom_object *intern, xmlHashTablePtr ht, zend_string *local, zend_string *ns, const php_dom_obj_map_handler *handler);
void php_dom_obj_map_get_ns_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, const char *ns, zval *return_value);
void php_dom_obj_map_get_ns_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, const char *ns, bool use_ns, zval *return_value);
void php_dom_obj_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value);
zend_long php_dom_get_nodelist_length(dom_object *obj);

Expand Down
8 changes: 4 additions & 4 deletions ext/dom/php_dom.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,7 +2403,7 @@ static zval *dom_nodemap_read_dimension(zend_object *object, zval *offset, int t
zend_long lval;
if (dom_nodemap_or_nodelist_process_offset_as_named(offset, &lval)) {
/* exceptional case, switch to named lookup */
php_dom_obj_map_get_ns_named_item_into_zval(php_dom_obj_from_obj(object)->ptr, Z_STR_P(offset), NULL, rv);
php_dom_obj_map_get_ns_named_item_into_zval(php_dom_obj_from_obj(object)->ptr, Z_STR_P(offset), NULL, false, rv);
return rv;
}

Expand All @@ -2429,7 +2429,7 @@ static int dom_nodemap_has_dimension(zend_object *object, zval *member, int chec
if (dom_nodemap_or_nodelist_process_offset_as_named(member, &offset)) {
/* exceptional case, switch to named lookup */
dom_nnodemap_object *map = php_dom_obj_from_obj(object)->ptr;
return map->handler->has_ns_named_item(map, Z_STR_P(member), NULL);
return map->handler->has_ns_named_item(map, Z_STR_P(member), NULL, false);
}

return offset >= 0 && offset < php_dom_get_namednodemap_length(php_dom_obj_from_obj(object));
Expand All @@ -2450,7 +2450,7 @@ static zval *dom_modern_nodemap_read_dimension(zend_object *object, zval *offset
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), lval)) {
map->handler->get_item(map, (zend_long) lval, rv);
} else {
php_dom_obj_map_get_ns_named_item_into_zval(map, Z_STR_P(offset), NULL, rv);
php_dom_obj_map_get_ns_named_item_into_zval(map, Z_STR_P(offset), NULL, false, rv);
}
} else if (Z_TYPE_P(offset) == IS_LONG) {
map->handler->get_item(map, Z_LVAL_P(offset), rv);
Expand Down Expand Up @@ -2478,7 +2478,7 @@ static int dom_modern_nodemap_has_dimension(zend_object *object, zval *member, i
if (ZEND_HANDLE_NUMERIC(Z_STR_P(member), lval)) {
return (zend_long) lval >= 0 && (zend_long) lval < php_dom_get_namednodemap_length(obj);
} else {
return map->handler->has_ns_named_item(map, Z_STR_P(member), NULL);
return map->handler->has_ns_named_item(map, Z_STR_P(member), NULL, false);
}
} else if (Z_TYPE_P(member) == IS_LONG) {
zend_long offset = Z_LVAL_P(member);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
--TEST--
getNamedItemNS() must match on the local name in a namespace, not on the qualified name
--EXTENSIONS--
dom
--FILE--
<?php
$src = '<root xmlns:q="urn:q" bar="no-ns" q:bar="ns" q:only="prefixed"/>';
$dtd = <<<XML
<?xml version="1.0"?>
<!DOCTYPE root [
<!ELEMENT root EMPTY>
<!ATTLIST root defaulted CDATA "from-dtd">
]>
<root/>
XML;

$legacy = new DOMDocument();
$legacy->loadXML($src);
$legacyDtd = new DOMDocument();
$legacyDtd->loadXML($dtd);

foreach (['legacy' => $legacy, 'spec' => Dom\XMLDocument::createFromString($src)] as $label => $doc) {
echo $label, PHP_EOL;
$map = $doc->documentElement->attributes;
var_dump($map->getNamedItemNS(null, 'bar')?->nodeValue);
var_dump($map->getNamedItemNS('', 'bar')?->nodeValue);
var_dump($map->getNamedItemNS(null, 'q:bar')?->nodeValue);
var_dump($map->getNamedItemNS('', 'q:bar')?->nodeValue);
var_dump($map->getNamedItemNS(null, 'only')?->nodeValue);
var_dump($map->getNamedItemNS('urn:q', 'only')?->nodeValue);
var_dump($map->getNamedItem('q:bar')?->nodeValue);
}

echo 'dtd default', PHP_EOL;
var_dump($legacyDtd->documentElement->attributes->getNamedItemNS(null, 'defaulted')?->nodeValue);
var_dump(Dom\XMLDocument::createFromString($dtd)->documentElement->attributes->getNamedItemNS(null, 'defaulted')?->nodeValue);
?>
--EXPECT--
legacy
string(5) "no-ns"
NULL
NULL
NULL
NULL
string(8) "prefixed"
NULL
spec
string(5) "no-ns"
string(5) "no-ns"
NULL
NULL
NULL
string(8) "prefixed"
string(2) "ns"
dtd default
NULL
NULL
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--TEST--
getNamedItem() must not expose DTD attribute declarations
--EXTENSIONS--
dom
--FILE--
<?php
$xml = <<<XML
<?xml version="1.0"?>
<!DOCTYPE root [
<!ELEMENT root EMPTY>
<!ATTLIST root defaulted CDATA "from-dtd">
]>
<root real="present"/>
XML;

$legacy = new DOMDocument();
$legacy->loadXML($xml);

foreach (['legacy' => $legacy, 'spec' => Dom\XMLDocument::createFromString($xml)] as $label => $doc) {
echo $label, PHP_EOL;
$map = $doc->documentElement->attributes;
foreach (['defaulted', 'real'] as $name) {
var_dump($map->getNamedItem($name)?->nodeValue);
var_dump(isset($map[$name]));
var_dump($map[$name]?->nodeValue);
}
}
?>
--EXPECT--
legacy
NULL
bool(false)
NULL
string(7) "present"
bool(true)
string(7) "present"
spec
NULL
bool(false)
NULL
string(7) "present"
bool(true)
string(7) "present"
Loading