Skip to content

fix(markdown): escape double quotes in link href/title and image title#3590

Open
yashs33244 wants to merge 1 commit into
resend:canaryfrom
yashs33244:fix/markdown-escape-link-quotes
Open

fix(markdown): escape double quotes in link href/title and image title#3590
yashs33244 wants to merge 1 commit into
resend:canaryfrom
yashs33244:fix/markdown-escape-link-quotes

Conversation

@yashs33244

@yashs33244 yashs33244 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What

The Markdown renderer escapes double quotes in image src and alt, but not in link href, link title, or image title - those are interpolated raw into the attribute:

renderer.image = ({ href, text, title }) =>
  `<img src="${href.replaceAll('"', '&quot;')}" alt="${text.replaceAll('"', '&quot;')}"${
    title ? ` title="${title}"` : ''   // not escaped
  }…>`;

renderer.link = ({ href, title, tokens }) =>
  `<a href="${href}" target="_blank"${    // not escaped
    title ? ` title="${title}"` : ''      // not escaped
  }…>`;

So a markdown title that contains a double quote breaks out of the attribute:

[guide](https://example.com 'The "Complete" Guide')
-> <a … title="The "Complete" Guide" …>   // attribute terminates at the first "

The same happens for an image title and for an href that contains a quote.

Fix

Apply the same .replaceAll('"', '&quot;') already used for image src/alt to link href, link title, and image title. Added a regression test rendering a link and image whose title/href contain quotes. Existing snapshots are unaffected.


Summary by cubic

Escape double quotes in react-email’s Markdown renderer for link href/title and image title to prevent HTML attribute breakouts, matching the existing escaping for image src/alt. Adds a regression test that covers quotes in link/image titles and hrefs.

Written for commit 0aef517. Summary will update on new commits.

Review in cubic

Image src/alt were already escaped, but link href, link title, and
image title were interpolated raw. A title like 'The "Complete" Guide'
or an href with a quoted query value broke out of the attribute in the
rendered HTML. Escape them the same way.
Copilot AI review requested due to automatic review settings June 23, 2026 07:36
@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0aef517

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
react-email Patch
@react-email/editor Patch
@react-email/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@yashs33244 is attempting to deploy a commit to the resend Team on Vercel.

A member of the Team first needs to authorize it.

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Fixes an HTML attribute escaping bug in the Markdown renderer by applying the same replaceAll pattern already used for image src/alt to link href/title and image title. The change is small (3 files, 23 lines), isolated, test-covered, and does not affect any snapshots.

Re-trigger cubic

@github-actions github-actions Bot added the linear-synced PR has been synced to Linear label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

linear-synced PR has been synced to Linear

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants