Make WordPress Core

Changeset 43981


Ignore:
Timestamp:
12/12/2018 02:38:14 AM (8 years ago)
Author:
jeremyfelt
Message:

KSES: Allow HTML data-* attributes.

Add global support for HTML attributes prefixed data- for authors and contributors, as required by the new editor.

Merges [43727] to trunk.

Props azaozz, peterwilsoncc.
Fixes #33121.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/wp-includes/kses.php

    r43571 r43981  
    10771077 *
    10781078 * @since 4.2.3
     1079 * @since 5.0.0 Add support for `data-*` wildcard attributes.
    10791080 *
    10801081 * @param string $name         The attribute name. Passed by reference. Returns empty string when not allowed.
     
    10911092        $name_low = strtolower( $name );
    10921093        if ( ! isset( $allowed_attr[ $name_low ] ) || '' == $allowed_attr[ $name_low ] ) {
    1093                 $name = $value = $whole = '';
    1094                 return false;
     1094                /*
     1095                 * Allow `data-*` attributes.
     1096                 *
     1097                 * When specifying `$allowed_html`, the attribute name should be set as
     1098                 * `data-*` (not to be mixed with the HTML 4.0 `data` attribute, see
     1099                 * https://www.w3.org/TR/html40/struct/objects.html#adef-data).
     1100                 *
     1101                 * Note: the attribute name should only contain `A-Za-z0-9_-` chars,
     1102                 * double hyphens `--` are not accepted by WordPress.
     1103                 */
     1104                if ( strpos( $name_low, 'data-' ) === 0 && ! empty( $allowed_attr['data-*'] ) && preg_match( '/^data(?:-[a-z0-9_]+)+$/', $name_low, $match ) ) {
     1105                        /*
     1106                         * Add the whole attribute name to the allowed attributes and set any restrictions
     1107                         * for the `data-*` attribute values for the current element.
     1108                         */
     1109                        $allowed_attr[ $match[0] ] = $allowed_attr['data-*'];
     1110                } else {
     1111                        $name = $value = $whole = '';
     1112                        return false;
     1113                }
    10951114        }
    10961115
     
    20922111 *
    20932112 * @since 3.5.0
     2113 * @since 5.0.0 Add support for `data-*` wildcard attributes.
    20942114 * @access private
    20952115 * @ignore
     
    21002120function _wp_add_global_attributes( $value ) {
    21012121        $global_attributes = array(
    2102                 'class' => true,
    2103                 'id'    => true,
    2104                 'style' => true,
    2105                 'title' => true,
    2106                 'role'  => true,
     2122                'class'  => true,
     2123                'id'     => true,
     2124                'style'  => true,
     2125                'title'  => true,
     2126                'role'   => true,
     2127                'data-*' => true,
    21072128        );
    21082129
  • trunk/tests/phpunit/tests/kses.php

    r42880 r43981  
    826826                );
    827827        }
     828
     829        /**
     830         * Data attributes are globally accepted.
     831         *
     832         * @ticket 33121
     833         */
     834        function test_wp_kses_attr_data_attribute_is_allowed() {
     835                $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>';
     836                $expected = '<div data-foo="foo" data-bar="bar" data-two-hyphens="remains">Pens and pencils</div>';
     837
     838                $this->assertEquals( $expected, wp_kses_post( $test ) );
     839        }
     840
     841        /**
     842         * Ensure wildcard attributes block unprefixed wildcard uses.
     843         *
     844         * @ticket 33121
     845         */
     846        function test_wildcard_requires_hyphen_after_prefix() {
     847                $allowed_html = array(
     848                        'div' => array(
     849                                'data-*' => true,
     850                                'on-*'   => true,
     851                        ),
     852                );
     853
     854                $string   = '<div datamelformed-prefix="gone" data="gone" data-="gone" onclick="alert(1)">Malformed attributes</div>';
     855                $expected = '<div>Malformed attributes</div>';
     856
     857                $actual = wp_kses( $string, $allowed_html );
     858
     859                $this->assertSame( $expected, $actual );
     860        }
     861
     862        /**
     863         * Ensure wildcard allows two hyphen.
     864         *
     865         * @ticket 33121
     866         */
     867        function test_wildcard_allows_two_hyphens() {
     868                $allowed_html = array(
     869                        'div' => array(
     870                                'data-*' => true,
     871                        ),
     872                );
     873
     874                $string   = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
     875                $expected = '<div data-wp-id="pens-and-pencils">Well formed attribute</div>';
     876
     877                $actual = wp_kses( $string, $allowed_html );
     878
     879                $this->assertSame( $expected, $actual );
     880        }
     881
     882        /**
     883         * Ensure wildcard attributes only support valid prefixes.
     884         *
     885         * @dataProvider data_wildcard_attribute_prefixes
     886         *
     887         * @ticket 33121
     888         */
     889        function test_wildcard_attribute_prefixes( $wildcard_attribute, $expected ) {
     890                $allowed_html = array(
     891                        'div' => array(
     892                                $wildcard_attribute => true,
     893                        ),
     894                );
     895
     896                $name  = str_replace( '*', strtolower( __FUNCTION__ ), $wildcard_attribute );
     897                $value = __FUNCTION__;
     898                $whole = "{$name}=\"{$value}\"";
     899
     900                $actual = wp_kses_attr_check( $name, $value, $whole, 'n', 'div', $allowed_html );
     901
     902                $this->assertSame( $expected, $actual );
     903        }
     904
     905        /**
     906         * @return array Array of arguments for wildcard testing
     907         *               [0] The prefix being tested.
     908         *               [1] The outcome of `wp_kses_attr_check` for the prefix.
     909         */
     910        function data_wildcard_attribute_prefixes() {
     911                return array(
     912                        // Ends correctly
     913                        array( 'data-*', true ),
     914
     915                        // Does not end with trialing `-`.
     916                        array( 'data*', false ),
     917
     918                        // Multiple wildcards.
     919                        array( 'd*ta-*', false ),
     920                        array( 'data**', false ),
     921                );
     922        }
    828923}
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r43980 r43981  
    10801080                                // Raw values.
    10811081                                array(
    1082                                         'title'       => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
    1083                                         'description' => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
    1084                                         'caption'     => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
     1082                                        'title'       => '<a href="#" target="_blank" unfiltered=true>link</a>',
     1083                                        'description' => '<a href="#" target="_blank" unfiltered=true>link</a>',
     1084                                        'caption'     => '<a href="#" target="_blank" unfiltered=true>link</a>',
    10851085                                ),
    10861086                                // Expected returned values.
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r43980 r43981  
    32843284                                // Raw values.
    32853285                                array(
    3286                                         'title'   => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
    3287                                         'content' => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
    3288                                         'excerpt' => '<a href="#" target="_blank" data-unfiltered=true>link</a>',
     3286                                        'title'   => '<a href="#" target="_blank" unfiltered=true>link</a>',
     3287                                        'content' => '<a href="#" target="_blank" unfiltered=true>link</a>',
     3288                                        'excerpt' => '<a href="#" target="_blank" unfiltered=true>link</a>',
    32893289                                ),
    32903290                                // Expected returned values.
Note: See TracChangeset for help on using the changeset viewer.