KSES: Allow `url()` to be used in inline CSS.

The cover image block uses the `url()` function in its inline CSS, to show the cover image. KSES didn't allow this, causing the block to not save correctly for Author and Contributor users. As KSES does already check each attribute name against an allowed list, we're able to add an extra check for certain attributes to be able to use the `url()` function, too.

Merges [43781] from the 5.0 branch to core.

Props peterwilsoncc, azaozz, pento, dd32.
Fixes #45067.


Built from https://develop.svn.wordpress.org/trunk@44136


git-svn-id: http://core.svn.wordpress.org/trunk@43966 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Gary Pendergast 2018-12-14 01:41:36 +00:00
parent d45126977e
commit 1947e4424a
2 changed files with 63 additions and 10 deletions

View File

@ -1985,9 +1985,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
$css = wp_kses_no_null( $css );
$css = str_replace( array( "\n", "\r", "\t" ), '', $css );
if ( preg_match( '%[\\\\(&=}]|/\*%', $css ) ) { // remove any inline css containing \ ( & } = or comments
return '';
}
$allowed_protocols = wp_allowed_protocols();
$css_array = explode( ';', trim( $css ) );
@ -1998,6 +1996,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
* @since 4.4.0 Added support for `min-height`, `max-height`, `min-width`, and `max-width`.
* @since 4.6.0 Added support for `list-style-type`.
* @since 5.0.0 Added support for `text-transform`.
* @since 5.0.0 Added support for `background-image`.
*
* @param string[] $attr Array of allowed CSS attributes.
*/
@ -2006,6 +2005,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
array(
'background',
'background-color',
'background-image',
'border',
'border-width',
@ -2076,6 +2076,24 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
)
);
/*
* CSS attributes that accept URL data types.
*
* This is in accordance to the CSS spec and unrelated to
* the sub-set of supported attributes above.
*
* See: https://developer.mozilla.org/en-US/docs/Web/CSS/url
*/
$css_url_data_types = array(
'background',
'background-image',
'cursor',
'list-style',
'list-style-image',
);
if ( empty( $allowed_attr ) ) {
return $css;
}
@ -2085,20 +2103,55 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
if ( $css_item == '' ) {
continue;
}
$css_item = trim( $css_item );
$found = false;
$css_item = trim( $css_item );
$css_test_string = $css_item;
$found = false;
$url_attr = false;
if ( strpos( $css_item, ':' ) === false ) {
$found = true;
} else {
$parts = explode( ':', $css_item );
if ( in_array( trim( $parts[0] ), $allowed_attr ) ) {
$found = true;
$parts = explode( ':', $css_item, 2 );
$css_selector = trim( $parts[0] );
if ( in_array( $css_selector, $allowed_attr, true ) ) {
$found = true;
$url_attr = in_array( $css_selector, $css_url_data_types, true );
}
}
if ( $found ) {
if ( $found && $url_attr ) {
// Simplified: matches the sequence `url(*)`.
preg_match_all( '/url\([^)]+\)/', $parts[1], $url_matches );
foreach ( $url_matches[0] as $url_match ) {
// Clean up the URL from each of the matches above.
preg_match( '/^url\(\s*([\'\"]?)(.*)(\g1)\s*\)$/', $url_match, $url_pieces );
if ( empty( $url_pieces[2] ) ) {
$found = false;
break;
}
$url = trim( $url_pieces[2] );
if ( empty( $url ) || $url !== wp_kses_bad_protocol( $url, $allowed_protocols ) ) {
$found = false;
break;
} else {
// Remove the whole `url(*)` bit that was matched above from the CSS.
$css_test_string = str_replace( $url_match, '', $css_test_string );
}
}
}
// Remove any CSS containing containing \ ( & } = or comments, except for url() useage checked above.
if ( $found && ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
if ( $css != '' ) {
$css .= ';';
}
$css .= $css_item;
}
}

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.1-alpha-44135';
$wp_version = '5.1-alpha-44136';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.