@@ -1441,25 +1441,114 @@ public function data_safecss_filter_attr() {
14411441 /**
14421442 * Data attributes are globally accepted.
14431443 *
1444- * @ticket 33121
1444+ * @ticket 61501
1445+ *
1446+ * @dataProvider data_data_attributes_and_whether_they_are_allowed
1447+ *
1448+ * @param string $attribute_name Custom data attribute, e.g. "data-wp-bind--enabled".
1449+ * @param bool $is_allowed Whether the given attribute should be allowed.
14451450 */
1446- public function test_wp_kses_attr_data_attribute_is_allowed () {
1447- $ test = '<div data-foo="foo" data-bar="bar" datainvalid="gone" data-two-hyphens="remains">Pens and pencils</div> ' ;
1448- $ expected = '<div data-foo="foo" data-bar="bar" data-two-hyphens="remains">Pens and pencils</div> ' ;
1451+ public function test_wp_kses_attr_boolean_data_attribute_is_allowed ( string $ attribute_name , bool $ is_allowed ) {
1452+ $ element = "<div {$ attribute_name }>Pens and pencils.</div> " ;
14491453
1450- $ this ->assertEqualHTML ( $ expected , wp_kses_post ( $ test ) );
1454+ $ processor = new WP_HTML_Tag_Processor ( $ element );
1455+ $ processor ->next_tag ();
1456+
1457+ $ this ->assertTrue (
1458+ $ processor ->get_attribute ( $ attribute_name ),
1459+ "Failed to find expected attribute ' {$ attribute_name }' before filtering: check test. "
1460+ );
1461+
1462+ $ processor = new WP_HTML_Tag_Processor ( wp_kses_post ( $ element ) );
1463+ $ this ->assertTrue (
1464+ $ processor ->next_tag (),
1465+ 'Failed to find containing tag after filtering: check test. '
1466+ );
1467+
1468+ if ( $ is_allowed ) {
1469+ $ this ->assertTrue (
1470+ $ processor ->get_attribute ( $ attribute_name ),
1471+ "Allowed custom data attribute ' {$ attribute_name }' should not have been removed. "
1472+ );
1473+ } else {
1474+ $ this ->assertNull (
1475+ $ processor ->get_attribute ( $ attribute_name ),
1476+ "Should have removed un-allowed custom data attribute ' {$ attribute_name }'. "
1477+ );
1478+ }
14511479 }
14521480
14531481 /**
1454- * Data attributes with leading, trailing, and double "-" are globally accepted.
1482+ * Ensures that only allowable custom data attributes with values are retained.
1483+ *
1484+ * @ticket 33121
1485+ *
1486+ * @dataProvider data_data_attributes_and_whether_they_are_allowed
14551487 *
1456- * @ticket 61052
1488+ * @param string $attribute_name Custom data attribute, e.g. "dat-wp-bind--enabled".
1489+ * @param bool $is_allowed Whether the given attribute should be allowed.
14571490 */
1458- public function test_wp_kses_attr_data_attribute_hypens_allowed () {
1459- $ test = '<div data--leading="remains" data-trailing-="remains" data-middle--double="remains">Pens and pencils</div> ' ;
1460- $ expected = '<div data--leading="remains" data-trailing-="remains" data-middle--double="remains">Pens and pencils</div> ' ;
1491+ public function test_wp_kses_attr_data_attribute_is_allowed ( string $ attribute_name , bool $ is_allowed ) {
1492+ $ element = "<div {$ attribute_name }='shadows and dust'>Pens and pencils.</div> " ;
14611493
1462- $ this ->assertEqualHTML ( $ expected , wp_kses_post ( $ test ) );
1494+ $ processor = new WP_HTML_Tag_Processor ( $ element );
1495+ $ processor ->next_tag ();
1496+
1497+ $ this ->assertIsString (
1498+ $ processor ->get_attribute ( $ attribute_name ),
1499+ "Failed to find expected attribute ' {$ attribute_name }' before filtering: check test. "
1500+ );
1501+
1502+ $ processor = new WP_HTML_Tag_Processor ( wp_kses_post ( $ element ) );
1503+ $ this ->assertTrue (
1504+ $ processor ->next_tag (),
1505+ 'Failed to find containing tag after filtering: check test. '
1506+ );
1507+
1508+ if ( $ is_allowed ) {
1509+ $ this ->assertIsString (
1510+ $ processor ->get_attribute ( $ attribute_name ),
1511+ "Allowed custom data attribute ' {$ attribute_name }' should not have been removed. "
1512+ );
1513+ } else {
1514+ $ this ->assertNull (
1515+ $ processor ->get_attribute ( $ attribute_name ),
1516+ "Should have removed un-allowed custom data attribute ' {$ attribute_name }'. "
1517+ );
1518+ }
1519+ }
1520+
1521+ /**
1522+ * Data provider.
1523+ *
1524+ * @return array[].
1525+ */
1526+ public static function data_data_attributes_and_whether_they_are_allowed () {
1527+ return array (
1528+ // Allowable custom data attributes.
1529+ 'Normative attribute ' => array ( 'data-foo ' , true ),
1530+ 'Non-consecutive dashes ' => array ( 'data-two-hyphens ' , true ),
1531+ 'Double-dashes ' => array ( 'data--double-dash ' , true ),
1532+ 'Trailing dash ' => array ( 'data-trailing-dash- ' , true ),
1533+ 'Uppercase alphas ' => array ( 'data-Post-ID ' , true ),
1534+ 'Bind Directive ' => array ( 'data-wp-bind--enabled ' , true ),
1535+ 'Single-dash suffix ' => array ( 'data-after- ' , true ),
1536+ 'Double-dash prefix ' => array ( 'data--before ' , true ),
1537+ 'Double-dash suffix ' => array ( 'data-after-- ' , true ),
1538+ 'Double-dashes everywhere ' => array ( 'data--one--two-- ' , true ),
1539+ 'Underscore ' => array ( 'data-over_under ' , true ),
1540+
1541+ // Not custom data attributes.
1542+ 'No data- prefix ' => array ( 'post-id ' , false ),
1543+ 'No dash after prefix ' => array ( 'datainvalid ' , false ),
1544+
1545+ // Un-allowable custom data attributes.
1546+ 'Nothing after prefix ' => array ( 'data- ' , false ),
1547+ 'Whitespace after prefix ' => array ( "data- \u{2003}" , false ),
1548+ 'Emoji in name ' => array ( 'data-🐄 ' , false ),
1549+ 'Brackets ' => array ( 'data-[enabled] ' , false ),
1550+ 'Colon ' => array ( 'data-wp:bind ' , false ),
1551+ );
14631552 }
14641553
14651554 /**
0 commit comments