Skip to content

Copy Post: fix backslash characters being stripped when duplicating a post#48870

Merged
Gilmoursa merged 3 commits into
Automattic:trunkfrom
Gilmoursa:fix/copy-post-backslash-stripping
May 15, 2026
Merged

Copy Post: fix backslash characters being stripped when duplicating a post#48870
Gilmoursa merged 3 commits into
Automattic:trunkfrom
Gilmoursa:fix/copy-post-backslash-stripping

Conversation

@Gilmoursa
Copy link
Copy Markdown
Contributor

Fixes #46020

Proposed changes

wp_update_post() calls wp_unslash() internally because it expects WordPress-style slashed data (as received from $_POST). The Copy Post module passed raw database content from get_post() directly — content that is already unslashed — so backslash sequences like \t, \n, \\, and \f were silently stripped from post_content, post_title, and post_excerpt when duplicating a post.

Fix: wrap the data array with wp_slash() before calling wp_update_post() in update_content(), which is the standard WordPress pattern for passing programmatically-constructed post data.

One-line change:

// Before
return wp_update_post( $data );

// After
return wp_update_post( wp_slash( $data ) );

Also adds a regression test using ReflectionMethod to invoke the protected update_content() method and assert that backslashes in all three fields are preserved after the copy.

Does this pull request change what data or activity we track or use?

No. This is a bug fix for data fidelity during post duplication. No tracking or privacy-relevant behaviour is changed.

Testing instructions

  1. Enable the Copy Post module in Jetpack → Settings → Writing.
  2. Create a post containing backslash characters, e.g. add a Code block with the text \t is a tab and a paragraph with \\escaped\\.
  3. Save and publish the post.
  4. Go to Posts → All Posts, find the post, and click Duplicate.
  5. Open the duplicated post — the content should be identical to the original, with all backslashes intact.
    • Before this fix: \t is a tab becomes t is a tab; \\escaped\\ becomes \escaped\
    • After this fix: content is preserved exactly

🤖 Generated with Claude Code

wp_update_post() / wp_insert_post() calls wp_unslash() internally
because it expects slashed $_POST-style data. Passing raw DB content
(e.g. from get_post()) directly caused backslash sequences like \t, \n,
and \\ to be stripped from post_content, post_title, and post_excerpt.

Wrap the data array with wp_slash() before calling wp_update_post() so
the backslashes survive the internal wp_unslash() call.

Adds a regression test using ReflectionMethod to invoke the protected
update_content() method and assert all three fields are preserved.

Fixes Automattic#46020

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ [Tests] Includes Tests labels May 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖



Jetpack plugin:

The Jetpack plugin has different release cadences depending on the platform:

  • WordPress.com Simple releases happen as soon as you deploy your changes after merging this PR (PCYsg-Jjm-p2).
  • WoA releases happen weekly.
  • Releases to self-hosted sites happen monthly:
    • Scheduled release: June 2, 2026
    • Code freeze: June 1, 2026

If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack.

@github-actions github-actions Bot added the OSS Citizen This Pull Request was opened by an Open Source contributor. label May 15, 2026
Gilmoursa and others added 2 commits May 15, 2026 14:17
factory()->post->create() calls wp_insert_post() directly, which calls
wp_unslash() internally (as it expects slashed $_POST-style input). Without
wp_slash() on the test data, PHP's stripslashes() strips backslashes from
the source post before it's even read, causing the assertion to compare
against a string with backslashes that was never stored. Wrap the factory
args with wp_slash() to match how WordPress normally receives post data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove multi-line description from docblock (PHPCS requires long
  descriptions to start with a capital letter)
- Guard setAccessible(true) behind PHP_VERSION_ID < 80100 since
  ReflectionMethod::setAccessible() is deprecated in PHP 8.5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Gilmoursa Gilmoursa merged commit 95432c6 into Automattic:trunk May 15, 2026
65 checks passed
@github-actions github-actions Bot added this to the jetpack/15.9 milestone May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OSS Citizen This Pull Request was opened by an Open Source contributor. [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ [Tests] Includes Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copy post strips "\" characters from post content

1 participant