Commit 7b1f5637b6f for php.net
commit 7b1f5637b6f4024ab081b1eb97681102b3eeae70
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Tue Aug 4 22:01:44 2026 -0400
Fix segfault comparing uninitialized SimpleXMLElement instances
sxe_objects_compare dereferenced document->ptr when both nodes were
NULL without checking document. A subclass that skips parent
__construct leaves document NULL, so $a == $b segfaulted. Compare the
documents only when both are set; anything else is uncomparable.
Closes GH-23067
diff --git a/NEWS b/NEWS
index e3995c5664b..d19e6b8ae2a 100644
--- a/NEWS
+++ b/NEWS
@@ -62,6 +62,8 @@ PHP NEWS
- SimpleXML:
. Fixed integer element offsets that cannot resolve aliasing an existing
element. (iliaal)
+ . Fixed segfault when comparing uninitialized SimpleXMLElement
+ instances. (iliaal)
- Sockets:
. Fixed various memory related issues in ext/sockets. (David Carlier)
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index f3c1a073fca..1a346200199 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -1237,7 +1237,7 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */
if (sxe1->node == NULL && sxe2->node == NULL) {
/* Both nodes not set: Only support equality comparison between documents. */
- if (sxe1->document->ptr == sxe2->document->ptr) {
+ if (sxe1->document != NULL && sxe2->document != NULL && sxe1->document->ptr == sxe2->document->ptr) {
return 0;
}
return ZEND_UNCOMPARABLE;
diff --git a/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt
new file mode 100644
index 00000000000..4d915b66c3a
--- /dev/null
+++ b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Comparing uninitialized SimpleXMLElement instances must not segfault
+--EXTENSIONS--
+simplexml
+--FILE--
+<?php
+class MySXE extends SimpleXMLElement {
+ public function __construct() {}
+}
+$a = new MySXE;
+$b = new MySXE;
+echo "self: ";
+var_dump($a == $a);
+echo "equal: ";
+var_dump($a == $b);
+echo "identical: ";
+var_dump($a === $b);
+$c = simplexml_load_string('<r/>');
+echo "uninit vs init: ";
+var_dump($a == $c);
+echo "done\n";
+?>
+--EXPECT--
+self: bool(true)
+equal: bool(false)
+identical: bool(false)
+uninit vs init: bool(false)
+done