Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
26a51db
Icons Regstry: improveme SVG sanitizer
t-hamano Mar 12, 2026
4ae7479
WIP
t-hamano Mar 12, 2026
a777fff
Improve unit test
t-hamano Mar 12, 2026
2bd0b84
Format
t-hamano Mar 12, 2026
3dc5e28
Add missing elements
t-hamano Mar 12, 2026
8708824
Remove redundant def element
t-hamano Mar 12, 2026
5c36d1f
Add temporary backport changelog
t-hamano Mar 12, 2026
e8f8a31
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 15, 2026
d4f4022
Consolidate icon registry sanitize tests into a single test file
t-hamano Jun 15, 2026
06dbc86
Reject malformed SVG when the processor errors or pauses incomplete
t-hamano Jun 15, 2026
ae4140d
Branch xmlns:xlink test expectation by WordPress version
t-hamano Jun 15, 2026
49f6a74
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 15, 2026
c360d0c
Allow all ARIA states/properties and data-* attributes in icon SVGs
t-hamano Jun 15, 2026
d5c5967
Add type hints to sanitize_icon_content()
t-hamano Jun 17, 2026
5a99e53
Use array_fill_keys() for SVG attribute allow-lists
t-hamano Jun 17, 2026
97d3002
Use @link tag for dmsnell PR reference in docblock
t-hamano Jun 17, 2026
39deef1
Skip leading comments and XML declarations before the SVG element
t-hamano Jun 17, 2026
29eca95
Return null from sanitize_icon_content() on failure
t-hamano Jun 17, 2026
dc2ab15
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 17, 2026
0993ad8
Drop parameter type hint to stay compatible with the parent signature
t-hamano Jun 17, 2026
a46f913
Revert "Return null from sanitize_icon_content() on failure"
t-hamano Jun 17, 2026
cf0d2a3
Use array_fill_keys() for the remaining SVG attribute lists
t-hamano Jun 17, 2026
c7ff855
Add backport changelog
t-hamano Jun 17, 2026
d3ee803
Rename backport changelog file to match its PR number
t-hamano Jun 17, 2026
381209c
Skip ReflectionMethod::setAccessible() on PHP 8.1+
t-hamano Jun 17, 2026
20abfeb
Use @link for WAI-ARIA spec reference in sanitize_icon_content()
t-hamano Jun 19, 2026
33f767d
Use @link for Trac changeset reference in icons registry test
t-hamano Jun 19, 2026
5b2e3d4
Sort SVG sanitizer attribute lists alphabetically
t-hamano Jun 19, 2026
e39539b
Extract get_allowed_attribute_list() helper to build kses attribute l…
t-hamano Jun 19, 2026
c7a1947
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 22, 2026
b88395f
Fix incorrect PHPDoc tags
t-hamano Jun 22, 2026
1fe8e6c
Resolve leftover merge conflict in icons registry test
t-hamano Jun 22, 2026
0c76fa6
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 22, 2026
f203e7d
Icons: Reject foreign-namespaced <svg> in sanitizer
t-hamano Jun 23, 2026
f4c78d9
Icons: Relax SVG extraction but reject multiple roots
t-hamano Jun 23, 2026
de4e098
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jun 26, 2026
a3b0fac
Merge remote-tracking branch 'origin/trunk' into icon-registry-sanitizer
t-hamano Jul 1, 2026
711128d
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jul 8, 2026
abb6f73
Icons Registry: rename sanitizer to sanitize_inline_svg and clarify c…
t-hamano Jul 8, 2026
9f0c80f
Icons Registry: document why truncated SVG input is rejected
t-hamano Jul 8, 2026
b4b7ebc
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Jul 28, 2026
42fe41c
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Aug 1, 2026
6ddec02
Icons: Clarify expected input of sanitize_inline_svg()
t-hamano Aug 1, 2026
a57e993
Icons: Protocol-check xlink:href during SVG sanitization
t-hamano Aug 1, 2026
e43b7a6
Icons: Disallow the SMIL animate and set elements
t-hamano Aug 1, 2026
7b2c89c
Icons: Handle a self-closing SVG root when extracting the element
t-hamano Aug 1, 2026
dde0b00
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Aug 12, 2026
b0a368a
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Aug 18, 2026
72b6978
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Sep 17, 2026
e745b53
Icons: Use input/expected keys in the sanitize_inline_svg data provider
t-hamano Sep 17, 2026
9604c0d
Merge branch 'trunk' into icon-registry-sanitizer
t-hamano Oct 3, 2026
c4073a2
Icons: Declare string types on sanitize_inline_svg()
t-hamano Oct 3, 2026
5c05c02
Icons: Guard against a failed read of an icon file
t-hamano Oct 3, 2026
f278e66
Icons: Declare the array return type on the sanitize_inline_svg data …
t-hamano Oct 3, 2026
fdc9db8
Icons: Declare string parameter types on test_sanitize_inline_svg()
t-hamano Oct 3, 2026
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
Prev Previous commit
Next Next commit
WIP
  • Loading branch information
t-hamano committed Mar 12, 2026
commit 4ae7479cdb4336e55cac82cab633fbb0c41f70d0
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ protected function sanitize_icon_content( $icon_content ) {
);

/*
* Allowed tags for wp_kses(). WP_HTML_Processor::normalize() with
* constraints (similar structure to this array) is proposed to improve
* HTML/SVG sanitization in the future.
* Allowed tags for wp_kses(). Only SVG elements are permitted; foreignObject
* and HTML tags (e.g. p, div) are intentionally excluded as they are not
* valid in icon SVG content per the SVG specification.
*
* @see https://github.com/dmsnell/wordpress-develop/pull/20
*/
Expand Down Expand Up @@ -649,9 +649,10 @@ protected function sanitize_icon_content( $icon_content ) {

$svg = $processor->serialize_token();
$depth = $processor->get_current_depth();
while ( $processor->next_token() && $processor->get_current_depth() >= $depth ) {
while ( $processor->next_token() && $processor->get_current_depth() > $depth ) {
$svg .= $processor->serialize_token();
}
$svg .= '</svg>';
return wp_kses( $svg, $allowed_tags );
}

Expand Down
51 changes: 35 additions & 16 deletions phpunit/experimental/class-gutenberg-icons-registry-7-1-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,43 +65,62 @@ public function test_sanitize_icon_content( $input, $expected ) {
*/
public function data_sanitize_icon_content() {
return array(
'strips script tags' => array(
// Correctly extracts the SVG element.
'strips html-like tags inside svg' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><p>paragraph content</p><path d="M0 0h24v24H0z" /><div>div content</div></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"></svg>',
),
'strips foreignObject and html inside' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><foreignObject><p>paragraph content</p></foreignObject><path d="M0 0h24v24H0z" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" /></svg>',
),
'extracts only first svg when multiple present' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><path d="first"/></svg><svg xmlns="http://www.w3.org/2000/svg"><path d="second"/></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><path d="first" /></svg>',
),

// Dangerous content is stripped.
'strips script tags' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script><path d="M0 0h24v24H0z" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg">alert(1)<path d="M0 0h24v24H0z" /></svg>',
),
'strips event handlers' => array(
'strips event handlers' => array(
'<svg xmlns="http://www.w3.org/2000/svg" onclick="alert(1)"><path d="M0 0h24v24H0z" onload="evil()" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" /></svg>',
),
'returns empty for plain text' => array(
'strips javascript protocol in href' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><use href="javascript:alert(1)" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><use href="alert(1)" /></svg>',
),
'strips disallowed tags' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0"/><iframe src="evil"></iframe><object data="x" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0" /></svg>',
),

// Returns empty string when input is not SVG.
'returns empty for plain text' => array(
'plain text without svg',
'',
),
'returns empty for html without svg' => array(
'returns empty for html without svg' => array(
'<div>not svg</div><p>content</p>',
'',
),
'allows https in href' => array(

// Valid SVG elements and attributes are preserved.
'allows https in href' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><use href="https://example.com/icon.svg#symbol" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><use href="https://example.com/icon.svg#symbol" /></svg>',
),
'strips javascript protocol in href' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><use href="javascript:alert(1)" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><use href="alert(1)" /></svg>',
),
'preserves allowed attributes' => array(
'preserves allowed attributes' => array(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" class="icon" aria-hidden="true"><path d="M0 0" fill="currentColor" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" width="24" height="24" class="icon" aria-hidden="true"><path d="M0 0" fill="currentColor" /></svg>',
),
'preserves allowed elements' => array(
'preserves allowed elements' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" /><rect x="2" y="2" width="20" height="20" /><g><path d="M0 0" /></g></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" /><rect x="2" y="2" width="20" height="20" /><g><path d="M0 0" /></g></svg>',
),
'strips disallowed tags' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0"/><iframe src="evil"></iframe><object data="x" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0" /></svg>',
),
'keeps svg with inner title and desc' => array(
'keeps svg with inner title and desc' => array(
'<svg xmlns="http://www.w3.org/2000/svg"><title>Icon title</title><desc>Description</desc><path d="M0 0h24v24H0z" /></svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><title>Icon title</title><desc>Description</desc><path d="M0 0h24v24H0z" /></svg>',
),
Expand Down