Skip to content

Commit 6aa33f2

Browse files
committed
Fix phpGH-10234: Setting DOMAttr::textContent results in an empty attribute value.
We can't directly call xmlNodeSetContent, because it might encode the string through xmlStringLenGetNodeList for types XML_DOCUMENT_FRAG_NODE, XML_ELEMENT_NODE, XML_ATTRIBUTE_NODE. In these cases we need to use a text node to avoid the encoding. For the other cases, we *can* rely on xmlNodeSetContent because it is either a no-op, or handles the content without encoding and clears the properties field if needed.
1 parent 4c9375e commit 6aa33f2

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

ext/dom/node.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,17 +769,29 @@ int dom_node_text_content_write(dom_object *obj, zval *newval)
769769
return FAILURE;
770770
}
771771

772-
if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE) {
772+
const xmlChar *xmlChars = (const xmlChar *) ZSTR_VAL(str);
773+
int type = nodep->type;
774+
775+
/**
776+
* We can't directly call xmlNodeSetContent, because it might encode the string through
777+
* xmlStringLenGetNodeList for types XML_DOCUMENT_FRAG_NODE, XML_ELEMENT_NODE, XML_ATTRIBUTE_NODE.
778+
* In these cases we need to use a text node to avoid the encoding.
779+
* For the other cases, we *can* rely on xmlNodeSetContent because it is either a no-op, or handles
780+
* the content without encoding and clears the properties field if needed.
781+
*/
782+
if (type == XML_DOCUMENT_FRAG_NODE || type == XML_ELEMENT_NODE || type == XML_ATTRIBUTE_NODE) {
773783
if (nodep->children) {
774784
node_list_unlink(nodep->children);
775785
php_libxml_node_free_list((xmlNodePtr) nodep->children);
776786
nodep->children = NULL;
777787
}
788+
789+
xmlNode *textNode = xmlNewText(xmlChars);
790+
xmlAddChild(nodep, textNode);
791+
} else {
792+
xmlNodeSetContent(nodep, xmlChars);
778793
}
779794

780-
/* we have to use xmlNodeAddContent() to get the same behavior as with xmlNewText() */
781-
xmlNodeSetContent(nodep, (xmlChar *) "");
782-
xmlNodeAddContent(nodep, (xmlChar *) ZSTR_VAL(str));
783795
zend_string_release_ex(str, 0);
784796

785797
return SUCCESS;

0 commit comments

Comments
 (0)