diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 28bbce222a214..c58bb0dac4c47 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2587,6 +2587,28 @@ function safecss_filter_attr( $css, $deprecated = '' ) { 'list-style-image', ); + /* + * CSS attributes that accept rgb(a) color data types. + * + */ + $css_color_data_types = array( + 'color', + + 'border', + 'border-color', + 'border-right', + 'border-right-color', + 'border-bottom', + 'border-bottom-color', + 'border-left', + 'border-left-color', + 'border-top', + 'border-top-color', + + 'background', + 'background-color', + ); + /* * CSS attributes that accept gradient data types. * @@ -2610,6 +2632,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) { $css_test_string = $css_item; $found = false; $url_attr = false; + $color_attr = false; $gradient_attr = false; $is_custom_var = false; @@ -2629,6 +2652,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 ); + $color_attr = in_array( $css_selector, $css_color_data_types, true ); } if ( $is_custom_var ) { @@ -2671,6 +2695,16 @@ function safecss_filter_attr( $css, $deprecated = '' ) { } } + if ( $found && $color_attr ) { + $css_value = trim( $parts[1] ); + $comma_syntax = '/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i'; + $space_syntax = '/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i'; + + if ( preg_match( $comma_syntax, $css_value ) || preg_match( $space_syntax, $css_value ) ) { + $css_test_string = str_replace( $css_value, '', $css_test_string ); + } + } + if ( $found ) { /* * Allow CSS functions like var(), calc(), etc. by removing them from the test string. diff --git a/tests/phpunit/tests/kses.php b/tests/phpunit/tests/kses.php index e3bd074511d2c..d1ea60490ab86 100644 --- a/tests/phpunit/tests/kses.php +++ b/tests/phpunit/tests/kses.php @@ -1178,16 +1178,7 @@ public function data_safecss_filter_attr() { 'css' => 'height: expression( body.scrollTop + 50 + "px" )', 'expected' => '', ), - // RGB color values are not allowed. - array( - 'css' => 'color: rgb( 100, 100, 100 )', - 'expected' => '', - ), - // RGBA color values are not allowed. - array( - 'css' => 'color: rgb( 100, 100, 100, .4 )', - 'expected' => '', - ), + // Allow min(). array( 'css' => 'width: min(50%, 400px)', @@ -1308,6 +1299,73 @@ public function data_safecss_filter_attr() { 'css' => 'gap: 10px;column-gap: 5px;row-gap: 20px', 'expected' => 'gap: 10px;column-gap: 5px;row-gap: 20px', ), + + // RGB color. + array( + 'css' => 'color: rgb(255, 0, 0)', + 'expected' => 'color: rgb(255, 0, 0)', + ), + array( + 'css' => 'color: rgb(255 0 0)', + 'expected' => 'color: rgb(255 0 0)', + ), + array( + 'css' => 'color: rgb(100%, 0%, 50%)', + 'expected' => 'color: rgb(100%, 0%, 50%)', + ), + array( + 'css' => 'color: rgb(255, 50%, 0)', + 'expected' => 'color: rgb(255, 50%, 0)', + ), + // RGBA color. + array( + 'css' => 'color: rgba(255, 128, 0, 0.5)', + 'expected' => 'color: rgba(255, 128, 0, 0.5)', + ), + array( + 'css' => 'color: rgb(255 128 0 / 50%)', + 'expected' => 'color: rgb(255 128 0 / 50%)', + ), + // RGB color with extra whitespace. + array( + 'css' => 'color: rgb( 255 , 128 , 0 )', + 'expected' => 'color: rgb( 255 , 128 , 0 )', + ), + // RGB background color. + array( + 'css' => 'background-color: rgb(200, 100, 50)', + 'expected' => 'background-color: rgb(200, 100, 50)', + ), + // RGBA border color. + array( + 'css' => 'border-color: rgba(100, 200, 300, 0.8)', + 'expected' => 'border-color: rgba(100, 200, 300, 0.8)', + ), + // Malformed RGB color, invalid number of values. + array( + 'css' => 'color: rgb(255, 128, 0, 0.5, 100)', + 'expected' => '', + ), + array( + 'css' => 'color: rgb(255, 128)', + 'expected' => '', + ), + // Malformed RGB color, non-numeric values. + array( + 'css' => 'color: rgb(red, green, blue)', + 'expected' => '', + ), + // Malformed RGB color, unmatched parentheses. + array( + 'css' => 'color: rgb(255, 128, 0', + 'expected' => '', + ), + // Malformed RGB color, empty values. + array( + 'css' => 'color: rgb(, , )', + 'expected' => '', + ), + // Margin and padding logical properties introduced in 6.1. array( 'css' => 'margin-block-start: 1px;margin-block-end: 2px;margin-inline-start: 3px;margin-inline-end: 4px;',