-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Post Featured Image: Shadows not applied to block instances #62207
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress. If so, it is recommended to create a new Trac ticket and submit a pull request to the WordPress Core Github repository soon after this pull request is merged. If you're unsure, you can always ask for help in the #core-editor channel in WordPress Slack. Thank you! ❤️ View changed files❔ packages/block-library/src/post-featured-image/index.php |
Flaky tests detected in b06dfbb. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/9338411881
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this — unfortunately I'm not able to reproduce the bug on trunk
. When setting an individual featured image block to use a shadow (either one of the default shadows, or a custom shadow defined in the site editor's global styles), I can see the shadow output in the site frontend, and the css
key is returned by the style engine.
CSS key:
Site frontend
Bundled shadow | Custom shadow in global styles |
---|---|
I'm testing with GB trunk in a test site running WP 6.5.3, and with TT4 theme. Do you have any additional testing instructions that might help us debug this?
Rather than merge this PR, I'd be keen for us to figure out in which conditions the CSS key isn't being returned by this style engine call, in case this fix masks another issue, and since I haven't been able to reproduce the problem so far.
CC: @ramonjd for visibility since this is style engine related 😅
Thanks for the ping, and for the PR @t-hamano I can replicate with a hardcoded value, e.g., $shadow_styles = wp_style_engine_get_styles( array( 'shadow' => '6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1)' ) );
Good call. It seems to be rather an issue with It doesn't pass the following test: /*
* Allow CSS functions like var(), calc(), etc. by removing them from the test string.
* Nested functions and parentheses are also removed, so long as the parentheses are balanced.
*/
$css_test_string = preg_replace(
'/\b(?:var|calc|min|max|minmax|clamp|repeat)(\((?:[^()]|(?1))*\))/',
'',
$css_test_string
);
/*
* Disallow CSS containing \ ( & } = or comments, except for within url(), var(), calc(), etc.
* which were removed from the test string above.
*/
$allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ); See: https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/kses.php#L2606 From looking, it's because WordPress doesn't allow I think WordPress should allow
So I reckon, rather than hardcode a fix only for one block, let's fix it every where by adding a hook on |
Ah, I think it's because it's matching $allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ); |
I haven't tested it, but would it work to add |
So something like this might work: Just allowing RGB(A)if ( ! function_exists( 'gutenberg_safecss_filter_attr_allow_rgb' ) ) {
/**
* Filters the check for unsafe CSS in `safecss_filter_attr` to allow `rgba()`.
*
* @param bool $allow_css Whether the CSS in the test string is considered safe.
* @param string $css_test_string The CSS string to test.
*/
function gutenberg_safecss_filter_attr_allow_rgb( $allow_css, $css_test_string ) {
/*
* Allow CSS functions like var(), calc(), etc. by removing them from the test string.
* Nested functions and parentheses are also removed, so long as the parentheses are balanced.
*/
$css_test_string = preg_replace(
// SINGLE CHANGE HERE: adding `|rgb[a]?`
'/\b(?:var|calc|min|max|minmax|clamp|repeat|rgb[a]?)(\((?:[^()]|(?1))*\))/',
'',
$css_test_string
);
/*
* Disallow CSS containing \ ( & } = or comments, except for within url(), var(), calc(), etc.
* which were removed from the test string above.
*/
return ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string );
}
}
add_filter( 'safecss_filter_attr_allow_css', 'gutenberg_safecss_filter_attr_allow_rgb', 10, 2 ); It will allow Therefore we should check whether we need something stricter for With extra checks for RGB(A)if ( ! function_exists( 'gutenberg_safecss_filter_attr_allow_rgb' ) ) {
/**
* Filters the check for unsafe CSS in `safecss_filter_attr` to allow `rgba()`.
*
* @param bool $allow_css Whether the CSS in the test string is considered safe.
* @param string $css_test_string The CSS string to test.
*/
function gutenberg_safecss_filter_attr_allow_rgb( $allow_css, $css_test_string ) {
$parts = explode( ':', $css_test_string, 2 );
$css_value = trim( $parts[1] );
$has_rgb = str_contains( $css_value, 'rgba(' ) || str_contains( $css_value, 'rgb(' );
// Check that rgb(a) values are digits.
if ( $has_rgb ) {
$regex = '/rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(,\s*\d(\.\d+)?)?\s*\)/';
if ( preg_match_all( $regex, $css_value ) ) {
$css_test_string = str_replace( $css_value, '', $css_test_string );
}
}
/*
* The code below is taken from Core: wp-includes/kses.php.
* It does not need backporting.
*/
/*
* Allow CSS functions like var(), calc(), etc. by removing them from the test string.
* Nested functions and parentheses are also removed, so long as the parentheses are balanced.
*/
$css_test_string = preg_replace(
'/\b(?:var|calc|min|max|minmax|clamp|repeat)(\((?:[^()]|(?1))*\))/',
'',
$css_test_string
);
/*
* Disallow CSS containing \ ( & } = or comments, except for within url(), var(), calc(), etc.
* which were removed from the test string above.
*/
$allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string );
}
}
add_filter( 'safecss_filter_attr_allow_css', 'gutenberg_safecss_filter_attr_allow_rgb', 10, 2 );
|
Yeah, I was just testing that So It's probably good enough. It'll also open up But if we want to add an extra layer of security, then the rgb value can also be checked, e.g., // Check that rgb(a) values are digits.
if ( $has_rgb ) {
$regex = '/rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(,\s*\d(\.\d+)?)?\s*\)/';
if ( preg_match_all( $regex, $css_value ) ) {
$css_test_string = str_replace( $css_value, '', $css_test_string );
}
} |
Thanks for the detailed advice! I should have looked deeper 😅 I looked into why this issue was difficult to reproduce and found that normally the shadow preset is applied with CSS variables just like other presets:
However, after updating the shadow preset or applying the shadow several times, I found that somehow it changed to a hardcoded value with
I agree with you that a more fundamental approach is needed as you suggested. While looking through Trac, I found a changeset that allows rgba for background colors: https://core.trac.wordpress.org/ticket/48376 In light of this approach, I am considering submitting a core patch limited to certain CSS properties. For example, the following code: Patch Examplediff --git a/wp-includes/kses.php b/wp-includes/kses.php
index 8ab9afd5..99b049c6 100644
--- a/wp-includes/kses.php
+++ b/wp-includes/kses.php
@@ -2513,6 +2513,14 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
'background-image',
);
+ /*
+ * CSS attributes that accept rgba data types.
+ *
+ */
+ $css_rgba_data_types = array(
+ 'box-shadow'
+ );
+
if ( empty( $allowed_attr ) ) {
return $css;
}
@@ -2528,6 +2536,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
$found = false;
$url_attr = false;
$gradient_attr = false;
+ $rgba_attr = false;
$is_custom_var = false;
if ( ! str_contains( $css_item, ':' ) ) {
@@ -2546,6 +2555,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
$found = true;
$url_attr = in_array( $css_selector, $css_url_data_types, true );
$gradient_attr = in_array( $css_selector, $css_gradient_data_types, true );
+ $rgba_attr = in_array( $css_selector, $css_rgba_data_types, true );
}
if ( $is_custom_var ) {
@@ -2588,6 +2598,14 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
}
}
+ if ( $found && $rgba_attr ) {
+ $css_value = trim( $parts[1] );
+ if ( preg_match( '/rgb(a)?\([^)]+\)/', $css_value ) ) {
+ // Remove the whole `rgba` bit that was matched above from the CSS.
+ $css_test_string = str_replace( $css_value, '', $css_test_string );
+ }
+ }
+
if ( $found ) { Maybe it would be better to add an equivalent filter in Gutenberg after the core patch is comitted. What do you think? |
Thanks @t-hamano !! In my opinion, a Core patch would be the way to go then we can decide if a filter in Gutenberg is necessary. I'm happy to help out, or test when it's ready.
What do you think about allowing |
I think allowing everywhere would be the way to go. My understanding is that the safe CSS filters are about avoiding dangerous CSS values, not about validating CSS, so I think allowing |
I discovered there was a ticket (opened 11 years ago!) proposing to allow I proposed to move the ticket forward, so I'd like to close this PR for now. If Thanks everyone for the advice! |
Now that folks have had 11 years to think about it, I think the time is right! Thanks for pursuing this @t-hamano |
Follow up #59616
What?
This PR fixes an issue where the shadow is not applied to the Post Featured block under the following conditions:
Why?
In the current implementation, CSS is generated via the style engine in the render callback function.
However, the value returned from the style engine is as follows and does not contain
css
key:How?
Shadow is just a CSS value, and there is no class like
has-shadow
. In this case, I don't think there is any need to use the style engine.Testing Instructions