From 0094ebf7778eb52fd95aac68f34d360bdcad01e9 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 5 Aug 2026 09:16:11 -0400 Subject: [PATCH] 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. Treat two NULL documents as equal and mixed NULL/non-NULL as uncomparable. Closes GH-23067 --- NEWS | 4 +++ ext/simplexml/simplexml.c | 6 +++++ .../tests/bug_sxe_compare_uninitialized.phpt | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt diff --git a/NEWS b/NEWS index 474db936ef15..a9ca3fea246c 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,10 @@ PHP NEWS . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap corrupted). (ndossche) +- SimpleXML: + . 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 8cf8e657e58f..b3266f813975 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1229,6 +1229,12 @@ 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 == NULL || sxe2->document == NULL) { + if (sxe1->document == sxe2->document) { + return 0; + } + return ZEND_UNCOMPARABLE; + } if (sxe1->document->ptr == sxe2->document->ptr) { return 0; } 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 000000000000..742761eed6c0 --- /dev/null +++ b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt @@ -0,0 +1,25 @@ +--TEST-- +Comparing uninitialized SimpleXMLElement instances must not segfault +--EXTENSIONS-- +simplexml +--FILE-- +'); +echo "uninit vs init: "; +var_dump($a == $c); +echo "done\n"; +?> +--EXPECT-- +equal: bool(true) +identical: bool(false) +uninit vs init: bool(false) +done