Skip to content

Commit 19537ea

Browse files
committed
switch to encoded string to stop kses mangling
1 parent a007350 commit 19537ea

2 files changed

Lines changed: 20 additions & 47 deletions

File tree

src/wp-includes/block-supports/custom-css.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ function wp_render_custom_css_support_styles( $parsed_block ) {
2626
return $parsed_block;
2727
}
2828

29-
// Validate CSS doesn't contain HTML markup (same validation as global styles REST API).
30-
if ( preg_match( '#</?\w+#', $custom_css ) ) {
31-
return $parsed_block;
32-
}
33-
3429
// Generate a unique class name for this block instance.
3530
$class_name = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' );
3631
$updated_class_name = isset( $parsed_block['attrs']['className'] )

src/wp-includes/blocks.php

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,16 +2075,28 @@ function _filter_block_content_callback( $matches ) {
20752075
* @return array The filtered and sanitized block object result.
20762076
*/
20772077
function filter_block_kses( $block, $allowed_html, $allowed_protocols = array() ) {
2078+
/*
2079+
* Per-block custom CSS (attrs.style.css) may contain characters like <, >,
2080+
* and & that are valid in CSS but would be mangled by wp_kses(), which treats
2081+
* all values as HTML. Encode these characters as JSON unicode escapes before
2082+
* KSES runs, then decode afterwards. This is the same approach used for
2083+
* Global Styles custom CSS (see r61486).
2084+
*/
2085+
$has_block_css = isset( $block['attrs']['style']['css'] );
2086+
if ( $has_block_css ) {
2087+
// wp_json_encode wraps the string in quotes: "encoded content".
2088+
// Trim them to get the raw escaped content as a PHP string.
2089+
$block['attrs']['style']['css'] = trim(
2090+
wp_json_encode( $block['attrs']['style']['css'], JSON_HEX_TAG | JSON_HEX_AMP ),
2091+
'"'
2092+
);
2093+
}
2094+
20782095
$block['attrs'] = filter_block_kses_value( $block['attrs'], $allowed_html, $allowed_protocols, $block );
20792096

2080-
// Per-block custom CSS (attrs.style.css) may contain & and > as valid
2081-
// CSS selectors. wp_kses() entity-encodes these because it treats the
2082-
// value as HTML. Decode them after KSES has already stripped any
2083-
// dangerous HTML tags, so the CSS round-trips correctly through
2084-
// serialize_block_attributes().
2085-
if ( isset( $block['attrs']['style']['css'] ) ) {
2086-
$block['attrs']['style']['css'] = undo_block_custom_css_kses_entities(
2087-
$block['attrs']['style']['css']
2097+
if ( $has_block_css && isset( $block['attrs']['style']['css'] ) ) {
2098+
$block['attrs']['style']['css'] = json_decode(
2099+
'"' . $block['attrs']['style']['css'] . '"'
20882100
);
20892101
}
20902102

@@ -2135,40 +2147,6 @@ function filter_block_kses_value( $value, $allowed_html, $allowed_protocols = ar
21352147
return $value;
21362148
}
21372149

2138-
/**
2139-
* Decodes HTML entities in per-block custom CSS that were incorrectly
2140-
* introduced by wp_kses() during the block KSES filtering pipeline.
2141-
*
2142-
* Per-block custom CSS (stored in attrs.style.css) may contain & and >
2143-
* as valid CSS selectors (nesting and child combinator). When wp_kses()
2144-
* processes this CSS string as if it were HTML, it entity-encodes these
2145-
* characters (&amp;, &gt;). If the block is then re-serialized via
2146-
* serialize_block_attributes(), the entity's ampersand is escaped again
2147-
* (\u0026amp;), producing a double-encoded value that corrupts the CSS
2148-
* on subsequent editor loads.
2149-
*
2150-
* This reverses only the specific named entities that wp_kses() may
2151-
* introduce, intentionally narrower than wp_specialchars_decode() to
2152-
* avoid decoding numeric/hex references that KSES intentionally preserved.
2153-
*
2154-
* @since 7.0
2155-
*
2156-
* @param string $value Per-block custom CSS string potentially containing
2157-
* KSES-introduced entities.
2158-
* @return string CSS string with KSES-introduced entities decoded.
2159-
*/
2160-
function undo_block_custom_css_kses_entities( $value ) {
2161-
if ( ! is_string( $value ) || false === strpos( $value, '&' ) ) {
2162-
return $value;
2163-
}
2164-
2165-
return str_replace(
2166-
array( '&amp;', '&gt;', '&quot;', '&#039;' ),
2167-
array( '&', '>', '"', "'" ),
2168-
$value
2169-
);
2170-
}
2171-
21722150
/**
21732151
* Sanitizes the value of the Template Part block's `tagName` attribute.
21742152
*

0 commit comments

Comments
 (0)