Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 44 additions & 20 deletions src/wp-includes/class-wp-icons-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
64 changes: 64 additions & 0 deletions tests/phpunit/tests/icons/wpIconsRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,70 @@ public function test_register_icon_sanitizes_content() {
$this->assertSame( '<svg viewbox="0 0 24 24"><path d="M0 0" /></svg>', $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 = '<svg fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" ' . $stroke . '>' .
'<path clip-rule="evenodd" ' . $stroke . ' />' .
'<polygon clip-rule="evenodd" ' . $stroke . ' />' .
'</svg>';
$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(
'<svg fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" ' . $stroke . '>',
$icon['content'],
'Attributes were altered or stripped from the svg element.'
);

$this->assertStringContainsString(
'<path clip-rule="evenodd" ' . $stroke . ' />',
$icon['content'],
'Attributes were altered or stripped from the path element.'
);

$this->assertStringContainsString(
'<polygon clip-rule="evenodd" ' . $stroke . ' />',
$icon['content'],
'Attributes were altered or stripped from the polygon element.'
);
}

/**
* Should fail to register an icon that provides both `content` and `file_path`.
*
Expand Down
Loading