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 > 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.