Slash post content before writing in publish-post - #211
Merged
Conversation
wp_update_post() and wp_insert_post() call wp_unslash() internally and expect slashed input. The body was passed unslashed, so every literal backslash was eaten on the way into the database. Prose was unaffected, which is why this went unnoticed. Posts carrying code were silently corrupted: escapes and regex backreferences such as \" \' \\ \n \b and \2 are load-bearing in preg_replace patterns and printf calls, and simply vanished. Applies wp_slash() to the body immediately before the write, covering the update and create paths in both the MCP tool and the CLI script. The slash lands after the transit-length guard so that guard still measures the real payload, and the post-write byte verification now round-trips instead of reporting a length mismatch. Fixes #210
Same defect as the body: wp_insert_post() unslashes its input, so a backslash in the title or meta description was dropped on write. Rare in practice, but the create path writes both fields today, so it is a live bug rather than a latent one.
Contributor
Author
|
Added a second commit: Same defect — |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #210.
Problem
publish-postpassedpost_contenttowp_update_post()/wp_insert_post()unslashed. Both callwp_unslash()internally and are documented as expecting slashed data, so every literal backslash in a draft was eaten on the way into the database.Prose posts were unaffected, which is why this survived review. Posts carrying code were silently corrupted:
\",\',\\,\n,\band backreferences like\2are load-bearing insidepreg_replacepatterns andprintf/sprintfcalls, and simply disappeared.Hit in practice on a WooCommerce MU-plugin post — 17701 bytes in, 17688 stored, the regex and format strings mangled beyond use.
Scope
Four call sites, both entry points, both the update and the create path:
mcp-server/src/tools/publishPost.tswp_update_post,wp_insert_postwp-cli/content-creation/publish-post.shwp_update_post,wp_insert_postCreating a new post was affected identically to updating one.
Fix
One
wp_slash( $body )per worker, placed after the transit-length guard and before either write, so a single statement covers both paths. Keeping it after the guard means that check still measures the real payload rather than the slashed one.Why the existing guards missed it
The transit check runs before the write:
The body arrived intact; the loss happened inside WordPress afterwards. The post-write byte verification did catch it — it reported the length mismatch that led here — but only as a generic count, with no hint that backslashes were the cause. With this change that verification round-trips instead of failing.
Verification
bash -n wp-cli/content-creation/publish-post.shpassestsc --noEmitpasses; the builtdist/tools/publishPost.jsemits$body = wp_slash( $body );intact (the worker is aString.rawliteral, so no escaping surprises)build_phpand linted withphp -lunder PHP 8.5 — valid, withwp_slashcorrectly placed ahead of both writes and$bodycorrectly unescaped through the heredocwp_slash()was already confirmed as the working counterpart out-of-band: writing the same content viawp evalwithwp_slash()applied stored 17153 bytes with all 16 backslashes preserved, byte-identical to sourceNot addressed here
On the update path
publish-postsets SEO meta, tags and terms but does not rewritepost_title, so a title typo survives an update that changes everything else. Noted at the end of #210; left alone since it may well be deliberate.