From cbbe4942e788ac3f3c74f966c1ff436dc06a38e2 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 24 Aug 2026 11:14:11 -0400 Subject: [PATCH] [SimpleXML] Fix creating new attributes via attributes() dimension write sxe_prop_dim_write() overwrote the element node with the first attribute node when resolving an SXE_ITER_ATTRLIST iterator, so xmlNewProp() targeted a non-element node and was skipped entirely when no attribute existed yet. Keep the element node in place and resolve only the attribute list start, so $x->attributes()["new"] = "v" creates the attribute like the symmetric $x["new"] path; property writes on the attributes() object share the fixed path while read/exists/unset handlers are unaffected by this defect. --- NEWS | 2 ++ ext/simplexml/simplexml.c | 3 +- .../tests/attributes_dimension_write.phpt | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 ext/simplexml/tests/attributes_dimension_write.phpt diff --git a/NEWS b/NEWS index a2c65685b4ce..c156668f14cf 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,8 @@ PHP NEWS corrupted). (ndossche) - SimpleXML: + . Fixed writing to a dimension of the object returned by attributes() not + creating the attribute. (iliaal) . Fixed integer element offsets that cannot resolve aliasing an existing element. (iliaal) . Fixed segfault when comparing uninitialized SimpleXMLElement diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 1a346200199b..44fdef5e12d7 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -443,8 +443,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; elements = 0; - node = php_sxe_get_first_node_non_destructive(sxe, node); - attr = (xmlAttrPtr)node; + attr = (xmlAttrPtr)php_sxe_get_first_node_non_destructive(sxe, node); test = sxe->iter.name != NULL; } else if (sxe->iter.type != SXE_ITER_CHILD) { mynode = node; diff --git a/ext/simplexml/tests/attributes_dimension_write.phpt b/ext/simplexml/tests/attributes_dimension_write.phpt new file mode 100644 index 000000000000..8721dc7dc7c2 --- /dev/null +++ b/ext/simplexml/tests/attributes_dimension_write.phpt @@ -0,0 +1,30 @@ +--TEST-- +Creating new attributes via dimension and property writes on attributes() +--FILE-- +'); +$x->attributes()['new'] = 'v'; +echo $x->asXML(); + +$a = simplexml_load_string(''); +$a->attributes()['created'] = 'yes'; +echo $a->asXML(); + +$b = simplexml_load_string(''); +$attrs = $b->attributes(); +$attrs->other = 2; +echo $b->asXML(); + +$c = simplexml_load_string(''); +$c->attributes()['a'] = '2'; +echo $c->asXML(); +?> +--EXPECT-- + + + + + + + +