WordPress.org

Make WordPress Core

Ticket #33121: 33121.6.diff

File 33121.6.diff, 5.6 KB (added by peterwilsoncc, 12 months ago)
  • src/wp-includes/kses.php

    diff --git src/wp-includes/kses.php src/wp-includes/kses.php
    index 0cf4ce14c4..64acf7ff7d 100644
    function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { 
    854854 * Determine whether an attribute is allowed.
    855855 *
    856856 * @since 4.2.3
     857 * @since 5.0.0 Add support for `data-*` wildcard attributes.
    857858 *
    858859 * @param string $name The attribute name. Returns empty string when not allowed.
    859860 * @param string $value The attribute value. Returns a filtered value.
    function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { 
    864865 * @return bool Is the attribute allowed?
    865866 */
    866867function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowed_html ) {
    867         $allowed_attr = $allowed_html[strtolower( $element )];
     868        $allowed_attr = $allowed_html[ strtolower( $element ) ];
    868869
    869870        $name_low = strtolower( $name );
     871
    870872        if ( ! isset( $allowed_attr[$name_low] ) || '' == $allowed_attr[$name_low] ) {
    871                 $name = $value = $whole = '';
    872                 return false;
     873                /*
     874                 * Allow `data-*` attributes.
     875                 *
     876                 * When specifying `$allowed_html`, the attribute name should be set as
     877                 * `data-*` (not to be mixed with the HTML 4.0 `data` attribute, see
     878                 * https://www.w3.org/TR/html40/struct/objects.html#adef-data).
     879                 *
     880                 * Note: the attribute name should only contain `A-Za-z0-9_-` chars,
     881                 * double hyphens `--` are not accepted by WordPress.
     882                 */
     883                if ( strpos( $name_low, 'data-' ) === 0 && ! empty( $allowed_attr['data-*'] ) && preg_match( '/^data(?:-[a-z0-9_]+)+$/', $name_low, $match ) ) {
     884                        /*
     885                         * Add the whole attribute name to the allowed attributes and set any restrictions
     886                         * for the `data-*` attribute values for the current element.
     887                         */
     888                        $allowed_attr[ $match[0] ] = $allowed_attr['data-*'];
     889                } else {
     890                        $name = $value = $whole = '';
     891                        return false;
     892                }
    873893        }
    874894
    875895        if ( 'style' == $name_low ) {
    function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowe 
    884904                $value = $new_value;
    885905        }
    886906
    887         if ( is_array( $allowed_attr[$name_low] ) ) {
     907        if ( is_array( $allowed_attr[ $name_low ] ) ) {
    888908                // there are some checks
    889909                foreach ( $allowed_attr[$name_low] as $currkey => $currval ) {
    890910                        if ( ! wp_kses_check_attr_val( $value, $vless, $currkey, $currval ) ) {
    function safecss_filter_attr( $css, $deprecated = '' ) { 
    18081828 * Helper function to add global attributes to a tag in the allowed html list.
    18091829 *
    18101830 * @since 3.5.0
     1831 * @since 5.0.0 Add support for `data-*` wildcard attributes.
    18111832 * @access private
    18121833 *
    18131834 * @param array $value An array of attributes.
    function _wp_add_global_attributes( $value ) { 
    18201841                'style' => true,
    18211842                'title' => true,
    18221843                'role' => true,
     1844                'data-*' => true,
    18231845        );
    18241846
    18251847        if ( true === $value )
  • tests/phpunit/tests/kses.php

    diff --git tests/phpunit/tests/kses.php tests/phpunit/tests/kses.php
    index dea4a881a2..2d9c28411f 100644
    EOF; 
    718718
    719719                $this->assertEquals( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => false ), array() ) );
    720720        }
     721
     722        /**
     723         * Data attributes are globally accepted.
     724         *
     725         * @ticket 33121
     726         */
     727        function test_wp_kses_attr_data_attribute_is_allowed() {
     728                $test = '<div data-foo="foo" data-bar="bar" datainvalid="gone" data--invaild="gone"  data-also-invaild-="gone" data-two-hyphens="remains">Pens and pencils</div>';
     729                $expected = '<div data-foo="foo" data-bar="bar" data-two-hyphens="remains">Pens and pencils</div>';
     730
     731                $this->assertEquals( $expected, wp_kses_post( $test ) );
     732        }
     733
     734        /**
     735         * Ensure wildcard attributes block unprefixed wildcard uses.
     736         *
     737         * @ticket 33121
     738         */
     739        function test_wildcard_requires_hyphen_after_prefix() {
     740                $allowed_html = array(
     741                        'div' => array(
     742                                'data-*' => true,
     743                                'on-*' => true,
     744                        ),
     745                );
     746
     747                $string = '<div datamelformed-prefix="gone" data="gone" data-="gone" onclick="alert(1)">Malformed attributes</div>';
     748                $expected = '<div>Malformed attributes</div>';
     749
     750                $actual = wp_kses( $string, $allowed_html );
     751
     752                $this->assertSame( $expected, $actual );
     753        }
     754
     755        /**
     756         * Ensure wildcard allows two hyphen.
     757         *
     758         * @ticket 33121
     759         */
     760        function test_wildcard_allows_two_hyphens() {
     761                $allowed_html = array(
     762                        'div' => array(
     763                                'data-*' => true,
     764                        ),
     765                );
     766
     767                $string = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
     768                $expected = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
     769
     770                $actual = wp_kses( $string, $allowed_html );
     771
     772                $this->assertSame( $expected, $actual );
     773        }
     774
     775        /**
     776         * Ensure wildcard attributes only support valid prefixes.
     777         *
     778         * @dataProvider data_wildcard_attribute_prefixes
     779         *
     780         * @ticket 33121
     781         */
     782        function test_wildcard_attribute_prefixes( $wildcard_attribute, $expected ) {
     783                $allowed_html = array(
     784                        'div' => array(
     785                                $wildcard_attribute => true,
     786                        ),
     787                );
     788
     789                $name = str_replace( '*', strtolower( __FUNCTION__ ), $wildcard_attribute );
     790                $value = __FUNCTION__;
     791                $whole = "{$name}=\"{$value}\"";
     792
     793                $actual = wp_kses_attr_check( $name, $value, $whole, 'n', 'div', $allowed_html );
     794
     795                $this->assertSame( $expected, $actual );
     796        }
     797
     798        /**
     799         * @return array Array of arguments for wildcard testing
     800         *               [0] The prefix being tested.
     801         *               [1] The outcome of `wp_kses_attr_check` for the prefix.
     802         */
     803        function data_wildcard_attribute_prefixes() {
     804                return array(
     805                        // Ends correctly
     806                        array( 'data-*', true ),
     807
     808                        // Does not end with trialing `-`.
     809                        array( 'data*', false ),
     810
     811                        // Multiple wildcards.
     812                        array( 'd*ta-*', false ),
     813                        array( 'data**', false ),
     814                );
     815        }
    721816}