Repository navigation
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
t-hamano
force-pushed
the
66112-icons-rect-circle-sanitizer
branch
2 times, most recently
from
September 15, 2026 14:05
44ca689 to
14edf58
Compare
A number of icons in the icon library are redrawn with the `rect` and `circle` elements. `WP_Icons_Registry::sanitize_icon_content()` allows the `svg`, `path` and `polygon` tags only, so `wp_kses()` removes both elements before the icon is stored or returned. This adds `rect` and `circle` to the allowlist, carrying the same presentation attributes the existing shapes have along with the geometry attributes each element needs. Props wildworks, retrofox. See #66101. Fixes #66112. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
t-hamano
force-pushed
the
66112-icons-rect-circle-sanitizer
branch
from
September 15, 2026 14:10
14edf58 to
e3e6d1e
Compare
fabiankaegy
added a commit
to 10up/wp-scaffold
that referenced
this pull request
Oct 14, 2026
## Why WordPress 7.0/7.1 ship a core Icons API (`wp_register_icon()`, `WP_Icons_Registry`). Its sanitizer, `WP_Icons_Registry::sanitize_icon_content()`, runs `wp_kses` with a fixed allowlist and no filter: - `svg`: `class`, `xmlns`, `width`, `height`, `viewbox`, `aria-hidden`, `role`, `focusable` - `path`: `fill`, `fill-rule`, `d`, `transform` - `polygon`: `fill`, `fill-rule`, `points`, `transform`, `focusable` Everything else (`g`, `polyline`, `circle`, `rect`, `stroke*`, `clip-rule`, `id`, `style`, …) is removed without a warning. The icon still registers, but it renders empty or wrong. A Feather `check.svg` comes back as an empty `<svg>`. Upstream is widening the list in WordPress/wordpress-develop#12197 and WordPress/wordpress-develop#13539, but neither has merged, so this check matches what ships today. ## Scope: a lint, not a sanitizer This checks **rendering fidelity** of icons committed to a theme: trusted code, reviewed like any PHP file. It answers "will core's sanitizer leave this icon intact?", not "is this SVG safe?". The tokenizer is deliberately simple because it never decides what reaches a page. Core's `wp_kses` pass on registration still does that. Nothing here accepts SVG from users. A feature that does (an admin icon upload, say) needs its own sanitizer that rebuilds the markup from an allowlist rather than filtering it. ## What - `bin/lint-svg.mjs`: a zero-dependency Node script. It reports disallowed elements (with counts) and disallowed attributes per element, comparing names case-insensitively as kses does, and adds fix hints for strokes, shapes and `<g>` wrappers. XML declarations, doctypes and comments are ignored. It exits 1 on any problem. The allowlist sits in one commented constant to update as core widens it. - `npm run lint-svg`: with no arguments it scans `themes/*/assets/svg` and `mu-plugins/*/assets/svg`. It also takes files, folders or globs. - lint-staged runs it on staged `**/assets/svg/**/*.svg` files. - A `lint-svg` job in `.github/workflows/node.yml`. It needs Node only, no install. - Docs: a new "SVG Icons" section in `docs/frontend-development/frontend-build-process.md`, and the pre-commit list in `docs/testing-quality/code-quality.md`. ## How to test ```bash npm run lint-svg # passes: the svg folders are empty npm run lint-svg -- path/to/icons # point it at a folder of Feather icons to see failures ``` Example output for a Feather icon: ``` feather-check.svg ✖ element <polyline> is not allowed (1×) ✖ <svg> attributes not allowed: fill, stroke, stroke-width, stroke-linecap, stroke-linejoin → stroke attributes are stripped by core — outline strokes in your design tool (Figma: Outline stroke) before exporting → convert shapes to paths (e.g. SVGO convertShapeToPath) ```
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backports Gutenberg PR #82846 to the Core icon registry.
A number of icons in the icon library are redrawn with the
rectandcircleelements, butWP_Icons_Registry::sanitize_icon_content()allows thesvg,pathandpolygontags only, sowp_kses()removes both elements before the icon is stored or returned. Icons registered by plugins and themes throughwp_register_icon()are affected today, and the redrawn library icons will lose part of their shape once they are synced to Core.Both new entries carry the presentation attributes the existing shapes already have, plus the geometry attributes each element needs.
Notes:
rectandcircleneed to carry them as well, since the two elements are drawn with strokes in the library today.focusableis not included. It is meaningful on thesvgroot element only, and the entry onpolygonis a leftover from the Twenty Twenty allowlist this list was copied from.Trac ticket: https://core.trac.wordpress.org/ticket/66112
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Porting the Gutenberg change to its Core equivalent and drafting the unit tests. The result was reviewed and edited by me.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.