WordPress.org

Make WordPress Core

Ticket #33121: 33121.3.diff

File 33121.3.diff, 5.3 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..27805ac14d 100644
    function wp_kses_one_attr( $string, $element ) { 
    549549        $allowed_html = wp_kses_allowed_html( 'post' );
    550550        $allowed_protocols = wp_allowed_protocols();
    551551        $string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) );
    552        
     552
    553553        // Preserve leading and trailing whitespace.
    554554        $matches = array();
    555555        preg_match('/^\s*/', $string, $matches);
    function wp_kses_one_attr( $string, $element ) { 
    561561        } else {
    562562                $string = substr( $string, strlen( $lead ), -strlen( $trail ) );
    563563        }
    564        
     564
    565565        // Parse attribute name and value from input.
    566566        $split = preg_split( '/\s*=\s*/', $string, 2 );
    567567        $name = $split[0];
    function wp_kses_one_attr( $string, $element ) { 
    598598                $value = '';
    599599                $vless = 'y';
    600600        }
    601        
     601
    602602        // Sanitize attribute by name.
    603603        wp_kses_attr_check( $name, $value, $string, $vless, $element, $allowed_html );
    604604
    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 Accepts wildcard attributes in allowed attributes in the form `prefix-*`.
     858 *              Wilcards are accepted as a suffix only and the prefix must end with a hyphen.
    857859 *
    858860 * @param string $name The attribute name. Returns empty string when not allowed.
    859861 * @param string $value The attribute value. Returns a filtered value.
    function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowe 
    867869        $allowed_attr = $allowed_html[strtolower( $element )];
    868870
    869871        $name_low = strtolower( $name );
     872
    870873        if ( ! isset( $allowed_attr[$name_low] ) || '' == $allowed_attr[$name_low] ) {
    871                 $name = $value = $whole = '';
    872                 return false;
     874                $allowed_wildcard = false;
     875
     876                // Check if attribute matches allowed wildcard.
     877                foreach ( array_keys( $allowed_attr ) as $attr ) {
     878                        if ( '-*' !== substr( $attr, -2 ) ) {
     879                                continue;
     880                        }
     881
     882                        // Store prefix without trailing `-*`.
     883                        $prefix = strtolower( substr( $attr, 0, -2 ) );
     884
     885                        if ( 1 !== preg_match( '/^' . preg_quote( $prefix ) . '(-[a-z0-9_]+)*$/', $name_low ) ) {
     886                                // Disallowed attribute format.
     887                                continue;
     888                        }
     889
     890                        // Attribute name is valid.
     891                        $allowed_attr[$name_low] = true;
     892                        $allowed_wildcard = true;
     893
     894                        // Stop checking.
     895                        break;
     896                }
     897
     898                if ( false === $allowed_wildcard ) {
     899                        $name = $value = $whole = '';
     900                        return false;
     901                }
    873902        }
    874903
    875904        if ( 'style' == $name_low ) {
    function wp_kses_attr_parse( $element ) { 
    10621091        } else {
    10631092                $xhtml_slash = '';
    10641093        }
    1065        
     1094
    10661095        // Split it
    10671096        $attrarr = wp_kses_hair_parse( $attr );
    10681097        if ( false === $attrarr ) {
    function wp_kses_attr_parse( $element ) { 
    10721101        // Make sure all input is returned by adding front and back matter.
    10731102        array_unshift( $attrarr, $begin . $slash . $elname );
    10741103        array_push( $attrarr, $xhtml_slash . $end );
    1075        
     1104
    10761105        return $attrarr;
    10771106}
    10781107
    function safecss_filter_attr( $css, $deprecated = '' ) { 
    18081837 * Helper function to add global attributes to a tag in the allowed html list.
    18091838 *
    18101839 * @since 3.5.0
     1840 * @since 5.0.0 `data-*` wildcard added to globally accepted attributes.
    18111841 * @access private
    18121842 *
    18131843 * @param array $value An array of attributes.
    function _wp_add_global_attributes( $value ) { 
    18201850                'style' => true,
    18211851                'title' => true,
    18221852                'role' => true,
     1853                'data-*' => true,
    18231854        );
    18241855
    18251856        if ( true === $value )
  • tests/phpunit/tests/kses.php

    diff --git tests/phpunit/tests/kses.php tests/phpunit/tests/kses.php
    index dea4a881a2..0c6b91a6e0 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 only support valid prefixes.
     736         *
     737         * @dataProvider data_wildcard_attribute_prefixes
     738         *
     739         * @ticket 33121
     740         */
     741        function test_wildcard_attribute_prefixes( $wildcard_attribute, $expected ) {
     742                $allowed_html = array(
     743                        'div' => array(
     744                                $wildcard_attribute => true,
     745                        ),
     746                );
     747
     748                $name = str_replace( '*', strtolower( __FUNCTION__ ), $wildcard_attribute );
     749                $value = __FUNCTION__;
     750                $whole = "{$name}=\"{$value}\"";
     751
     752                $actual = wp_kses_attr_check( $name, $value, $whole, 'n', 'div', $allowed_html );
     753
     754                $this->assertSame( $expected, $actual );
     755        }
     756
     757        /**
     758         * @return array Array of arguments for wildcard testing
     759         *               [0] The prefix being tested.
     760         *               [1] The outcome of `wp_kses_attr_check` for the prefix.
     761         */
     762        function data_wildcard_attribute_prefixes() {
     763                return array(
     764                        // Ends correctly
     765                        array( '33121-*', true ),
     766
     767                        // Does not end with trialing `-`.
     768                        array( '33121*', false ),
     769
     770                        // Multiple wildcards.
     771                        array( '3*121-*', false ),
     772                        array( '33121**', false ),
     773                );
     774        }
    721775}