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);