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
This commit is contained in:
jonsurrell
2025-12-30 13:03:34 +00:00
parent b9a793c0f1
commit fe6a992df0
5 changed files with 44 additions and 44 deletions

View File

@@ -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;
}

View File

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

View File

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

View File

@@ -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";
}
/**

View File

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