mirror of
git://develop.git.wordpress.org/
synced 2025-02-07 08:04:27 +01:00
KSES: Allow min()
, max()
, minmax()
, and clamp()
values to be used in inline CSS.
Additionally, this commit updates `safecss_filter_attr()` to add support for nested `var()` functions, so that a fallback value can be another CSS variable. Follow-up to [50923]. Props johnregan3, noisysocks, cbravobernal, uxl, isabel_brison, andrewserong, ramonopoly, joyously, bernhard-reiter, peterwilsoncc. Fixes #55966. git-svn-id: https://develop.svn.wordpress.org/trunk@54100 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
ad92f3ef9e
commit
cb6f447d52
@ -2228,6 +2228,8 @@ function kses_init() {
|
|||||||
* @since 5.3.1 Added support for gradient backgrounds.
|
* @since 5.3.1 Added support for gradient backgrounds.
|
||||||
* @since 5.7.1 Added support for `object-position`.
|
* @since 5.7.1 Added support for `object-position`.
|
||||||
* @since 5.8.0 Added support for `calc()` and `var()` values.
|
* @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.
|
||||||
*
|
*
|
||||||
* @param string $css A string of CSS rules.
|
* @param string $css A string of CSS rules.
|
||||||
* @param string $deprecated Not used.
|
* @param string $deprecated Not used.
|
||||||
@ -2467,13 +2469,20 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $found ) {
|
if ( $found ) {
|
||||||
// Allow CSS calc().
|
/*
|
||||||
$css_test_string = preg_replace( '/calc\(((?:\([^()]*\)?|[^()])*)\)/', '', $css_test_string );
|
* Allow CSS functions like var(), calc(), etc. by removing them from the test string.
|
||||||
// Allow CSS var().
|
* Nested functions and parentheses are also removed, so long as the parentheses are balanced.
|
||||||
$css_test_string = preg_replace( '/\(?var\(--[a-zA-Z0-9_-]*\)/', '', $css_test_string );
|
*/
|
||||||
|
$css_test_string = preg_replace(
|
||||||
|
'/\b(?:var|calc|min|max|minmax|clamp)(\((?:[^()]|(?1))*\))/',
|
||||||
|
'',
|
||||||
|
$css_test_string
|
||||||
|
);
|
||||||
|
|
||||||
// Check for any CSS containing \ ( & } = or comments,
|
/*
|
||||||
// except for url(), calc(), or var() usage checked above.
|
* 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 );
|
$allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -935,6 +935,7 @@ EOF;
|
|||||||
* @ticket 37248
|
* @ticket 37248
|
||||||
* @ticket 42729
|
* @ticket 42729
|
||||||
* @ticket 48376
|
* @ticket 48376
|
||||||
|
* @ticket 55966
|
||||||
* @dataProvider data_test_safecss_filter_attr
|
* @dataProvider data_test_safecss_filter_attr
|
||||||
*
|
*
|
||||||
* @param string $css A string of CSS rules.
|
* @param string $css A string of CSS rules.
|
||||||
@ -1120,6 +1121,121 @@ EOF;
|
|||||||
'css' => 'color: rgb( 100, 100, 100, .4 )',
|
'css' => 'color: rgb( 100, 100, 100, .4 )',
|
||||||
'expected' => '',
|
'expected' => '',
|
||||||
),
|
),
|
||||||
|
// Allow min().
|
||||||
|
array(
|
||||||
|
'css' => 'width: min(50%, 400px)',
|
||||||
|
'expected' => 'width: min(50%, 400px)',
|
||||||
|
),
|
||||||
|
// Allow max().
|
||||||
|
array(
|
||||||
|
'css' => 'width: max(50%, 40rem)',
|
||||||
|
'expected' => 'width: max(50%, 40rem)',
|
||||||
|
),
|
||||||
|
// Allow minmax().
|
||||||
|
array(
|
||||||
|
'css' => 'width: minmax(100px, 50%)',
|
||||||
|
'expected' => 'width: minmax(100px, 50%)',
|
||||||
|
),
|
||||||
|
// Allow clamp().
|
||||||
|
array(
|
||||||
|
'css' => 'width: clamp(100px, 50%, 100vw)',
|
||||||
|
'expected' => 'width: clamp(100px, 50%, 100vw)',
|
||||||
|
),
|
||||||
|
// Allow two functions in the same CSS.
|
||||||
|
array(
|
||||||
|
'css' => 'width: clamp(min(100px, 350px), 50%, 500px), 600px)',
|
||||||
|
'expected' => 'width: clamp(min(100px, 350px), 50%, 500px), 600px)',
|
||||||
|
),
|
||||||
|
// Allow gradient() function.
|
||||||
|
array(
|
||||||
|
'css' => 'background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)',
|
||||||
|
'expected' => 'background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)',
|
||||||
|
),
|
||||||
|
// Combined CSS function names.
|
||||||
|
array(
|
||||||
|
'css' => 'width: calcmax(100px + 50%)',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Allow calc().
|
||||||
|
array(
|
||||||
|
'css' => 'width: calc(2em + 3px)',
|
||||||
|
'expected' => 'width: calc(2em + 3px)',
|
||||||
|
),
|
||||||
|
// Allow calc() with nested brackets.
|
||||||
|
array(
|
||||||
|
'css' => 'width: calc(3em + (10px * 2))',
|
||||||
|
'expected' => 'width: calc(3em + (10px * 2))',
|
||||||
|
),
|
||||||
|
// Allow var().
|
||||||
|
array(
|
||||||
|
'css' => 'padding: var(--wp-var1) var(--wp-var2)',
|
||||||
|
'expected' => 'padding: var(--wp-var1) var(--wp-var2)',
|
||||||
|
),
|
||||||
|
// Allow var() with fallback (commas).
|
||||||
|
array(
|
||||||
|
'css' => 'padding: var(--wp-var1, 10px)',
|
||||||
|
'expected' => 'padding: var(--wp-var1, 10px)',
|
||||||
|
),
|
||||||
|
// Allow var() with fallback (percentage).
|
||||||
|
array(
|
||||||
|
'css' => 'padding: var(--wp-var1, 50%)',
|
||||||
|
'expected' => 'padding: var(--wp-var1, 50%)',
|
||||||
|
),
|
||||||
|
// Allow var() with fallback var().
|
||||||
|
array(
|
||||||
|
'css' => 'background-color: var(--wp-var, var(--wp-var-fallback, pink))',
|
||||||
|
'expected' => 'background-color: var(--wp-var, var(--wp-var-fallback, pink))',
|
||||||
|
),
|
||||||
|
// Allow var() with square brackets.
|
||||||
|
array(
|
||||||
|
'css' => 'background-color: var(--wp-var, [pink])',
|
||||||
|
'expected' => 'background-color: var(--wp-var, [pink])',
|
||||||
|
),
|
||||||
|
// Allow calc() with var().
|
||||||
|
array(
|
||||||
|
'css' => 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
|
||||||
|
'expected' => 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
|
||||||
|
),
|
||||||
|
// Malformed min, no closing `)`.
|
||||||
|
array(
|
||||||
|
'css' => 'width: min(3em + 10px',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed max, no closing `)`.
|
||||||
|
array(
|
||||||
|
'css' => 'width: max(3em + 10px',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed minmax, no closing `)`.
|
||||||
|
array(
|
||||||
|
'css' => 'width: minmax(3em + 10px',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed calc, no closing `)`.
|
||||||
|
array(
|
||||||
|
'css' => 'width: calc(3em + 10px',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed var, no closing `)`.
|
||||||
|
array(
|
||||||
|
'css' => 'width: var(--wp-var1',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed calc, mismatching brackets.
|
||||||
|
array(
|
||||||
|
'css' => 'width: calc(3em + (10px * 2)',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Malformed var, mismatching brackets.
|
||||||
|
array(
|
||||||
|
'css' => 'background-color: var(--wp-var, var(--wp-var-fallback, pink)',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
|
// Don't allow expressions outside of a calc().
|
||||||
|
array(
|
||||||
|
'css' => 'width: (3em + (10px * 2))',
|
||||||
|
'expected' => '',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,24 +1417,6 @@ EOF;
|
|||||||
'background: red',
|
'background: red',
|
||||||
),
|
),
|
||||||
|
|
||||||
// CSS calc().
|
|
||||||
array(
|
|
||||||
'width: calc(2em + 3px)',
|
|
||||||
'width: calc(2em + 3px)',
|
|
||||||
),
|
|
||||||
|
|
||||||
// CSS variable.
|
|
||||||
array(
|
|
||||||
'padding: var(--wp-var1) var(--wp-var2)',
|
|
||||||
'padding: var(--wp-var1) var(--wp-var2)',
|
|
||||||
),
|
|
||||||
|
|
||||||
// CSS calc() with var().
|
|
||||||
array(
|
|
||||||
'margin-top: calc(var(--wp-var1) * 3 + 2em)',
|
|
||||||
'margin-top: calc(var(--wp-var1) * 3 + 2em)',
|
|
||||||
),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalid use cases.
|
* Invalid use cases.
|
||||||
*/
|
*/
|
||||||
@ -1382,18 +1480,6 @@ EOF;
|
|||||||
'background-image: url( "http://example.com );',
|
'background-image: url( "http://example.com );',
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
|
|
||||||
// Malformed calc, no closing `)`.
|
|
||||||
array(
|
|
||||||
'width: calc(3em + 10px',
|
|
||||||
'',
|
|
||||||
),
|
|
||||||
|
|
||||||
// Malformed var, no closing `)`.
|
|
||||||
array(
|
|
||||||
'width: var(--wp-var1',
|
|
||||||
'',
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,7 +1602,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
),
|
),
|
||||||
'core/cover' => array(
|
'core/cover' => array(
|
||||||
'filter' => array(
|
'filter' => array(
|
||||||
'duotone' => 'var(--wp--preset--duotone--blue-red, var(--fallback-unsafe))',
|
'duotone' => 'var(--invalid',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'core/group' => array(
|
'core/group' => array(
|
||||||
@ -1676,7 +1676,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'border' => array(
|
'border' => array(
|
||||||
'radius' => array(
|
'radius' => array(
|
||||||
'topLeft' => '6px',
|
'topLeft' => '6px',
|
||||||
'topRight' => 'var(--top-right, var(--unsafe-fallback))',
|
'topRight' => 'var(--invalid',
|
||||||
'bottomRight' => '6px',
|
'bottomRight' => '6px',
|
||||||
'bottomLeft' => '6px',
|
'bottomLeft' => '6px',
|
||||||
),
|
),
|
||||||
@ -1685,7 +1685,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'padding' => array(
|
'padding' => array(
|
||||||
'top' => '1px',
|
'top' => '1px',
|
||||||
'right' => '1px',
|
'right' => '1px',
|
||||||
'bottom' => 'var(--bottom, var(--unsafe-fallback))',
|
'bottom' => 'var(--invalid',
|
||||||
'left' => '1px',
|
'left' => '1px',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1695,7 +1695,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'padding' => array(
|
'padding' => array(
|
||||||
'top' => '2px',
|
'top' => '2px',
|
||||||
'right' => '2px',
|
'right' => '2px',
|
||||||
'bottom' => 'var(--bottom, var(--unsafe-fallback))',
|
'bottom' => 'var(--invalid',
|
||||||
'left' => '2px',
|
'left' => '2px',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1706,7 +1706,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'border' => array(
|
'border' => array(
|
||||||
'radius' => array(
|
'radius' => array(
|
||||||
'topLeft' => '5px',
|
'topLeft' => '5px',
|
||||||
'topRight' => 'var(--top-right, var(--unsafe-fallback))',
|
'topRight' => 'var(--invalid',
|
||||||
'bottomRight' => '5px',
|
'bottomRight' => '5px',
|
||||||
'bottomLeft' => '5px',
|
'bottomLeft' => '5px',
|
||||||
),
|
),
|
||||||
@ -1715,7 +1715,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'padding' => array(
|
'padding' => array(
|
||||||
'top' => '3px',
|
'top' => '3px',
|
||||||
'right' => '3px',
|
'right' => '3px',
|
||||||
'bottom' => 'var(bottom, var(--unsafe-fallback))',
|
'bottom' => 'var(--invalid',
|
||||||
'left' => '3px',
|
'left' => '3px',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1725,7 +1725,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
'padding' => array(
|
'padding' => array(
|
||||||
'top' => '4px',
|
'top' => '4px',
|
||||||
'right' => '4px',
|
'right' => '4px',
|
||||||
'bottom' => 'var(--bottom, var(--unsafe-fallback))',
|
'bottom' => 'var(--invalid',
|
||||||
'left' => '4px',
|
'left' => '4px',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1944,7 +1944,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
array(
|
array(
|
||||||
'name' => 'Blue',
|
'name' => 'Blue',
|
||||||
'slug' => 'blue',
|
'slug' => 'blue',
|
||||||
'color' => 'var(--color, var(--unsafe-fallback))',
|
'color' => 'var(--invalid',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'Pink',
|
'name' => 'Pink',
|
||||||
@ -1975,7 +1975,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
array(
|
array(
|
||||||
'name' => 'Helvetica Arial',
|
'name' => 'Helvetica Arial',
|
||||||
'slug' => 'helvetica-arial',
|
'slug' => 'helvetica-arial',
|
||||||
'fontFamily' => 'var(--fontFamily, var(--unsafe-fallback))',
|
'fontFamily' => 'var(--invalid',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1998,7 +1998,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
|
|||||||
array(
|
array(
|
||||||
'name' => 'Blue',
|
'name' => 'Blue',
|
||||||
'slug' => 'blue',
|
'slug' => 'blue',
|
||||||
'color' => 'var(--color, var(--unsafe--fallback))',
|
'color' => 'var(--invalid',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'Pink',
|
'name' => 'Pink',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user