Don't use the obj_map cache for attributes (#18895)

This commit is contained in:
Niels Dossche 2025-06-22 12:31:06 +02:00 committed by GitHub
parent 479e9be45d
commit 9b6df109c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 16 deletions

View file

@ -196,19 +196,25 @@ static void dom_map_cache_obj(dom_nnodemap_object *map, xmlNodePtr itemnode, zen
map->cached_obj = cached_obj; map->cached_obj = cached_obj;
} }
static xmlNodePtr dom_map_get_attr_start(xmlNodePtr node) static void dom_map_get_attributes_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
{ {
ZEND_ASSERT(node->type == XML_ELEMENT_NODE); xmlNodePtr nodep = dom_object_get_node(map->baseobj);
return (xmlNodePtr) node->properties; xmlNodePtr itemnode = NULL;
if (nodep && index >= 0) {
ZEND_ASSERT(nodep->type == XML_ELEMENT_NODE);
itemnode = (xmlNodePtr) nodep->properties;
for (; index > 0 && itemnode; itemnode = itemnode->next, index--);
}
dom_ret_node_to_zobj(map, itemnode, return_value);
} }
static void dom_map_get_chain_item(dom_nnodemap_object *map, zend_long index, zval *return_value, xmlNodePtr (*get_start)(xmlNodePtr)) static void dom_map_get_nodes_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
{ {
xmlNodePtr nodep = dom_object_get_node(map->baseobj); xmlNodePtr nodep = dom_object_get_node(map->baseobj);
xmlNodePtr itemnode = NULL; xmlNodePtr itemnode = NULL;
if (nodep && index >= 0) { if (nodep && index >= 0) {
dom_node_idx_pair start_point = dom_obj_map_get_start_point(map, nodep, index); dom_node_idx_pair start_point = dom_obj_map_get_start_point(map, nodep, index);
itemnode = start_point.node ? start_point.node : get_start(nodep); itemnode = start_point.node ? start_point.node : dom_nodelist_iter_start_first_child(nodep);
for (; start_point.index > 0 && itemnode; itemnode = itemnode->next, start_point.index--); for (; start_point.index > 0 && itemnode; itemnode = itemnode->next, start_point.index--);
} }
dom_ret_node_to_zobj(map, itemnode, return_value); dom_ret_node_to_zobj(map, itemnode, return_value);
@ -217,16 +223,6 @@ static void dom_map_get_chain_item(dom_nnodemap_object *map, zend_long index, zv
} }
} }
static void dom_map_get_attributes_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
{
dom_map_get_chain_item(map, index, return_value, dom_map_get_attr_start);
}
static void dom_map_get_nodes_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
{
dom_map_get_chain_item(map, index, return_value, dom_nodelist_iter_start_first_child);
}
static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value) static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
{ {
xmlNodePtr nodep = dom_object_get_node(map->baseobj); xmlNodePtr nodep = dom_object_get_node(map->baseobj);
@ -411,7 +407,7 @@ const php_dom_obj_map_handler php_dom_obj_map_attributes = {
.get_item = dom_map_get_attributes_item, .get_item = dom_map_get_attributes_item,
.get_named_item = dom_map_get_named_item_prop, .get_named_item = dom_map_get_named_item_prop,
.has_named_item = dom_map_has_named_item_prop, .has_named_item = dom_map_has_named_item_prop,
.use_cache = true, .use_cache = false,
.nameless = false, .nameless = false,
}; };

View file

@ -0,0 +1,17 @@
--TEST--
Attribute named node map cache
--EXTENSIONS--
dom
--FILE--
<?php
$dom = Dom\XMLDocument::createFromString('<root a="1" b="2" c="3"/>');
$attrs = $dom->documentElement->attributes;
var_dump($attrs[1]->nodeName);
$dom->documentElement->removeAttribute('b');
var_dump($attrs[1]->nodeName);
?>
--EXPECT--
string(1) "b"
string(1) "c"