Administration: Strip escaped HTML from list table aria-labels - #12710
Administration: Strip escaped HTML from list table aria-labels#12710itzmekhokan wants to merge 1 commit into
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
The attachment, post and link names used in the row action `aria-label` attributes are escaped before use: by `_draft_or_post_title()` for posts and attachments, and by `WP_Links_List_Table::display_rows()` for links. Some of these values are also stored with any HTML already escaped. Because `esc_attr()` does not double encode, that escaped HTML survives into the attribute, and screen readers announce it as literal markup, for example `Edit "my<div>image"`. Decode the entities before calling `wp_strip_all_tags()` so the HTML can be detected and removed, following the pattern already used by `WP_REST_URL_Details_Controller::prepare_metadata_for_output()`. The displayed link name is intentionally left unchanged. Fixes #65729.
There was a problem hiding this comment.
Pull request overview
Improves accessibility in wp-admin list tables by preventing escaped HTML fragments in titles/names from being announced literally by screen readers when used in row-action aria-label attributes.
Changes:
- Decode HTML entities and strip tags before building row-action
aria-labelvalues in Posts and Media list tables. - Clean only the
aria-labelvalue (not the displayed text) for link names in the Links list table. - Add PHPUnit coverage to ensure escaped HTML is removed from these
aria-labelattributes.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/wp-admin/includes/class-wp-posts-list-table.php |
Decodes entities then strips tags from the post title before composing row-action aria-label strings. |
src/wp-admin/includes/class-wp-media-list-table.php |
Decodes entities then strips tags from the attachment title before composing row-action aria-label strings. |
src/wp-admin/includes/class-wp-links-list-table.php |
Introduces a cleaned name variant for aria-label while leaving the displayed link name unchanged. |
tests/phpunit/tests/admin/wpPostsListTable.php |
Adds a test asserting escaped HTML is removed from Posts list table row-action aria-labels. |
tests/phpunit/tests/admin/wpMediaListTable.php |
Adds a test asserting escaped HTML is removed from Media list table row-action aria-labels. |
tests/phpunit/tests/admin/wpLinksListTable.php |
Adds a new test file validating link-name aria-label cleaning without changing visible output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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. |
b137090 to
8b476c1
Compare
Some of the values used in list table
aria-labelattributes reach the attribute with their HTML already escaped, so screen readers announce the markup as literal text.What the problem was:
_draft_or_post_title(), and the link name is escaped byWP_Links_List_Table::display_rows(). Some of these values are also stored in the database with any HTML already escaped.esc_attr()does not double encode, so the escaped HTML survives into the attribute. The browser decodes it back and the accessible name becomesEdit "my<div>image"instead ofEdit "myimage".What the fix does:
html_entity_decode()before callingwp_strip_all_tags(), so the HTML can be detected and removed, inWP_Media_List_Table::handle_row_actions(),WP_Posts_List_Table::handle_row_actions(), andWP_Links_List_Table::column_name().aria-labelvalue is cleaned.Approach and why:
WP_REST_URL_Details_Controller::prepare_metadata_for_output(), rather than introducing a new formatting helper. The ticket raises a helper as a possibility ("maybe a new formatting helper function could be handy"), but that is a new public API worth deciding separately with committer input, so this patch keeps the change to the affected call sites only.blogname) case named in the ticket is not currently used in any trunk list table attribute, so nothing is changed for it here.sanitize_term()on creation and update.Trac ticket: https://core.trac.wordpress.org/ticket/65729
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.8
Used for: Ticket analysis, tests and writing PR description.
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.