Commit fe6a992df0 for wordpress.org

commit fe6a992df032de6aed941c14e2754f17053824ae
Author: jonsurrell <jonsurrell@git.wordpress.org>
Date:   Tue Dec 30 13:03:34 2025 +0000

    Use the HTML API to generate style tags.

    The HTML API escapes `<style>` tag contents to ensure the correct HTML structure. Common HTML escaping is unsuitable for `<style>` tags because they contain "raw text." The additional safety allows other restrictions, such as rejecting content with `<>`, to be relaxed or removed because the resulting tag will be well-formed.

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

    Props jonsurrell, westonruter, dmsnell, ramonopoly, soyebsalar01, drw158, sabernhardt.
    See #64418.

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


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

diff --git a/wp-includes/class-wp-styles.php b/wp-includes/class-wp-styles.php
index a5d071da54..72af6c29b0 100644
--- a/wp-includes/class-wp-styles.php
+++ b/wp-includes/class-wp-styles.php
@@ -158,11 +158,11 @@ class WP_Styles extends WP_Dependencies {
 		$inline_style = $this->print_inline_style( $handle, false );

 		if ( $inline_style ) {
-			$inline_style_tag = sprintf(
-				"<style id='%s-inline-css'>\n%s\n</style>\n",
-				esc_attr( $handle ),
-				$inline_style
-			);
+			$processor = new WP_HTML_Tag_Processor( '<style></style>' );
+			$processor->next_tag();
+			$processor->set_attribute( 'id', "{$handle}-inline-css" );
+			$processor->set_modifiable_text( "\n{$inline_style}\n" );
+			$inline_style_tag = "{$processor->get_updated_html()}\n";
 		} else {
 			$inline_style_tag = '';
 		}
@@ -336,11 +336,11 @@ class WP_Styles extends WP_Dependencies {
 			return $output;
 		}

-		printf(
-			"<style id='%s-inline-css'>\n%s\n</style>\n",
-			esc_attr( $handle ),
-			$output
-		);
+		$processor = new WP_HTML_Tag_Processor( '<style></style>' );
+		$processor->next_tag();
+		$processor->set_attribute( 'id', "{$handle}-inline-css" );
+		$processor->set_modifiable_text( "\n{$output}\n" );
+		echo "{$processor->get_updated_html()}\n";

 		return true;
 	}
diff --git a/wp-includes/fonts/class-wp-font-face.php b/wp-includes/fonts/class-wp-font-face.php
index 96d51b19ff..193a5d0951 100644
--- a/wp-includes/fonts/class-wp-font-face.php
+++ b/wp-includes/fonts/class-wp-font-face.php
@@ -92,7 +92,10 @@ class WP_Font_Face {
 			return;
 		}

-		printf( $this->get_style_element(), $css );
+		$processor = new WP_HTML_Tag_Processor( '<style class="wp-fonts-local"></style>' );
+		$processor->next_tag();
+		$processor->set_modifiable_text( "\n{$css}\n" );
+		echo "{$processor->get_updated_html()}\n";
 	}

 	/**
@@ -193,17 +196,6 @@ class WP_Font_Face {
 		return $font_face;
 	}

-	/**
-	 * Gets the style element for wrapping the `@font-face` CSS.
-	 *
-	 * @since 6.4.0
-	 *
-	 * @return string The style element.
-	 */
-	private function get_style_element() {
-		return "<style class='wp-fonts-local'>\n%s\n</style>\n";
-	}
-
 	/**
 	 * Gets the `@font-face` CSS styles for locally-hosted font files.
 	 *
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index ffb2fffa5c..c0108dc848 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -2413,10 +2413,12 @@ function _print_styles() {
 		echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "' media='all' />\n";

 		if ( ! empty( $wp_styles->print_code ) ) {
-			echo "<style>\n";
-			echo $wp_styles->print_code;
-			echo sprintf( "\n/*# sourceURL=%s */", rawurlencode( $concat_source_url ) );
-			echo "\n</style>\n";
+			$processor = new WP_HTML_Tag_Processor( '<style></style>' );
+			$processor->next_tag();
+			$style_tag_contents = "\n{$wp_styles->print_code}\n"
+				. sprintf( "/*# sourceURL=%s */\n", rawurlencode( $concat_source_url ) );
+			$processor->set_modifiable_text( $style_tag_contents );
+			echo "{$processor->get_updated_html()}\n";
 		}
 	}

@@ -3171,7 +3173,10 @@ function wp_enqueue_block_support_styles( $style, $priority = 10 ) {
 	add_action(
 		$action_hook_name,
 		static function () use ( $style ) {
-			echo "<style>$style</style>\n";
+			$processor = new WP_HTML_Tag_Processor( '<style></style>' );
+			$processor->next_tag();
+			$processor->set_modifiable_text( $style );
+			echo "{$processor->get_updated_html()}\n";
 		},
 		$priority
 	);
diff --git a/wp-includes/theme.php b/wp-includes/theme.php
index 89d56d4e44..0ff915cbe4 100644
--- a/wp-includes/theme.php
+++ b/wp-includes/theme.php
@@ -1950,11 +1950,13 @@ function _custom_background_cb() {

 		$style .= $image . $position . $size . $repeat . $attachment;
 	}
-	?>
-<style<?php echo $type_attr; ?> id="custom-background-css">
-body.custom-background { <?php echo trim( $style ); ?> }
-</style>
-	<?php
+
+	$processor = new WP_HTML_Tag_Processor( "<style{$type_attr} id=\"custom-background-css\"></style>" );
+	$processor->next_tag();
+
+	$style_tag_content = 'body.custom-background { ' . trim( $style ) . ' }';
+	$processor->set_modifiable_text( "\n{$style_tag_content}\n" );
+	echo "{$processor->get_updated_html()}\n";
 }

 /**
@@ -1964,17 +1966,18 @@ body.custom-background { <?php echo trim( $style ); ?> }
  */
 function wp_custom_css_cb() {
 	$styles = wp_get_custom_css();
-	if ( $styles || is_customize_preview() ) :
-		$type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"';
-		?>
-		<style<?php echo $type_attr; ?> id="wp-custom-css">
-			<?php
-			// Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly.
-			echo strip_tags( $styles );
-			?>
-		</style>
-		<?php
-	endif;
+	if ( ! $styles && ! is_customize_preview() ) {
+		return;
+	}
+
+	$processor = new WP_HTML_Tag_Processor( '<style></style>' );
+	$processor->next_tag();
+	if ( ! current_theme_supports( 'html5', 'style' ) ) {
+		$processor->set_attribute( 'type', 'text/css' );
+	}
+	$processor->set_attribute( 'id', 'wp-custom-css' );
+	$processor->set_modifiable_text( "\n{$styles}\n" );
+	echo "{$processor->get_updated_html()}\n";
 }

 /**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 30a4e4e46c..ac2047f6ae 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.0-alpha-61417';
+$wp_version = '7.0-alpha-61418';

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