diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 9d5b13426f4ef..83ab0841e2748 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -26,11 +26,6 @@ function wp_render_custom_css_support_styles( $parsed_block ) { return $parsed_block; } - // Validate CSS doesn't contain HTML markup (same validation as global styles REST API). - if ( preg_match( '#, + * and & that are valid in CSS but would be mangled by wp_kses(), which treats + * all values as HTML. Encode these characters as JSON unicode escapes before + * KSES runs, then decode afterwards. This is the same approach used for + * Global Styles custom CSS (see r61486). + */ + $has_block_css = isset( $block['attrs']['style']['css'] ); + if ( $has_block_css ) { + // wp_json_encode wraps the string in quotes: "encoded content". + // Trim them to get the raw escaped content as a PHP string. + $block['attrs']['style']['css'] = trim( + wp_json_encode( $block['attrs']['style']['css'], JSON_HEX_TAG | JSON_HEX_AMP ), + '"' + ); + } + $block['attrs'] = filter_block_kses_value( $block['attrs'], $allowed_html, $allowed_protocols, $block ); + if ( $has_block_css && isset( $block['attrs']['style']['css'] ) ) { + $block['attrs']['style']['css'] = json_decode( + '"' . $block['attrs']['style']['css'] . '"' + ); + } + if ( is_array( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as $i => $inner_block ) { $block['innerBlocks'][ $i ] = filter_block_kses( $inner_block, $allowed_html, $allowed_protocols );