Ticket #33121: 33121.4.diff
File 33121.4.diff, 6.3 KB (added by , 6 years ago) |
---|
-
src/wp-includes/kses.php
diff --git src/wp-includes/kses.php src/wp-includes/kses.php index 0cf4ce14c4..efec78d81a 100644
function wp_kses_one_attr( $string, $element ) { 549 549 $allowed_html = wp_kses_allowed_html( 'post' ); 550 550 $allowed_protocols = wp_allowed_protocols(); 551 551 $string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) ); 552 552 553 553 // Preserve leading and trailing whitespace. 554 554 $matches = array(); 555 555 preg_match('/^\s*/', $string, $matches); … … function wp_kses_one_attr( $string, $element ) { 561 561 } else { 562 562 $string = substr( $string, strlen( $lead ), -strlen( $trail ) ); 563 563 } 564 564 565 565 // Parse attribute name and value from input. 566 566 $split = preg_split( '/\s*=\s*/', $string, 2 ); 567 567 $name = $split[0]; … … function wp_kses_one_attr( $string, $element ) { 598 598 $value = ''; 599 599 $vless = 'y'; 600 600 } 601 601 602 602 // Sanitize attribute by name. 603 603 wp_kses_attr_check( $name, $value, $string, $vless, $element, $allowed_html ); 604 604 … … function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { 854 854 * Determine whether an attribute is allowed. 855 855 * 856 856 * @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. 857 859 * 858 860 * @param string $name The attribute name. Returns empty string when not allowed. 859 861 * @param string $value The attribute value. Returns a filtered value. … … function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowe 867 869 $allowed_attr = $allowed_html[strtolower( $element )]; 868 870 869 871 $name_low = strtolower( $name ); 872 870 873 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 } 873 902 } 874 903 875 904 if ( 'style' == $name_low ) { … … function wp_kses_attr_parse( $element ) { 1062 1091 } else { 1063 1092 $xhtml_slash = ''; 1064 1093 } 1065 1094 1066 1095 // Split it 1067 1096 $attrarr = wp_kses_hair_parse( $attr ); 1068 1097 if ( false === $attrarr ) { … … function wp_kses_attr_parse( $element ) { 1072 1101 // Make sure all input is returned by adding front and back matter. 1073 1102 array_unshift( $attrarr, $begin . $slash . $elname ); 1074 1103 array_push( $attrarr, $xhtml_slash . $end ); 1075 1104 1076 1105 return $attrarr; 1077 1106 } 1078 1107 … … function safecss_filter_attr( $css, $deprecated = '' ) { 1808 1837 * Helper function to add global attributes to a tag in the allowed html list. 1809 1838 * 1810 1839 * @since 3.5.0 1840 * @since 5.0.0 `data-*` wildcard added to globally accepted attributes. 1811 1841 * @access private 1812 1842 * 1813 1843 * @param array $value An array of attributes. … … function _wp_add_global_attributes( $value ) { 1820 1850 'style' => true, 1821 1851 'title' => true, 1822 1852 'role' => true, 1853 'data-*' => true, 1823 1854 ); 1824 1855 1825 1856 if ( true === $value ) -
tests/phpunit/tests/kses.php
diff --git tests/phpunit/tests/kses.php tests/phpunit/tests/kses.php index dea4a881a2..c9b17dea63 100644
EOF; 718 718 719 719 $this->assertEquals( "<{$element}>", wp_kses_attr( $element, $attribute, array( 'foo' => false ), array() ) ); 720 720 } 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( '33121-*', true ), 807 808 // Does not end with trialing `-`. 809 array( '33121*', false ), 810 811 // Multiple wildcards. 812 array( '3*121-*', false ), 813 array( '33121**', false ), 814 ); 815 } 721 816 }