Commit 570eedee14 for wordpress.org

commit 570eedee14daf9e040827c5f650586dffb7931ca
Author: jonsurrell <jonsurrell@git.wordpress.org>
Date:   Mon Sep 7 08:46:52 2026 +0000

    HTML API: Allow raw text which cannot close its own element.

    Developed in: https://github.com/WordPress/wordpress-develop/pull/12914

    Props khokansardar, jonsurrell, shailu25.
    Fixes #65824.

    Built from https://develop.svn.wordpress.org/trunk@63513


    git-svn-id: http://core.svn.wordpress.org/trunk@62689 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-includes/html-api/class-wp-html-tag-processor.php b/wp-includes/html-api/class-wp-html-tag-processor.php
index bbfbbea59b..4e3063f5bd 100644
--- a/wp-includes/html-api/class-wp-html-tag-processor.php
+++ b/wp-includes/html-api/class-wp-html-tag-processor.php
@@ -4092,11 +4092,20 @@ class WP_HTML_Tag_Processor {
 				 * Because of this, content which could potentially modify the SCRIPT tag’s
 				 * HTML structure is rejected here. It’s the responsibility of calling code to
 				 * perform whatever semantic escaping is necessary to avoid problematic strings.
+				 *
+				 * Both the start tag `<script` and the end tag `</script` are rejected. It’s
+				 * easy to assume that only an end tag can alter the HTML structure, but a
+				 * start tag which follows `<!--` moves the tokenizer into the double-escaped
+				 * states, where a later `</script>` no longer closes the element.
+				 *
+				 * In both cases the tag name ends only at one of the characters matched
+				 * below, so text such as `</scriptx>` cannot change that structure and is
+				 * safe to set.
+				 *
+				 * @link https://html.spec.whatwg.org/#script-data-end-tag-name-state
+				 * @link https://html.spec.whatwg.org/#script-data-double-escape-start-state
 				 */
-				if (
-					false !== stripos( $plaintext_content, '<script' ) ||
-					false !== stripos( $plaintext_content, '</script' )
-				) {
+				if ( 1 === preg_match( '~</?script[ \t\f\r\n/>]~i', $plaintext_content ) ) {
 					_doing_it_wrong(
 						__METHOD__,
 						__( 'SCRIPT text with an unrecognized content type cannot contain a SCRIPT tag. Apply the escaping appropriate for the content type.' ),
@@ -4116,7 +4125,14 @@ class WP_HTML_Tag_Processor {
 			case 'NOFRAMES':
 			case 'XMP':
 				$tag_name = $this->get_tag();
-				if ( false !== stripos( $plaintext_content, "</{$tag_name}" ) ) {
+
+				/*
+				 * A tag name ends only at one of the characters matched below, so text
+				 * such as `</xmp-tag>` cannot close the element and is safe to set.
+				 *
+				 * @link https://html.spec.whatwg.org/#rawtext-end-tag-name-state
+				 */
+				if ( 1 === preg_match( '~</' . preg_quote( $tag_name, '~' ) . '[ \t\f\r\n/>]~i', $plaintext_content ) ) {
 					_doing_it_wrong(
 						__METHOD__,
 						sprintf(
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 8c94678239..920fde9cc6 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-alpha-63512';
+$wp_version = '7.2-alpha-63513';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.