Make WordPress Core

Changeset 54100


Ignore:
Timestamp:
09/08/2022 01:24:10 PM (4 years ago)
Author:
SergeyBiryukov
Message:

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.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/kses.php

    r54093 r54100  
    22292229 * @since 5.7.1 Added support for `object-position`.
    22302230 * @since 5.8.0 Added support for `calc()` and `var()` values.
     2231 * @since 6.1.0 Added support for `min()`, `max()`, `minmax()`, `clamp()`,
     2232 *              and nested `var()` values.
    22312233 *
    22322234 * @param string $css        A string of CSS rules.
     
    24682470
    24692471                if ( $found ) {
    2470                         // Allow CSS calc().
    2471                         $css_test_string = preg_replace( '/calc\(((?:\([^()]*\)?|[^()])*)\)/', '', $css_test_string );
    2472                         // Allow CSS var().
    2473                         $css_test_string = preg_replace( '/\(?var\(--[a-zA-Z0-9_-]*\)/', '', $css_test_string );
    2474 
    2475                         // Check for any CSS containing \ ( & } = or comments,
    2476                         // except for url(), calc(), or var() usage checked above.
     2472                        /*
     2473                         * Allow CSS functions like var(), calc(), etc. by removing them from the test string.
     2474                         * Nested functions and parentheses are also removed, so long as the parentheses are balanced.
     2475                         */
     2476                        $css_test_string = preg_replace(
     2477                                '/\b(?:var|calc|min|max|minmax|clamp)(\((?:[^()]|(?1))*\))/',
     2478                                '',
     2479                                $css_test_string
     2480                        );
     2481
     2482                        /*
     2483                         * Disallow CSS containing \ ( & } = or comments, except for within url(), var(), calc(), etc.
     2484                         * which were removed from the test string above.
     2485                         */
    24772486                        $allow_css = ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string );
    24782487
  • trunk/tests/phpunit/tests/kses.php

    r54093 r54100  
    936936         * @ticket 42729
    937937         * @ticket 48376
     938         * @ticket 55966
    938939         * @dataProvider data_test_safecss_filter_attr
    939940         *
     
    11211122                                'expected' => '',
    11221123                        ),
     1124                        // Allow min().
     1125                        array(
     1126                                'css'      => 'width: min(50%, 400px)',
     1127                                'expected' => 'width: min(50%, 400px)',
     1128                        ),
     1129                        // Allow max().
     1130                        array(
     1131                                'css'      => 'width: max(50%, 40rem)',
     1132                                'expected' => 'width: max(50%, 40rem)',
     1133                        ),
     1134                        // Allow minmax().
     1135                        array(
     1136                                'css'      => 'width: minmax(100px, 50%)',
     1137                                'expected' => 'width: minmax(100px, 50%)',
     1138                        ),
     1139                        // Allow clamp().
     1140                        array(
     1141                                'css'      => 'width: clamp(100px, 50%, 100vw)',
     1142                                'expected' => 'width: clamp(100px, 50%, 100vw)',
     1143                        ),
     1144                        // Allow two functions in the same CSS.
     1145                        array(
     1146                                'css'      => 'width: clamp(min(100px, 350px), 50%, 500px), 600px)',
     1147                                'expected' => 'width: clamp(min(100px, 350px), 50%, 500px), 600px)',
     1148                        ),
     1149                        // Allow gradient() function.
     1150                        array(
     1151                                'css'      => 'background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)',
     1152                                'expected' => 'background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)',
     1153                        ),
     1154                        // Combined CSS function names.
     1155                        array(
     1156                                'css'      => 'width: calcmax(100px + 50%)',
     1157                                'expected' => '',
     1158                        ),
     1159                        // Allow calc().
     1160                        array(
     1161                                'css'      => 'width: calc(2em + 3px)',
     1162                                'expected' => 'width: calc(2em + 3px)',
     1163                        ),
     1164                        // Allow calc() with nested brackets.
     1165                        array(
     1166                                'css'      => 'width: calc(3em + (10px * 2))',
     1167                                'expected' => 'width: calc(3em + (10px * 2))',
     1168                        ),
     1169                        // Allow var().
     1170                        array(
     1171                                'css'      => 'padding: var(--wp-var1) var(--wp-var2)',
     1172                                'expected' => 'padding: var(--wp-var1) var(--wp-var2)',
     1173                        ),
     1174                        // Allow var() with fallback (commas).
     1175                        array(
     1176                                'css'      => 'padding: var(--wp-var1, 10px)',
     1177                                'expected' => 'padding: var(--wp-var1, 10px)',
     1178                        ),
     1179                        // Allow var() with fallback (percentage).
     1180                        array(
     1181                                'css'      => 'padding: var(--wp-var1, 50%)',
     1182                                'expected' => 'padding: var(--wp-var1, 50%)',
     1183                        ),
     1184                        // Allow var() with fallback var().
     1185                        array(
     1186                                'css'      => 'background-color: var(--wp-var, var(--wp-var-fallback, pink))',
     1187                                'expected' => 'background-color: var(--wp-var, var(--wp-var-fallback, pink))',
     1188                        ),
     1189                        // Allow var() with square brackets.
     1190                        array(
     1191                                'css'      => 'background-color: var(--wp-var, [pink])',
     1192                                'expected' => 'background-color: var(--wp-var, [pink])',
     1193                        ),
     1194                        // Allow calc() with var().
     1195                        array(
     1196                                'css'      => 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
     1197                                'expected' => 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
     1198                        ),
     1199                        // Malformed min, no closing `)`.
     1200                        array(
     1201                                'css'      => 'width: min(3em + 10px',
     1202                                'expected' => '',
     1203                        ),
     1204                        // Malformed max, no closing `)`.
     1205                        array(
     1206                                'css'      => 'width: max(3em + 10px',
     1207                                'expected' => '',
     1208                        ),
     1209                        // Malformed minmax, no closing `)`.
     1210                        array(
     1211                                'css'      => 'width: minmax(3em + 10px',
     1212                                'expected' => '',
     1213                        ),
     1214                        // Malformed calc, no closing `)`.
     1215                        array(
     1216                                'css'      => 'width: calc(3em + 10px',
     1217                                'expected' => '',
     1218                        ),
     1219                        // Malformed var, no closing `)`.
     1220                        array(
     1221                                'css'      => 'width: var(--wp-var1',
     1222                                'expected' => '',
     1223                        ),
     1224                        // Malformed calc, mismatching brackets.
     1225                        array(
     1226                                'css'      => 'width: calc(3em + (10px * 2)',
     1227                                'expected' => '',
     1228                        ),
     1229                        // Malformed var, mismatching brackets.
     1230                        array(
     1231                                'css'      => 'background-color: var(--wp-var, var(--wp-var-fallback, pink)',
     1232                                'expected' => '',
     1233                        ),
     1234                        // Don't allow expressions outside of a calc().
     1235                        array(
     1236                                'css'      => 'width: (3em + (10px * 2))',
     1237                                'expected' => '',
     1238                        ),
    11231239                );
    11241240        }
     
    13021418                        ),
    13031419
    1304                         // CSS calc().
    1305                         array(
    1306                                 'width: calc(2em + 3px)',
    1307                                 'width: calc(2em + 3px)',
    1308                         ),
    1309 
    1310                         // CSS variable.
    1311                         array(
    1312                                 'padding: var(--wp-var1) var(--wp-var2)',
    1313                                 'padding: var(--wp-var1) var(--wp-var2)',
    1314                         ),
    1315 
    1316                         // CSS calc() with var().
    1317                         array(
    1318                                 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
    1319                                 'margin-top: calc(var(--wp-var1) * 3 + 2em)',
    1320                         ),
    1321 
    13221420                        /*
    13231421                         * Invalid use cases.
     
    13811479                        array(
    13821480                                'background-image: url( "http://example.com );',
    1383                                 '',
    1384                         ),
    1385 
    1386                         // Malformed calc, no closing `)`.
    1387                         array(
    1388                                 'width: calc(3em + 10px',
    1389                                 '',
    1390                         ),
    1391 
    1392                         // Malformed var, no closing `)`.
    1393                         array(
    1394                                 'width: var(--wp-var1',
    13951481                                '',
    13961482                        ),
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r53129 r54100  
    16031603                                                'core/cover'  => array(
    16041604                                                        'filter' => array(
    1605                                                                 'duotone' => 'var(--wp--preset--duotone--blue-red, var(--fallback-unsafe))',
     1605                                                                'duotone' => 'var(--invalid',
    16061606                                                        ),
    16071607                                                ),
     
    16771677                                                'radius' => array(
    16781678                                                        'topLeft'     => '6px',
    1679                                                         'topRight'    => 'var(--top-right, var(--unsafe-fallback))',
     1679                                                        'topRight'    => 'var(--invalid',
    16801680                                                        'bottomRight' => '6px',
    16811681                                                        'bottomLeft'  => '6px',
     
    16861686                                                        'top'    => '1px',
    16871687                                                        'right'  => '1px',
    1688                                                         'bottom' => 'var(--bottom, var(--unsafe-fallback))',
     1688                                                        'bottom' => 'var(--invalid',
    16891689                                                        'left'   => '1px',
    16901690                                                ),
     
    16961696                                                                        'top'    => '2px',
    16971697                                                                        'right'  => '2px',
    1698                                                                         'bottom' => 'var(--bottom, var(--unsafe-fallback))',
     1698                                                                        'bottom' => 'var(--invalid',
    16991699                                                                        'left'   => '2px',
    17001700                                                                ),
     
    17071707                                                                'radius' => array(
    17081708                                                                        'topLeft'     => '5px',
    1709                                                                         'topRight'    => 'var(--top-right, var(--unsafe-fallback))',
     1709                                                                        'topRight'    => 'var(--invalid',
    17101710                                                                        'bottomRight' => '5px',
    17111711                                                                        'bottomLeft'  => '5px',
     
    17161716                                                                        'top'    => '3px',
    17171717                                                                        'right'  => '3px',
    1718                                                                         'bottom' => 'var(bottom, var(--unsafe-fallback))',
     1718                                                                        'bottom' => 'var(--invalid',
    17191719                                                                        'left'   => '3px',
    17201720                                                                ),
     
    17261726                                                                                        'top'    => '4px',
    17271727                                                                                        'right'  => '4px',
    1728                                                                                         'bottom' => 'var(--bottom, var(--unsafe-fallback))',
     1728                                                                                        'bottom' => 'var(--invalid',
    17291729                                                                                        'left'   => '4px',
    17301730                                                                                ),
     
    19451945                                                                        'name'  => 'Blue',
    19461946                                                                        'slug'  => 'blue',
    1947                                                                         'color' => 'var(--color, var(--unsafe-fallback))',
     1947                                                                        'color' => 'var(--invalid',
    19481948                                                                ),
    19491949                                                                array(
     
    19761976                                                                        'name'       => 'Helvetica Arial',
    19771977                                                                        'slug'       => 'helvetica-arial',
    1978                                                                         'fontFamily' => 'var(--fontFamily, var(--unsafe-fallback))',
     1978                                                                        'fontFamily' => 'var(--invalid',
    19791979                                                                ),
    19801980                                                        ),
     
    19991999                                                                                        'name'  => 'Blue',
    20002000                                                                                        'slug'  => 'blue',
    2001                                                                                         'color' => 'var(--color, var(--unsafe--fallback))',
     2001                                                                                        'color' => 'var(--invalid',
    20022002                                                                                ),
    20032003                                                                                array(
Note: See TracChangeset for help on using the changeset viewer.