Skip to content

Theme Directory: handle the theme description consistently across both writers - #874

Closed
obenland wants to merge 1 commit into
WordPress:trunkfrom
obenland:themes/description-header-storage
Closed

Theme Directory: handle the theme description consistently across both writers#874
obenland wants to merge 1 commit into
WordPress:trunkfrom
obenland:themes/description-header-storage

Conversation

@obenland

@obenland obenland commented Sep 4, 2026

Copy link
Copy Markdown
Member

A theme description is the one-line Description: header of the author’s style.css. Two writers put it into
post_content and they disagreed about it: create_or_update_theme_post() ran it through strip_shortcodes(),
while wporg_themes_approve_version() — which re-reads style.css from SVN when a version goes live — assigned it
as-is. The second is the only one that runs for an update to an existing theme, so the first never applied there.

strip_shortcodes() is the wrong tool for a header either way:

  • It only removes tags registered in the process that calls it, so it is a snapshot. A description is written once
    and rendered for a long time afterwards.
  • It deliberately unwraps an escaped [[tag]] into a live [tag], so a header carrying a tag and its escaped
    twin still has a shortcode in it afterwards.

Editing the syntax out is no better in general — removing one shortcode can splice the remaining text into another,
which is what [gal[caption]lery ids="1"] does.

So: refuse the header at upload, where the author can be told, and encode the delimiters on the SVN path, where
there is nobody to tell. Detection has neither problem, and the encoded form still reads as written ([ renders
as [).

Complements WordPress/wporg-theme-directory#179, which stops the theme page interpreting the description at all;
that side also covers descriptions stored before either change.

Also narrows the scope of #871 — the description handling there is superseded, the Name/Author/URI headers are not.

Testing steps

  1. Upload a theme whose style.css has Description: Fixture [caption width="1" caption="x"]y[/caption] theme.
    The upload is refused with a message pointing at the Description: line. Try [[caption …]y[/caption]] and
    [gal[caption]lery ids="1"] too; both are refused.
  2. A description with ordinary brackets — A theme for [developers] and designers — uploads fine.
  3. Commit a description carrying a shortcode straight to SVN and let the version go live. The stored post_content
    reads [caption …], renders as [caption …], and runs nothing.
  4. npm run themes:test from environments/ → 145 tests, 215 assertions. The pre-existing
    Search_Published_Filter_Test risky-test notice is unrelated.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Theme uploads now reject descriptions containing shortcodes.
    • Theme descriptions imported from SVN are safely encoded to prevent shortcode interpretation.
    • Bracketed prose remains supported, while ordinary descriptions are preserved unchanged.
    • Approved theme descriptions retain their content without executing embedded shortcodes.

…h writers

A theme's description is the one-line `Description:` header of the author's
`style.css`. Two writers put it into `post_content` and they disagreed about it:
`create_or_update_theme_post()` ran it through `strip_shortcodes()`, and
`wporg_themes_approve_version()`, which re-reads `style.css` from SVN when a
version goes live, assigned it as-is. The second is the only one that runs for an
update to an existing theme, so the first never applied there.

`strip_shortcodes()` is the wrong tool either way. It only removes tags that are
registered in the process that calls it, and it deliberately unwraps an escaped
`[[tag]]` into a live `[tag]`, so a header carrying a tag and its escaped twin
comes out of it with a shortcode still in place. Editing the syntax out is no
better in general: removing one shortcode can splice the remaining text into
another, as `[gal[caption]lery ids="1"]` does.

Refuse the header at upload instead, where the author can be told about it, and
encode the delimiters on the SVN path, where there is nobody to tell. Detection
does not have either problem, and the encoded form still reads as it was written.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 4, 2026 19:08
@github-actions

github-actions Bot commented Sep 4, 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.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: d818fb7c-aad3-4799-877b-53201a81c3be

📥 Commits

Reviewing files that changed from the base of the PR and between a3bbd33 and 06a7b31.

📒 Files selected for processing (3)
  • wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php
  • wordpress.org/public_html/wp-content/plugins/theme-directory/tests/Theme_Description_Shortcodes_Test.php
  • wordpress.org/public_html/wp-content/plugins/theme-directory/theme-directory.php

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

Theme uploads now reject descriptions containing shortcodes. Approved SVN descriptions escape square brackets before storage. Tests cover upload validation, approval behavior, cleanup, and ordinary descriptions.

Changes

Theme description safety

Layer / File(s) Summary
Upload shortcode validation
wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php, wordpress.org/public_html/wp-content/plugins/theme-directory/tests/Theme_Description_Shortcodes_Test.php
The importer reports shortcode_in_description for shortcode descriptions. Tests cover direct, escaped, and spliced shortcodes, plus accepted bracketed prose.
Description encoding during approval
wordpress.org/public_html/wp-content/plugins/theme-directory/theme-directory.php, wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php, wordpress.org/public_html/wp-content/plugins/theme-directory/tests/Theme_Description_Shortcodes_Test.php
SVN descriptions encode square brackets before theme post updates. The stored content uses the original description without strip_shortcodes(). Tests verify inert shortcode text and unchanged ordinary descriptions.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 06a7b

Theme descriptions now reject shortcode syntax on upload and store SVN-imported shortcode delimiters inertly, while ordinary bracketed descriptions remain supported. The change is covered across both write paths and is ready to merge.

Sequence Diagram(s)

sequenceDiagram
  participant SVN
  participant ThemeDirectory
  participant ThemePost
  SVN->>ThemeDirectory: provide theme description
  ThemeDirectory->>ThemeDirectory: validate or encode square brackets
  ThemeDirectory->>ThemePost: update theme post content
  ThemePost-->>ThemeDirectory: store description without shortcode execution
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: consistent theme description handling across both theme-writing paths.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 3 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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.

🟡 Changes recommended

The new upload-time detection relies on get_shortcode_regex() (registered shortcodes only), which can miss shortcode syntax for unregistered tags and undermine the long-lived safety goal described in the PR.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR makes Theme Directory handling of the one-line Description: header consistent across the upload path and the SVN “version goes live” path, preventing shortcode execution by rejecting shortcode syntax on upload and encoding delimiters on the SVN writer.

Changes:

  • Add upload-time validation to refuse theme descriptions that contain shortcode syntax.
  • Stop running strip_shortcodes() when writing Description: into post_content during upload.
  • Encode [/] in the SVN approval path and add PHPUnit coverage for both writers.
File summaries
File Description
wordpress.org/public_html/wp-content/plugins/theme-directory/theme-directory.php Encodes square brackets in the SVN approval writer before storing post_content.
wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php Adds upload-time shortcode detection error and stores the description as-is (no strip_shortcodes()).
wordpress.org/public_html/wp-content/plugins/theme-directory/tests/Theme_Description_Shortcodes_Test.php Adds tests covering upload refusal and SVN-path delimiter encoding behavior.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@wporg-sync wporg-sync closed this in 7a30578 Sep 4, 2026
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