diff --git a/NEWS b/NEWS index 7dd1aea4b881..26610ce9254f 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,9 @@ PHP NEWS - DOM: . Fix GH-22219 (Dom\XMLDocument::schemaValidate fails to resolve xs:QName with prefix from imported schema). (David Carlier) + . Fixed bug GH-22447 (UAF at dom_objects_free_storage when setting an + attribute node that collides by local name with a namespaced + attribute). (David Carlier) - Exif: . Read correct value for single and double tags. (ndossche) diff --git a/ext/dom/element.c b/ext/dom/element.c index e25805df53eb..f288ad76886b 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -722,6 +722,8 @@ static void dom_element_set_attribute_node_common(INTERNAL_FUNCTION_PARAMETERS, nsp = attrp->ns; if (use_ns && nsp != NULL) { existattrp = xmlHasNsProp(nodep, attrp->name, nsp->href); + } else if (nsp == NULL) { + existattrp = xmlHasNsProp(nodep, attrp->name, NULL); } else { existattrp = xmlHasProp(nodep, attrp->name); } diff --git a/ext/dom/node.c b/ext/dom/node.c index df806bddfae7..81c80cb0c8ac 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -965,7 +965,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj xmlAttrPtr lastattr; if (child->ns == NULL) - lastattr = xmlHasProp(refp->parent, child->name); + lastattr = xmlHasNsProp(refp->parent, child->name, NULL); else lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href); if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { @@ -1012,7 +1012,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj xmlAttrPtr lastattr; if (child->ns == NULL) - lastattr = xmlHasProp(parentp, child->name); + lastattr = xmlHasNsProp(parentp, child->name, NULL); else lastattr = xmlHasNsProp(parentp, child->name, child->ns->href); if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { @@ -1374,7 +1374,7 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern, xmlAttrPtr lastattr; if (child->ns == NULL) - lastattr = xmlHasProp(nodep, child->name); + lastattr = xmlHasNsProp(nodep, child->name, NULL); else lastattr = xmlHasNsProp(nodep, child->name, child->ns->href); if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { diff --git a/ext/dom/tests/gh22447.phpt b/ext/dom/tests/gh22447.phpt new file mode 100644 index 000000000000..396a0ff1ee1c --- /dev/null +++ b/ext/dom/tests/gh22447.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-22447 (UAF at dom_objects_free_storage when setAttributeNode collides with a namespaced attribute of the same local name) +--EXTENSIONS-- +dom +--FILE-- +createAttribute("my-attribute"); +$container = $dom->appendChild($dom->createElement("container")); +$attribute2 = $dom->createAttribute("my-attribute"); +$attribute4 = $dom->createAttributeNS("urn:a", "my-attribute"); + +$container->setAttributeNode($attribute1); +$container->setAttributeNode($attribute4); + +var_dump($container->setAttributeNode($attribute2) === $attribute1); +var_dump($container->setAttributeNode($attribute1) === $attribute2); + +echo $dom->saveXml($container), PHP_EOL; +?> +--EXPECT-- +bool(true) +bool(true) +