Skip to content

Commit 737f8be

Browse files
committed
Fix SimpleXML invalidations
Test was Co-authored-by: tstarling
1 parent dccd29c commit 737f8be

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
DOMDocument::getElementsByTagName() liveness with simplexml_import_dom
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$doc = new DOMDocument;
9+
$doc->loadXML( '<root><e i="1"/><e i="2"/><e i="3"/><e i="4"/><e i="5"/><e i="6"/><e i="7"/><e i="8"/><e i="9"/><e i="10"/></root>' );
10+
$list = $doc->getElementsByTagName('e');
11+
print $list->item(5)->getAttribute('i')."\n";
12+
echo "before import\n";
13+
$s = simplexml_import_dom($doc->documentElement);
14+
echo "after import\n";
15+
16+
unset($s->e[5]);
17+
print $list->item(5)->getAttribute('i')."\n";
18+
19+
unset($s->e[5]);
20+
print $list->item(5)->getAttribute('i')."\n";
21+
22+
?>
23+
--EXPECT--
24+
6
25+
before import
26+
after import
27+
7
28+
8

ext/simplexml/simplexml.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ PHP_SXE_API zend_class_entry *sxe_get_element_class_entry(void) /* {{{ */
4343
}
4444
/* }}} */
4545

46+
/* Similar to php_dom_invalidate_node_list_cache(), but SimpleXML shouldn't depend on ext/dom. */
47+
static zend_always_inline void php_sxe_invalidate_node_list_cache(xmlNodePtr node)
48+
{
49+
ZEND_ASSERT(node != NULL);
50+
xmlDocPtr docp = node->doc;
51+
if (docp && docp->_private) {
52+
php_libxml_invalidate_node_list_cache(docp->_private);
53+
}
54+
}
55+
4656
static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count);
4757
static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data);
4858
static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data);
@@ -442,6 +452,8 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value,
442452

443453
GET_NODE(sxe, node);
444454

455+
php_sxe_invalidate_node_list_cache(node);
456+
445457
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
446458
attribs = 1;
447459
elements = 0;
@@ -813,6 +825,8 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
813825

814826
GET_NODE(sxe, node);
815827

828+
php_sxe_invalidate_node_list_cache(node);
829+
816830
if (Z_TYPE_P(member) == IS_LONG) {
817831
if (sxe->iter.type != SXE_ITER_ATTRLIST) {
818832
attribs = 0;
@@ -1686,6 +1700,8 @@ PHP_METHOD(SimpleXMLElement, addChild)
16861700
sxe = Z_SXEOBJ_P(ZEND_THIS);
16871701
GET_NODE(sxe, node);
16881702

1703+
php_sxe_invalidate_node_list_cache(node);
1704+
16891705
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
16901706
php_error_docref(NULL, E_WARNING, "Cannot add element to attributes");
16911707
return;

0 commit comments

Comments
 (0)