From 3c0cebc45ae78a3dabb2565cc1177b2eaf98c84f Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 9 Sep 2022 12:37:47 +0000 Subject: [PATCH] KSES: Allow assigning values to CSS variables. The `safecss_filter_attr()` function allows using custom CSS variables like `color: var(--color)`. However, it did not allow assigning values to CSS variables like `--color: #F00`, which is common in Global Styles and Gutenberg. This commit adds support for assigning values to CSS variables, so that the function can be used consistently in Global Styles and the future Style Engine in Gutenberg. Follow-up to [50923], [54100]. Props aristath, ramonopoly, SergeyBiryukov. Fixes #56353. git-svn-id: https://develop.svn.wordpress.org/trunk@54117 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/kses.php | 18 +++++++++++++++++- tests/phpunit/tests/kses.php | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 2be0b5e14c3cf..7776de59d55d6 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2229,7 +2229,7 @@ function kses_init() { * @since 5.7.1 Added support for `object-position`. * @since 5.8.0 Added support for `calc()` and `var()` values. * @since 6.1.0 Added support for `min()`, `max()`, `minmax()`, `clamp()`, - * and nested `var()` values. + * nested `var()` values, and assigning values to CSS variables. * Added support for `gap`, `column-gap`, `row-gap`, and `flex-wrap`. * Extended `margin-*` and `padding-*` support for logical properties. * @@ -2391,6 +2391,9 @@ function safecss_filter_attr( $css, $deprecated = '' ) { 'object-position', 'overflow', 'vertical-align', + + // Custom CSS properties. + '--*', ) ); @@ -2436,6 +2439,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) { $found = false; $url_attr = false; $gradient_attr = false; + $is_custom_var = false; if ( strpos( $css_item, ':' ) === false ) { $found = true; @@ -2443,11 +2447,23 @@ function safecss_filter_attr( $css, $deprecated = '' ) { $parts = explode( ':', $css_item, 2 ); $css_selector = trim( $parts[0] ); + // Allow assigning values to CSS variables. + if ( in_array( '--*', $allowed_attr, true ) && preg_match( '/^--[a-zA-Z0-9-_]+$/', $css_selector ) ) { + $allowed_attr[] = $css_selector; + $is_custom_var = true; + } + if ( in_array( $css_selector, $allowed_attr, true ) ) { $found = true; $url_attr = in_array( $css_selector, $css_url_data_types, true ); $gradient_attr = in_array( $css_selector, $css_gradient_data_types, true ); } + + if ( $is_custom_var ) { + $css_value = trim( $parts[1] ); + $url_attr = str_starts_with( $css_value, 'url(' ); + $gradient_attr = str_contains( $css_value, '-gradient(' ); + } } if ( $found && $url_attr ) { diff --git a/tests/phpunit/tests/kses.php b/tests/phpunit/tests/kses.php index 274c5aaf7be06..5871f0fe3397f 100644 --- a/tests/phpunit/tests/kses.php +++ b/tests/phpunit/tests/kses.php @@ -1247,6 +1247,23 @@ public function data_test_safecss_filter_attr() { 'css' => 'margin-block-start: 1px;margin-block-end: 2px;margin-inline-start: 3px;margin-inline-end: 4px;padding-block-start: 1px;padding-block-end: 2px;padding-inline-start: 3px;padding-inline-end: 4px', 'expected' => 'margin-block-start: 1px;margin-block-end: 2px;margin-inline-start: 3px;margin-inline-end: 4px;padding-block-start: 1px;padding-block-end: 2px;padding-inline-start: 3px;padding-inline-end: 4px', ), + // Assigning values to CSS variables introduced in 6.1. + array( + 'css' => '--wp--medium-width: 100px; --var_with_underscores: #cccccc;', + 'expected' => '--wp--medium-width: 100px;--var_with_underscores: #cccccc', + ), + array( + 'css' => '--miXeD-CAse: red; --with-numbers-3_56: red; --with-url-value: url("foo.jpg");', + 'expected' => '--miXeD-CAse: red;--with-numbers-3_56: red;--with-url-value: url("foo.jpg")', + ), + array( + 'css' => '--with-gradient: repeating-linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);', + 'expected' => '--with-gradient: repeating-linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', + ), + array( + 'css' => '--?><.%-not-allowed: red;', + 'expected' => '', + ), ); }