[php-src] master: Fix GH-12171: resolve SimpleXML nodes before equality compare (#23187)

From: Date: Tue, 06 Oct 2026 00:01:59 +0000
Subject: [php-src] master: Fix GH-12171: resolve SimpleXML nodes before equality compare (#23187)
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-141984@lists.php.net to get a copy of this message
Author: Ilia Alshanetsky (iliaal) Committer: GitHub (web-flow) Pusher: iliaal Date: 2026-10-05T20:01:55-04:00 Commit: https://github.com/php/php-src/commit/75204bee6f40da6392d4961c0ae5d5adc4502e3a Raw diff: https://github.com/php/php-src/commit/75204bee6f40da6392d4961c0ae5d5adc4502e3a.diff Fix GH-12171: resolve SimpleXML nodes before equality compare (#23187) Property proxies like $xml->first store the parent node plus an element iterator name. sxe_objects_compare compared the parent wrappers, so sibling proxies always compared equal. Resolve each side through php_sxe_get_first_node_non_destructive before comparing. When both sides resolve to no node, keep comparing the parent wrappers, so two empty results from the same parent still compare equal. Fixes GH-12171 Closes GH-23187 Changed paths: A ext/simplexml/tests/gh12171.phpt M NEWS M ext/simplexml/simplexml.c Diff: diff --git a/NEWS b/NEWS index 44acf0104b54..8d0f7c815b6e 100644 --- a/NEWS +++ b/NEWS @@ -71,6 +71,10 @@ PHP NEWS . Fixed exceptions from user-defined create_sid() handlers being replaced by return-value validation errors. (Ilia Alshanetsky) +- SimpleXML: + . Fixed bug GH-12171 (SimpleXML property-proxy equality ignores element + names). (Ilia Alshanetsky) + - SOAP: . Fixed the SOAP client accepting a response body shorter than its Content-Length and reusing the connection. (Ilia Alshanetsky) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 75d859eea4ac..d4e8ea649d16 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1202,8 +1202,11 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */ sxe2 = Z_SXEOBJ_P(object2); if (sxe1->node != NULL && sxe2->node != NULL) { + xmlNodePtr node1 = php_sxe_get_first_node_non_destructive(sxe1, sxe1->node->node); + xmlNodePtr node2 = php_sxe_get_first_node_non_destructive(sxe2, sxe2->node->node); + /* Both nodes set: Only support equality comparison between nodes. */ - if (sxe1->node == sxe2->node) { + if (node1 == node2 && (node1 != NULL || sxe1->node == sxe2->node)) { return 0; } return ZEND_UNCOMPARABLE; diff --git a/ext/simplexml/tests/gh12171.phpt b/ext/simplexml/tests/gh12171.phpt new file mode 100644 index 000000000000..e6b3e75b99f4 --- /dev/null +++ b/ext/simplexml/tests/gh12171.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-12171 (SimpleXML property-proxy equality must resolve iterator nodes) +--EXTENSIONS-- +simplexml +--FILE-- +<?php +$xml = simplexml_load_string('<root><first/><second/><third/></root>'); +echo "first==second: "; +var_dump($xml->first == $xml->second); +echo "first==first: "; +var_dump($xml->first == $xml->first); +echo "first==root: "; +var_dump($xml->first == $xml); +$a = $xml->first; +$b = $xml->first; +echo "proxies equal: "; +var_dump($a == $b); + +$x = simplexml_load_string('<root><empty/></root>'); +echo "missing==missing: "; +var_dump($x->missing == $x->missing); +echo "children==children: "; +var_dump($x->empty->children() == $x->empty->children()); +echo "missing==empty->missing: "; +var_dump($x->missing == $x->empty->missing); +echo "missing==empty: "; +var_dump($x->missing == $x->empty); +?> +--EXPECT-- +first==second: bool(false) +first==first: bool(true) +first==root: bool(false) +proxies equal: bool(true) +missing==missing: bool(true) +children==children: bool(true) +missing==empty->missing: bool(false) +missing==empty: bool(false)

« previous php.cvs (#141984) next »