Commit 6044aee8611 for php
commit 6044aee861125f09f95e4007235bf13bf5f55e5d
Merge: 8450def0d07 5587c3265c4
Author: David Carlier <devnexen@gmail.com>
Date: Sun Oct 18 10:37:31 2026 +0100
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
Fix GH-23334: ext/dom: php_dom_free_templated_content() use-after-free
diff --cc ext/dom/inner_outer_html_mixin.c
index 2e080859d69,ef7f3051dc4..76c11b2a71d
--- a/ext/dom/inner_outer_html_mixin.c
+++ b/ext/dom/inner_outer_html_mixin.c
@@@ -343,32 -336,25 +343,39 @@@ static xmlNodePtr dom_xml_fragment_pars
return NULL;
}
-/* https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin
- * and https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm */
+/* https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm */
- xmlNodePtr dom_parse_fragment(dom_object *obj, xmlNodePtr context_node, const zend_string *input)
++static xmlNodePtr dom_parse_fragment_ex(dom_object *obj, xmlNodePtr context_node, const zend_string *input, bool is_template)
+{
+ if (context_node->doc->type == XML_DOCUMENT_NODE) {
+ return dom_xml_fragment_parsing_algorithm(obj, context_node, input);
+ } else {
- return dom_html_fragment_parsing_algorithm(obj, context_node, input, obj->document->quirks_mode);
++ return dom_html_fragment_parsing_algorithm(obj, context_node, input, obj->document->quirks_mode, is_template);
+ }
+}
+
++xmlNodePtr dom_parse_fragment(dom_object *obj, xmlNodePtr context_node, const zend_string *input)
++{
++ return dom_parse_fragment_ex(obj, context_node, input, false);
++}
++
+/* https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin */
zend_result dom_element_inner_html_write(dom_object *obj, zval *newval)
{
+ /* 1. We don't do injection sinks, skip. */
+
+ /* 2. Let context be this. */
DOM_PROP_NODE(xmlNodePtr, context_node, obj);
+ bool is_template = php_dom_ns_is_fast(context_node, php_dom_ns_is_html_magic_token) && xmlStrEqual(context_node->name, BAD_CAST "template");
- xmlNodePtr fragment;
- if (context_node->doc->type == XML_DOCUMENT_NODE) {
- fragment = dom_xml_fragment_parsing_algorithm(obj, context_node, Z_STR_P(newval));
- } else {
- fragment = dom_html_fragment_parsing_algorithm(obj, context_node, Z_STR_P(newval), obj->document->quirks_mode, is_template);
- }
+
+ /* 3. Let fragment be the result of invoking the fragment parsing algorithm steps with context and compliantString. */
- xmlNodePtr fragment = dom_parse_fragment(obj, context_node, Z_STR_P(newval));
++ xmlNodePtr fragment = dom_parse_fragment_ex(obj, context_node, Z_STR_P(newval), is_template);
if (fragment == NULL) {
return FAILURE;
}
+ /* 4. If context is a template element, then set context to the template element's template contents (a DocumentFragment). */
- if (php_dom_ns_is_fast(context_node, php_dom_ns_is_html_magic_token) && xmlStrEqual(context_node->name, BAD_CAST "template")) {
+ if (is_template) {
context_node = php_dom_ensure_templated_content(php_dom_get_private_data(obj), context_node);
if (context_node == NULL) {
xmlFreeNode(fragment);