diff --git a/ext/dom/attr.c b/ext/dom/attr.c
index a262aea821395..8d9d5b57f9973 100644
--- a/ext/dom/attr.c
+++ b/ext/dom/attr.c
@@ -136,6 +136,7 @@ int dom_attr_value_write(dom_object *obj, zval *newval)
{
zend_string *str;
xmlAttrPtr attrp = (xmlAttrPtr) dom_object_get_node(obj);
+ xmlNodePtr node, next;
if (attrp == NULL) {
php_dom_throw_error(INVALID_STATE_ERR, 1);
@@ -149,9 +150,17 @@ int dom_attr_value_write(dom_object *obj, zval *newval)
if (attrp->children) {
node_list_unlink(attrp->children);
+ node = attrp->children;
+ while (node) {
+ next = node->next;
+ xmlUnlinkNode(node);
+ xmlFreeNode(node);
+ node = next;
+ }
}
- xmlNodeSetContentLen((xmlNodePtr) attrp, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str) + 1);
+ node = xmlNewTextLen((xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str));
+ xmlAddChild((xmlNodePtr) attrp, node);
zend_string_release_ex(str, 0);
return SUCCESS;
diff --git a/ext/dom/tests/DOMAttr_entity_expansion.phpt b/ext/dom/tests/DOMAttr_entity_expansion.phpt
new file mode 100644
index 0000000000000..d8745cb9f460f
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_entity_expansion.phpt
@@ -0,0 +1,30 @@
+--TEST--
+DOMAttr entity expansion
+--FILE--
+createElement('elt');
+$doc->appendChild($elt);
+$elt->setAttribute('a','&');
+print $doc->saveXML($elt) . "\n";
+
+$attr = $elt->getAttributeNode('a');
+$attr->value = '&';
+print $doc->saveXML($elt) . "\n";
+
+$attr->removeChild($attr->firstChild);
+print $doc->saveXML($elt) . "\n";
+
+$elt->setAttributeNS('http://www.w3.org/2000/svg', 'svg:id','&');
+print $doc->saveXML($elt) . "\n";
+
+$attr = $elt->getAttributeNodeNS('http://www.w3.org/2000/svg', 'id');
+$attr->value = '<&';
+print $doc->saveXML($elt) . "\n";
+
+--EXPECT--
+
+
+
+
+