safecss_filter_attr( string $css, string $deprecated = '' )

Filters an inline style attribute and removes disallowed rules.


Description Description


Parameters Parameters

$css

(string) (Required) A string of CSS rules.

$deprecated

(string) (Optional) Not used.

Default value: ''


Top ↑

Return Return

(string) Filtered string of CSS rules.


Top ↑

Source Source

File: wp-includes/kses.php

function safecss_filter_attr( $css, $deprecated = '' ) {
	if ( ! empty( $deprecated ) ) {
		_deprecated_argument( __FUNCTION__, '2.8.1' ); // Never implemented
	}

	$css = wp_kses_no_null( $css );
	$css = str_replace( array( "\n", "\r", "\t" ), '', $css );

	$allowed_protocols = wp_allowed_protocols();

	$css_array = explode( ';', trim( $css ) );

	/**
	 * Filters list of allowed CSS attributes.
	 *
	 * @since 2.8.1
	 * @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 `background-image`.
	 * @since 5.1.0 Added support for `text-transform`.
	 * @since 5.2.0 Added support for `background-position` and `grid-template-columns`
	 * @since 5.3.0 Added support for `grid`, `flex` and `column` layout properties.
	 *              Extend `background-*` support of individual properties.
	 *
	 * @param string[] $attr Array of allowed CSS attributes.
	 */
	$allowed_attr = apply_filters(
		'safe_style_css',
		array(
			'background',
			'background-color',
			'background-image',
			'background-position',
			'background-size',
			'background-attachment',
			'background-blend-mode',

			'border',
			'border-radius',
			'border-width',
			'border-color',
			'border-style',
			'border-right',
			'border-right-color',
			'border-right-style',
			'border-right-width',
			'border-bottom',
			'border-bottom-color',
			'border-bottom-style',
			'border-bottom-width',
			'border-left',
			'border-left-color',
			'border-left-style',
			'border-left-width',
			'border-top',
			'border-top-color',
			'border-top-style',
			'border-top-width',

			'border-spacing',
			'border-collapse',
			'caption-side',

			'columns',
			'column-count',
			'column-fill',
			'column-gap',
			'column-rule',
			'column-span',
			'column-width',

			'color',
			'font',
			'font-family',
			'font-size',
			'font-style',
			'font-variant',
			'font-weight',
			'letter-spacing',
			'line-height',
			'text-align',
			'text-decoration',
			'text-indent',
			'text-transform',

			'height',
			'min-height',
			'max-height',

			'width',
			'min-width',
			'max-width',

			'margin',
			'margin-right',
			'margin-bottom',
			'margin-left',
			'margin-top',

			'padding',
			'padding-right',
			'padding-bottom',
			'padding-left',
			'padding-top',

			'flex',
			'flex-basis',
			'flex-direction',
			'flex-flow',
			'flex-grow',
			'flex-shrink',

			'grid-template-columns',
			'grid-auto-columns',
			'grid-column-start',
			'grid-column-end',
			'grid-column-gap',
			'grid-template-rows',
			'grid-auto-rows',
			'grid-row-start',
			'grid-row-end',
			'grid-row-gap',
			'grid-gap',

			'justify-content',
			'justify-items',
			'justify-self',
			'align-content',
			'align-items',
			'align-self',

			'clear',
			'cursor',
			'direction',
			'float',
			'overflow',
			'vertical-align',
			'list-style-type',
		)
	);

	/*
	 * 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;
	}

	$css = '';
	foreach ( $css_array as $css_item ) {
		if ( $css_item == '' ) {
			continue;
		}

		$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, 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 && $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;
		}
	}

	return $css;
}

Top ↑

Changelog Changelog

Changelog
Version Description
2.8.1 Introduced.


Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.