From e3971abb5d69bf055f9aea8c54dd532f494681c1 Mon Sep 17 00:00:00 2001 From: hbhalodia Date: Mon, 14 Sep 2026 14:29:45 +0530 Subject: [PATCH] Add the new attributes in SVG to pass through wp_kses --- src/wp-includes/class-wp-icons-registry.php | 64 +++++++++++++------ tests/phpunit/tests/icons/wpIconsRegistry.php | 64 +++++++++++++++++++ 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/src/wp-includes/class-wp-icons-registry.php b/src/wp-includes/class-wp-icons-registry.php index a10960da9a077..6d7ac0e0de689 100644 --- a/src/wp-includes/class-wp-icons-registry.php +++ b/src/wp-includes/class-wp-icons-registry.php @@ -237,29 +237,53 @@ public function unregister( $icon_name ) { * @return string The sanitized icon SVG content. */ protected function sanitize_icon_content( $icon_content ) { + $stroke_attributes = array( + 'style' => true, + 'stroke' => true, + 'stroke-width' => true, + 'stroke-linecap' => true, + 'stroke-linejoin' => true, + 'stroke-miterlimit' => true, + 'vector-effect' => true, + ); + $allowed_tags = array( - 'svg' => array( - 'class' => true, - 'xmlns' => true, - 'width' => true, - 'height' => true, - 'viewbox' => true, - 'aria-hidden' => true, - 'role' => true, - 'focusable' => true, + 'svg' => array_merge( + array( + 'class' => true, + 'xmlns' => true, + 'width' => true, + 'height' => true, + 'viewbox' => true, + 'aria-hidden' => true, + 'role' => true, + 'focusable' => true, + 'fill' => true, + 'fill-rule' => true, + 'clip-rule' => true, + ), + $stroke_attributes ), - 'path' => array( - 'fill' => true, - 'fill-rule' => true, - 'd' => true, - 'transform' => true, + 'path' => array_merge( + array( + 'fill' => true, + 'fill-rule' => true, + 'clip-rule' => true, + 'd' => true, + 'transform' => true, + ), + $stroke_attributes ), - 'polygon' => array( - 'fill' => true, - 'fill-rule' => true, - 'points' => true, - 'transform' => true, - 'focusable' => true, + 'polygon' => array_merge( + array( + 'fill' => true, + 'fill-rule' => true, + 'clip-rule' => true, + 'points' => true, + 'transform' => true, + 'focusable' => true, + ), + $stroke_attributes ), ); return wp_kses( $icon_content, $allowed_tags ); diff --git a/tests/phpunit/tests/icons/wpIconsRegistry.php b/tests/phpunit/tests/icons/wpIconsRegistry.php index 42853d2666a95..c6268666a2b7f 100644 --- a/tests/phpunit/tests/icons/wpIconsRegistry.php +++ b/tests/phpunit/tests/icons/wpIconsRegistry.php @@ -284,6 +284,70 @@ public function test_register_icon_sanitizes_content() { $this->assertSame( '', $icon['content'] ); } + /** + * Data provider. + * + * @return array[] + */ + public function data_icon_content_sources() { + return array( + 'inline content' => array( false ), + 'file path' => array( true ), + ); + } + + /** + * Should preserve the attributes that stroke-based icons rely on. + * + * Only covers the attributes allowed for stroke-based icons. Those that were + * already allowed are covered by test_register_icon_sanitizes_content(). + * + * @ticket 66101 + * + * @dataProvider data_icon_content_sources + * + * @covers ::register + * + * @param bool $use_file_path Whether to register the icon from a file path. + */ + public function test_register_icon_preserves_stroke_attributes( $use_file_path ) { + $stroke = 'style="fill: none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" vector-effect="non-scaling-stroke"'; + $content = '' . + '' . + '' . + ''; + $name = 'test-collection/stroke-icon'; + $settings = array( 'label' => 'Stroke Icon' ); + + if ( $use_file_path ) { + $settings['file_path'] = $this->create_temp_icon_file( $content ); + } else { + $settings['content'] = $content; + } + + $this->assertTrue( $this->registry->register( $name, $settings ) ); + + $icon = $this->registry->get_registered_icon( $name ); + + $this->assertStringContainsString( + '', + $icon['content'], + 'Attributes were altered or stripped from the svg element.' + ); + + $this->assertStringContainsString( + '', + $icon['content'], + 'Attributes were altered or stripped from the path element.' + ); + + $this->assertStringContainsString( + '', + $icon['content'], + 'Attributes were altered or stripped from the polygon element.' + ); + } + /** * Should fail to register an icon that provides both `content` and `file_path`. *