Skip to content

Commit 10af2d1

Browse files
committed
simplexml: filter addChild() result by the created element's namespace
addChild() built the returned SimpleXMLElement with the prefix the caller passed in, not the one the new node ended up in, so a child added through that object was filtered against the wrong namespace and was invisible by property name. Take the prefix from newnode->ns instead. The filter keys on the prefix rather than the href because node_as_zval() installs no filter at all for a prefixless namespace, and switching to href would start filtering the default-namespace case that today has none. Closes GH-23599
1 parent 979c827 commit 10af2d1

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ PHP NEWS
114114
- SimpleXML:
115115
. Fixed writing to a dimension of the object returned by attributes() not
116116
creating the attribute. (Ilia Alshanetsky)
117+
. Fixed child elements of the element returned by
118+
SimpleXMLElement::addChild() not being accessible by property name when
119+
namespaces are involved. (Ilia Alshanetsky)
117120

118121
- Zip:
119122
. Fixed bug GH-23276 (ZipArchive subclass storing its own stream cannot be

ext/simplexml/simplexml.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1727,7 +1727,8 @@ PHP_METHOD(SimpleXMLElement, addChild)
17271727
}
17281728
}
17291729

1730-
node_as_zval_str(sxe, newnode, return_value, SXE_ITER_NONE, localname, prefix, 0);
1730+
node_as_zval_str(sxe, newnode, return_value, SXE_ITER_NONE, localname,
1731+
newnode->ns ? newnode->ns->prefix : NULL, 1);
17311732

17321733
xmlFree(localname);
17331734
if (prefix != NULL) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
SimpleXMLElement::addChild() wrong namespace filter on returned element
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
$x = new SimpleXMLElement('<r xmlns:a="http://example.com"/>');
8+
$c = $x->addChild('a:kid', null, 'http://example.com');
9+
$c->addChild('inner', 'v');
10+
echo trim($x->asXML()), "\n";
11+
echo (string) $c->inner, "\n";
12+
var_dump(isset($c->inner));
13+
14+
$y = new SimpleXMLElement('<r xmlns:a="http://example.com"/>');
15+
$d = $y->addChild('kid', null, 'http://example.com');
16+
$d->addChild('inner', 'w');
17+
echo trim($y->asXML()), "\n";
18+
echo (string) $d->inner, "\n";
19+
20+
$z = new SimpleXMLElement('<p:r xmlns:p="http://example.com/p"/>');
21+
$e = $z->addChild('kid');
22+
$e->addChild('inner', 'z');
23+
echo trim($z->asXML()), "\n";
24+
echo (string) $e->inner, "\n";
25+
var_dump(isset($e->inner));
26+
?>
27+
--EXPECT--
28+
<?xml version="1.0"?>
29+
<r xmlns:a="http://example.com"><a:kid><a:inner>v</a:inner></a:kid></r>
30+
v
31+
bool(true)
32+
<?xml version="1.0"?>
33+
<r xmlns:a="http://example.com"><a:kid><a:inner>w</a:inner></a:kid></r>
34+
w
35+
<?xml version="1.0"?>
36+
<p:r xmlns:p="http://example.com/p"><p:kid><p:inner>z</p:inner></p:kid></p:r>
37+
z
38+
bool(true)

0 commit comments

Comments
 (0)