Skip to content

Decode the stored new-post prompt before using it as a placeholder - #271

Merged
lancewillett merged 2 commits into
masterfrom
fix/editor-placeholder-entities
Oct 26, 2026
Merged

lancewillett merged 2 commits into
masterfrom
fix/editor-placeholder-entities

Conversation

@bor0

@bor0 bor0 commented Oct 26, 2026

Copy link
Copy Markdown
Member

Proposed Changes

  • In o2Editor.getEditor(), decode the textarea's placeholder before setting it on the editor.
  • Add a QUnit test in tests/qunit/editor.js.

o2 saves a custom new-post prompt with esc_attr() (o2.php, front_side_post_prompt), so What's is stored as What&#039;s. The editor used to build the textarea from an HTML string, which decoded it. Since #252 the placeholder is set with .attr(), so the editor shows What&#039;s literally. The prompt is now decoded once through a detached <textarea>, which parses its content as text, so markup in a prompt still can't create elements.

Testing Instructions

  • Set the new-post prompt to something with an apostrophe and save it through the Customizer. On master the editor placeholder shows &#039;; on this branch it shows '.
  • npx grunt qunit passes. The new test fails without the fix.

🤖 Generated with Claude Code

Sites can store the new-post prompt entity-encoded (e.g. What&#39;s). The
editor used to build the textarea from an HTML string, which decoded it.
Since #252 the placeholder is set with .attr(), so the entity showed up
literally. Decode it once through a detached <textarea>, which parses its
content as text, so markup in the prompt can't create elements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bor0
bor0 requested a review from lancewillett October 26, 2026 11:00
@lancewillett

Copy link
Copy Markdown
Contributor

Blocker in js/editor/editor.js:158: jQuery .html() parses the string as live HTML when it contains <script, <style or <link, or starts with a table tag like <tr>. With jQuery 3.7.1, <style></style><img src=x onerror=…> runs its onerror handler.

Use $( '<textarea>' ).prop( 'innerHTML', … ).val() instead, and add a <style> case to the QUnit test. The current cases all take jQuery's safe path, so they can't catch this.

AI review · claude-opus-5-5

@lancewillett lancewillett left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Left a review comment with a few changes before we merge this.

jQuery's .html() appends a string containing <script, <style or <link
(or a leading table tag) instead of setting innerHTML, which builds live
elements even on a detached <textarea>. Set innerHTML on the textarea
directly so its content is always parsed as text, and read it back with
.val(). Add a <style> case to the test, which takes jQuery's append path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bor0
bor0 requested a review from lancewillett October 26, 2026 17:33
@lancewillett
lancewillett merged commit f289eda into master Oct 26, 2026
3 checks passed
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