Skip to content

Commit 89b3eda

Browse files
committed
Only include non-element children alongside a matching element
Keep the property table of children() consistent with sxe_prop_is_empty(): an element whose only children are PIs or comments (or with no child in the requested namespace) is still empty, so (bool) and (array) agree.
1 parent 1428f37 commit 89b3eda

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎ext/simplexml/simplexml.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,8 +1109,9 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */
11091109
GET_NODE(sxe, node);
11101110
if (sxe->iter.type == SXE_ITER_CHILD) {
11111111
/* Start at the first child rather than at the first element child, so that
1112-
* non-element nodes (e.g. PIs, comments) before it are not skipped. */
1113-
node = node ? node->children : NULL;
1112+
* non-element nodes (e.g. PIs, comments) before it are not skipped. Like
1113+
* sxe_prop_is_empty(), only do so if there is a matching element child. */
1114+
node = php_sxe_get_first_node_non_destructive(sxe, node) ? node->children : NULL;
11141115
} else {
11151116
node = php_sxe_get_first_node_non_destructive(sxe, node);
11161117
}

‎ext/simplexml/tests/gh12168.phpt‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ foreach ([
2121
echo $xml, ': ', json_encode(array_keys((array) $sxe->children())), "\n";
2222
}
2323

24+
/* Non-element nodes only show up alongside a matching element, consistent with (bool) */
25+
foreach ([
26+
'<c><?pi a?></c>',
27+
'<c><!-- c --></c>',
28+
'<c>t<?pi a?></c>',
29+
'<!DOCTYPE c [<!ENTITY e "v">]><c>&e;<x/></c>',
30+
] as $xml) {
31+
$sxe = simplexml_load_string($xml);
32+
echo $xml, ': ', json_encode(array_keys((array) $sxe->children())), ' ', var_export((bool) $sxe->children(), true), "\n";
33+
}
34+
35+
$sxe = simplexml_load_string('<c xmlns:a="urn:a"><?pi a?><y/><a:x/></c>');
36+
var_dump(array_keys((array) $sxe->children('urn:a')));
37+
$sxe = simplexml_load_string('<c xmlns:a="urn:a"><?pi a?><y/></c>');
38+
var_dump(array_keys((array) $sxe->children('urn:a')), (bool) $sxe->children('urn:a'));
39+
2440
?>
2541
--EXPECTF--
2642
object(SimpleXMLElement)#%d (2) {
@@ -43,3 +59,16 @@ object(SimpleXMLElement)#%d (2) {
4359
<c><x/><!-- c --></c>: ["x","comment"]
4460
<c><?pi a?><x/><?pi b?><y/></c>: ["pi","x","y"]
4561
<c>text</c>: []
62+
<c><?pi a?></c>: [] false
63+
<c><!-- c --></c>: [] false
64+
<c>t<?pi a?></c>: [] false
65+
<!DOCTYPE c [<!ENTITY e "v">]><c>&e;<x/></c>: ["e","x"] true
66+
array(2) {
67+
[0]=>
68+
string(2) "pi"
69+
[1]=>
70+
string(1) "x"
71+
}
72+
array(0) {
73+
}
74+
bool(false)

0 commit comments

Comments
 (0)