Skip to content

Commit 7b1f563

Browse files
committed
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
1 parent 71a1244 commit 7b1f563

3 files changed

Lines changed: 31 additions & 1 deletion

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ PHP NEWS
6262
- SimpleXML:
6363
. Fixed integer element offsets that cannot resolve aliasing an existing
6464
element. (iliaal)
65+
. Fixed segfault when comparing uninitialized SimpleXMLElement
66+
instances. (iliaal)
6567

6668
- Sockets:
6769
. Fixed various memory related issues in ext/sockets. (David Carlier)

ext/simplexml/simplexml.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,7 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */
12371237

12381238
if (sxe1->node == NULL && sxe2->node == NULL) {
12391239
/* Both nodes not set: Only support equality comparison between documents. */
1240-
if (sxe1->document->ptr == sxe2->document->ptr) {
1240+
if (sxe1->document != NULL && sxe2->document != NULL && sxe1->document->ptr == sxe2->document->ptr) {
12411241
return 0;
12421242
}
12431243
return ZEND_UNCOMPARABLE;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Comparing uninitialized SimpleXMLElement instances must not segfault
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
class MySXE extends SimpleXMLElement {
8+
public function __construct() {}
9+
}
10+
$a = new MySXE;
11+
$b = new MySXE;
12+
echo "self: ";
13+
var_dump($a == $a);
14+
echo "equal: ";
15+
var_dump($a == $b);
16+
echo "identical: ";
17+
var_dump($a === $b);
18+
$c = simplexml_load_string('<r/>');
19+
echo "uninit vs init: ";
20+
var_dump($a == $c);
21+
echo "done\n";
22+
?>
23+
--EXPECT--
24+
self: bool(true)
25+
equal: bool(false)
26+
identical: bool(false)
27+
uninit vs init: bool(false)
28+
done

0 commit comments

Comments
 (0)