Skip to content

Posts, Post Types: Unslash tags_input before comparing in wp_update_post(). - #14469

Open
abhishekfdd wants to merge 1 commit into
WordPress:trunkfrom
abhishekfdd:62461-unslash-tags-input
Open

abhishekfdd wants to merge 1 commit into
WordPress:trunkfrom
abhishekfdd:62461-unslash-tags-input

Conversation

@abhishekfdd

Copy link
Copy Markdown

wp_update_post() slashes the post array before comparing tags_input against the post's existing tag names. A tag name containing a character that wp_slash() escapes, such as an apostrophe in children's, no longer matches, so tags_input is not discarded and all of the names are passed to wp_set_post_tags(). There, term_exists() can resolve a name like kid+ to a different term whose slug is kid, so a title-only update silently swaps the post's tags.

This also affects the block editor: editing only a post's title sends a REST update without tags, which goes through wp_update_post() and triggers the same swap.

This PR unslashes tags_input before the strict comparison. It also adds a test that creates kid, kid+ and children's tags, assigns kid+ and children's to a post, updates only the title, and asserts that the tags are unchanged. The test fails without the fix (kid+ is replaced by kid) and passes with it.

Trac ticket: https://core.trac.wordpress.org/ticket/62461

Use of AI Tools

AI assistance: Yes
Tool(s): Claude (claude.ai) and Claude Code
Model(s): Claude Opus 5.5
Used for: Claude was used to reproduce and diagnose the bug and to draft the fix and the test. Claude Code applied the patch, ran the tests and lint, and committed. I reviewed and tested the changes.


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.

…e_post()`.

`wp_update_post()` slashes the post array, so tag names containing characters like apostrophes no longer match the existing tag names, and `tags_input` is not discarded. The names are then passed to `wp_set_post_tags()`, where `term_exists()` can resolve a name such as `kid+` to a different term whose slug is `kid`.

See #62461.
@github-actions

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 abhishekfdd.

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

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The 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

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@rejaulalomkhan rejaulalomkhan 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.

Thanks for working on this and diagnosing the root cause so thoroughly, @abhishekfdd! Unslashing tags_input before comparing against the unslashed tag names cleanly resolves the bug where title-only updates silently swapped tags containing slashable characters.

  • Verified reproduction locally on trunk: without the fix, test_wp_update_post_should_not_change_tags_with_slashable_names fails as expected (Failed asserting that two arrays are identical: Expected array(3, 4), Actual array(2, 4)).
  • With the fix applied, the new unit test passes cleanly (1 test, 2 assertions).
  • All 62 tests and 237 assertions in tests/phpunit/tests/post/wpInsertPost.php pass across single-site, multisite, and random order (--order-by=random).
  • Verified --group taxonomy (1,085 tests, 2,869 assertions) passes with no regressions.
  • PHPCS check on modified lines in src/wp-includes/post.php and tests/phpunit/tests/post/wpInsertPost.php passes with 0 errors and 0 warnings.

Looks good to merge!

AI Review: Antigravity

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