Skip to content

Escape translated strings on output - #895

Closed
obenland wants to merge 19 commits into
WordPress:trunkfrom
obenland:update/escape-translated-output
Closed

Escape translated strings on output#895
obenland wants to merge 19 commits into
WordPress:trunkfrom
obenland:update/escape-translated-output

Conversation

@obenland

@obenland obenland commented Sep 9, 2026

Copy link
Copy Markdown
Member

Escapes translated strings on their way into markup, clearing every WordPress.Security.EscapeOutput.UnsafePrintingFunction violation and the __()-family OutputNotEscaped ones (EscapeOutput total 2,437 → 1,080; UnsafePrintingFunction 826 → 0). Second batch after #814.

Where a rewrite put a line into the diff, the other violations the changed-lines linter reports for that line are fixed alongside it, which is what the fourth commit is.

Commit by commit:

  1. Rewrites the flagged _e(), _ex(), __(), _x(), _n() and _nx() calls. Plain strings become esc_html_e() / esc_html__(), or the esc_attr variants where the call sits inside an attribute. Plural calls are wrapped in esc_html(). The 139 strings that carry markup are wrapped in wp_kses_post() rather than restructured, so those strings keep their existing translations. One string printed into a JavaScript literal goes through esc_js(). Call spacing and missing semicolons on the touched lines are normalised. Also fixes a <span5%s</span> typo in the bb-base activity nav that broke the BuddyPress translation lookup for that label.
  2. The handbook watch link only needs its label translated, so the anchor becomes the format string and the label goes through esc_html__().
  3. Adds translators comments to the placeholder strings on touched lines that lacked one.
  4. The rest of what the changed-lines linter reports: escapes the neighbouring output on the same lines (bbPress titles and author links, counts, dates, widget title markup, activity nav URLs); numbers the placeholders in five strings that use %s more than once; turns the concatenated _n() in the Trac components page into a proper plural string with the milestone as a placeholder; reflows multi-line printf() calls into the ruleset's call-signature format; adds file docblocks to templates whose first line changed; registers jobswp_field_value() as auto-escaping in the ruleset since it returns selected() markup, a kses-filtered description, or an esc_attr()'d value; and marks with scoped phpcs:ignore comments the jobswp templates' reads of $_POST['errors'] and $_POST['job_token'], which the plugin's own form handler sets, and the two list-table search subtitles that are escaped for display. Two rosetta templates and two forum notices go from CRLF to LF.
  5. Straight apostrophes in the translated strings on touched lines become &#8217;, the form the surrounding strings already use, and strings that only needed double quotes for an apostrophe move to single quotes. Also fixes "are't" in the Photo Directory stats notice.
  6. Review fixes: wp_kses_post() where the wrapped value is markup (bbPress freshness links, the author card status labels, the Photo Directory rejecting-user link) and the $format template the photo submitbox still used.
  7. Review fixes: the support forums prepend an <abbr> to NSFW topic titles, so the support-2024 headings use wp_kses_post(); the plugin title and committer name that reach HTML slots as printf() arguments are escaped; and the "No site" string the first commit had turned into "None" is restored.

Decisions worth a look:

  • Strings with markup keep their text and get wp_kses_post(). Moving the tags out would change the translation keys for dozens of locales. The handbook watch link is the one place that was done, on request. The strings that do change are the two watch labels, the five with numbered placeholders, the Trac milestone plural, the <span5 typo, and the 21 apostrophes.
  • bbp_get_topic_author_link() and get_the_author_posts_link() return markup and get wp_kses_post(); widget $before_title / $after_title too.
  • Counts get an (int) cast rather than esc_html().

Left for follow-ups, in this order: the known-safe function outputs (number_format_i18n(), human_time_diff(), get_the_*(), bbPress getters), the 29 exception messages, then the plain variables one component at a time.

🤖 Generated with Claude Code

obenland and others added 4 commits September 9, 2026 16:25
Rewrites the _e(), _ex(), __(), _x(), _n() and _nx() calls the
EscapeOutput sniff flags across the sites. Plain strings go through
esc_html_e() and esc_html__(), or the esc_attr variants inside
attributes; plural calls are wrapped in esc_html(); strings that carry
markup are wrapped in wp_kses_post(), so no translation string changes.
One string printed into a JavaScript literal uses esc_js(). Call spacing
and missing statement semicolons on the touched lines are normalised
alongside.

Also corrects a `<span5%s</span>` typo in the bb-base activity nav that
broke the BuddyPress translation lookup for that label.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Only the label needs translating, so the anchor becomes the format
string and the label goes through esc_html__().

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The changed-lines linter reports every placeholder string on a touched
line that lacks one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Escapes the neighbouring output on the same lines: bbPress titles and
  author links, counts, dates, widget title markup and the BuddyPress
  activity nav URLs.
- Numbers the placeholders in five strings that use %s more than once,
  and turns the concatenated _n() in the Trac components page into a
  proper plural string with the milestone as a placeholder.
- Reflows the multi-line printf() calls into the call-signature format
  the ruleset wants, and adds file docblocks to the templates whose first
  line changed.
- Registers jobswp_field_value() as auto-escaping in the ruleset; it
  returns selected() markup, a kses-filtered description, or an
  esc_attr()'d value.
- Marks the jobswp templates' reads of $_POST['errors'] and
  $_POST['job_token'], which the plugin's form handler sets, and the
  search-term subtitles that are escaped for display, with scoped
  phpcs:ignore comments.
- Converts two rosetta templates and two forum notices from CRLF to LF.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 9, 2026 21:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 204 files, which is 104 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 1a49cab0-6817-45ae-bdcc-5ec20cf6adf3

📥 Commits

Reviewing files that changed from the base of the PR and between 8eae6fa and 115577a.

📒 Files selected for processing (204)
  • browsehappy.com/public_html/functions.php
  • browsehappy.com/public_html/index.php
  • buddypress.org/public_html/wp-content/themes/bb-base/archive-forum.php
  • buddypress.org/public_html/wp-content/themes/bb-base/archive.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/feedback-search.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/form-topic-merge.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/form-topic-split.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/form-topic.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/loop-forums.php
  • buddypress.org/public_html/wp-content/themes/bb-base/bbpress/loop-single-topic.php
  • buddypress.org/public_html/wp-content/themes/bb-base/buddypress/activity/index.php
  • buddypress.org/public_html/wp-content/themes/bb-base/buddypress/members/single/profile/edit.php
  • buddypress.org/public_html/wp-content/themes/bb-base/footer.php
  • buddypress.org/public_html/wp-content/themes/bb-base/functions.php
  • buddypress.org/public_html/wp-content/themes/bb-base/header-accessibility.php
  • buddypress.org/public_html/wp-content/themes/bb-base/image.php
  • buddypress.org/public_html/wp-content/themes/bb-base/index.php
  • buddypress.org/public_html/wp-content/themes/bb-base/page-homepage.php
  • buddypress.org/public_html/wp-content/themes/bb-base/sidebar.php
  • buddypress.org/public_html/wp-content/themes/bb-base/single.php
  • buddypress.org/public_html/wp-content/themes/bbpress-org/bbpress/form-topic.php
  • buddypress.org/public_html/wp-content/themes/bbpress-org/header-front.php
  • buddypress.org/public_html/wp-content/themes/bbpress-org/page-plugins.php
  • buddypress.org/public_html/wp-content/themes/bbpress-org/sidebar.php
  • buddypress.org/public_html/wp-content/themes/bporg-developer/header.php
  • buddypress.org/public_html/wp-content/themes/bporg-developer/page-reference-landing.php
  • buddypress.org/public_html/wp-content/themes/bporg-developer/reference/template-source.php
  • buddypress.org/public_html/wp-content/themes/buddypress-org/bbpress/form-topic.php
  • buddypress.org/public_html/wp-content/themes/buddypress-org/footer.php
  • buddypress.org/public_html/wp-content/themes/buddypress-org/header-front.php
  • buddypress.org/public_html/wp-content/themes/buddypress-org/header-nav.php
  • buddypress.org/public_html/wp-content/themes/buddypress-org/sidebar.php
  • buddypress.org/public_html/wp-content/themes/codex-bbpress-org/footer.php
  • buddypress.org/public_html/wp-content/themes/codex-bbpress-org/index.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/activity-entry.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/footer.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/header-nav.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/index.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/widgets/inbox.php
  • buddypress.org/public_html/wp-content/themes/codex-buddypress-org/widgets/login.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/downloads/rosetta-downloads.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/roles/class-translation-editors-list-table.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/roles/views/cross-locale-pte.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/roles/views/edit-cross-locale-pte.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/roles/views/edit-translation-editor.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/roles/views/translation-editors.php
  • global.wordpress.org/public_html/wp-content/mu-plugins/showcase/rosetta-showcase.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/404.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/archive.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/comments.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/contact.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/download.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/front-page.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/functions.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/inc/template-tags.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/index.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/sidebar-blog.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/sidebar-page.php
  • global.wordpress.org/public_html/wp-content/themes/rosetta/single.php
  • jobs.wordpress.net/public_html/wp-content/plugins/jobswp/jobswp-captcha.php
  • jobs.wordpress.net/public_html/wp-content/plugins/jobswp/jobswp-moderation.php
  • jobs.wordpress.net/public_html/wp-content/plugins/jobswp/jobswp-template.php
  • jobs.wordpress.net/public_html/wp-content/plugins/jobswp/jobswp.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/content-list.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/content-post-job-success.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/content-post-job.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/inc/template-tags.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/no-results.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/page-remove-a-job.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/searchform.php
  • jobs.wordpress.net/public_html/wp-content/themes/jobswp/sidebar.php
  • phpcs.xml.dist
  • wordpress.org/public_html/wp-content/plugins/handbook/inc/admin-notices.php
  • wordpress.org/public_html/wp-content/plugins/handbook/inc/handbook.php
  • wordpress.org/public_html/wp-content/plugins/handbook/inc/navigation.php
  • wordpress.org/public_html/wp-content/plugins/handbook/inc/watchlist.php
  • wordpress.org/public_html/wp-content/plugins/handbook/inc/widgets.php
  • wordpress.org/public_html/wp-content/plugins/photo-directory/inc/admin.php
  • wordpress.org/public_html/wp-content/plugins/photo-directory/inc/flagged.php
  • wordpress.org/public_html/wp-content/plugins/photo-directory/inc/moderation.php
  • wordpress.org/public_html/wp-content/plugins/photo-directory/inc/rejection.php
  • wordpress.org/public_html/wp-content/plugins/photo-directory/inc/settings.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-status-transitions.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-committers.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-plugin-posts.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-support-reps.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-author-card.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-author.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-controls.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-internal-notes.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-review-tools.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-author-cards.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-stats-report.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-upload-token.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-block-validator.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-readme-validator.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-release-confirmation.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-reviews.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-upload.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-adopt-me.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-committers.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-donate.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-meta.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-support-reps.php
  • wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-support.php
  • wordpress.org/public_html/wp-content/plugins/rosetta/inc/admin/network/class-locale-associations-view.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-blocks.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-hooks.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-moderators.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-nsfw-handler.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-ratings-compat.php
  • wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-report-topic.php
  • wordpress.org/public_html/wp-content/plugins/theme-directory/admin-edit.php
  • wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php
  • wordpress.org/public_html/wp-content/plugins/theme-directory/theme-directory.php
  • wordpress.org/public_html/wp-content/plugins/trac-notifications/trac-components.php
  • wordpress.org/public_html/wp-content/plugins/wp-i18n-teams/inc/locales.php
  • wordpress.org/public_html/wp-content/plugins/wp-i18n-teams/views/all-locales.php
  • wordpress.org/public_html/wp-content/plugins/wp-i18n-teams/views/locale-details.php
  • wordpress.org/public_html/wp-content/plugins/wporg-bbp-also-viewing/wporg-bbp-also-viewing.php
  • wordpress.org/public_html/wp-content/plugins/wporg-bbp-topic-resolution/inc/class-plugin.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/helper-functions.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/index-locales.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/locale-project.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/locale-projects.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/project-form.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/project-mass-create-sets.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/projects-wp-plugins-contributors.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/projects-wp-themes-contributors.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/settings.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/stats-overview.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/translation-row-editor.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/translation-row-preview.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/translation-set-form.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-discussions/inc/class-plugin.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-rosetta-roles/inc/admin/class-translators.php
  • wordpress.org/public_html/wp-content/plugins/wporg-gp-rosetta-roles/inc/admin/list-table/class-translators.php
  • wordpress.org/public_html/wp-content/plugins/wporg-meeting-posttype/wporg-meeting-posttype.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-breathe-2024/functions.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-breathe-2024/search.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-breathe-2024/searchform.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-breathe-2024/single-handbook.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/backup-codes.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/checkemail.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/enable-2fa.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/functions-registration.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/functions.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/linkexpired.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/loggedout.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/login.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/logout.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/lostpassword.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/partials/register-profilefields.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/pending-create.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/pending-profile.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/register.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-login/updated-tos.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-main/front-page.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-main/page-download-beta-nightly.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-main/page-download.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/inc/template-tags.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/patterns/page-add.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/404.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/archive.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/comments.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/functions.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/index.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/page-home.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/page-submit.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-showcase/sidebar-left.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/404.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/archive-forum.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/content-single-forum.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/feedback-no-search.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/feedback-no-topics.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/feedback-search.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/form-reply.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/form-topic-merge.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/form-topic-split.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/form-topic.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/form-user-edit.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/loop-forums-homepage.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/loop-forums.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/loop-single-reply-topic.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/loop-single-topic.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/user-profile.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/bbpress/user-subscriptions.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/functions.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/page-homepage.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/searchform.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg-support-2024/sidebar.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg/404.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg/inc/template-tags.php
  • wordpress.org/public_html/wp-content/themes/pub/wporg/template-parts/content-none.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/404.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/archive.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/breadcrumbs.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/comments.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/functions.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/index.php
  • wordpress.tv/public_html/wp-content/themes/wptv2/upload-subtitles-template.php
  • wp15.wordpress.net/public_html/content/mu-plugins/locales.php

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props obenland.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

obenland and others added 15 commits September 9, 2026 16:39
Straight apostrophes in the translated strings on touched lines become
&#8217;, the form the surrounding strings already use, and the strings
that only needed double quotes for an apostrophe move to single quotes.
Also fixes "are't" in the Photo Directory stats notice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The freshness links, the author card status labels and the rejecting
user link are anchors or styled spans, so esc_html() printed their tags
as text. Also restores the $format template the moderator row in the
photo submitbox still uses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The support forums prepend an <abbr> to NSFW topic titles through the
bbp_get_topic_title filter, so the support-2024 headings take
wp_kses_post() rather than esc_html(). Escapes the plugin title and the
committer name that reach HTML slots as printf() arguments, and restores
the "No site" string the first commit had turned into "None".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd it.

Fixes the one user-visible regression in the batch: repairing the
`<span5%s</span>` typo in the bb-base activity nav made the corrupted
`'ms'` argument visible, so the sitewide activity directory rendered
"All Members ms". It now passes bp_get_total_member_count(), matching
the four sibling tabs.

Five translators comments sat on their own line above a line holding two
gettext calls, so the extractor bound them to the leading placeholder-free
string and the string with the placeholder got nothing. They move inline,
immediately before the call they describe.

The jobswp ruleset entry claimed jobswp_field_value() is safe in every
context, but its job_description branch returns kses-filtered HTML that
carries unescaped quotes. That branch becomes jobswp_field_description_value(),
so the allowlisted function only ever returns an attribute fragment, and the
now-redundant per-line ignore goes away.

The `$_POST['errors']` and `$_POST['job_token']` ignores said the values are
"not read from the request", which is the opposite of what those lines do:
the form handlers are gated on postjob/removejob and check their nonce inside
that gate, while the templates read the keys on a bare isset(). The
justification now names the real protection, the reads are unslashed, and the
sniff scope narrows to InputNotSanitized so MissingUnslash is no longer hidden.

Also escapes the arguments the sweep left raw next to ones it fixed: the
bbPress forum title in the topic sidebar, the .tar.gz size, the plugin titles
and permalinks in the release confirmations list, the review author name and
login, the current user's display name, and the ratings-compat notice that
carries an anchor.

Nits: aligns @Package with each directory's convention, corrects the two
GlotPress form partial docblocks to say they serve both new and edit, names
the placeholder in the meetups comment, and normalises the translators
comments this batch touched to sentence case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The .tar.gz size collapses onto one line, matching the .zip sibling above
it, rather than tripping the multi-line call-signature rules; its URL gets
esc_url() now that the line is in the diff.

Narrowing the job token's ignore to InputNotSanitized uncovered
InputNotValidated, which the previous blanket ignore had hidden. The index
is validated instead of suppressed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…comment binding.

The (int) casts on the activity nav counts truncated them. All five
bp_get_total_*() helpers are filtered through bp_core_number_format(),
so they return number_format_i18n() output; (int) "1,234" is 1, and the
tabs rendered "1" for any count over 999. Four of those casts were a
regression against trunk, which passed the values raw. They now go
through esc_html() instead.

wp_kses_post() around bbp_get_topic_author_link() silently dropped the
avatar's srcset and decoding attributes, which are not in
$allowedposttags['img'], leaving blurry 1x gravatars on HiDPI in the
topic lists. Those two call sites now echo bbPress's markup with a
scoped ignore, matching the sibling templates that already do.

The translators comments above the wptv2 archive headings sat on the
line before a line holding two gettext calls, so the extractor bound
them to the date-format msgids as well; a translator reading
"translators: %s: Year." on the msgid "Y" could reasonably put a
placeholder into a date format. The date format moves to its own line.
The two term titles there are escaped to match their date siblings.

The buddypress-domain tooltip goes back to the straight apostrophe:
that msgid belongs to BuddyPress, and it has to match upstream's
catalogue byte for byte.

Reverts the @Package tags on three theme root templates: the
bbpress/ subdirectory convention does not apply to footer.php and
header-accessibility.php, which are the themes' own templates.

Corrects two comments of mine that said the opposite of what the code
does: jobswp_field_value() returns a whole attribute pair rather than
something safe inside an attribute's quotes and can return nothing at
all, and wp_filter_kses() re-slashes on the way out, which is why the
outer stripslashes() has to stay.

Also escapes the zip download link and version, the category select's
classes, and the two term titles; drops two stale translators comments
that described the wrong string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bb-base post byline escaped its format string but passed both
arguments through raw, so WordPress.Security.EscapeOutput still errored
on archive.php, index.php and single.php. get_the_author_link() returns
markup, so it takes wp_kses_post() rather than esc_html().

Also drops the translators comment that became a duplicate: WPCS wants
it directly above the gettext call, which is where this batch put it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sweep added a translators comment inside the printf, where WPCS
wants it, leaving the pre-existing one above the call saying the same
thing. Same cleanup as the bb-base byline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The topic title in these headings was wrapped in straight double quotes.
They become &#8220;/&#8221;, matching the &#8217; the rest of the batch
uses. esc_html__() leaves the entities alone, since _wp_specialchars()
passes double_encode false through to htmlspecialchars().

These strings are in the wporg-forums domain, so the new msgids orphan
their existing translations; bbPress's own copies of these templates are
in the bbpress domain and are unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The heading put "in the %s component" outside the _n() call, so the
sentence could only ever render in English word order. Both halves move
into the plural forms with numbered placeholders, letting translators
reorder them. Rendered output is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The two codex themes carry the same byline as the bb-base templates:
an escaped format string with both arguments passed raw. get_the_author_link()
returns markup, so it takes wp_kses_post(); the date takes esc_html(). The
translators comment the batch superseded goes away with them.

The showcase description textarea echoed post_excerpt behind a
// textarea_escaped annotation that asserted an escaping the line did not
do. textarea is in kses' post set, so a saved excerpt containing
</textarea> closes the field early on the edit screen. It goes through
esc_textarea() now and the annotation is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Same treatment as the support forums: bbPress builds the markup, and
wp_kses_post() would strip the srcset and decoding attributes from the
avatar.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants