fix(utils): stop comments from leaking into the excerpt - #12389
fix(utils): stop comments from leaking into the excerpt#12389pucedoteth wants to merge 4 commits into
Conversation
createExcerpt() removes HTML with a per-line `/<[^>]*>/` tag regex, which
cannot see a comment: it stops at the first ">", and it has no state to carry
an unterminated comment to the next line. So a document opening with a comment
excerpts the comment itself.
The excerpt becomes `description` in both the docs and blog plugins, so the
result is published in <meta name="description">, the Open Graph tags and the
blog feed. Comments are the syntax authors use for text addressed to editors
rather than readers, which makes this worse than cosmetic: a "<!-- TODO:
rewrite this page -->" note becomes the page's public description.
MDX's {/* ... */} form leaks the same way, and leaks even on a single line,
rendering as "{/ note /}" once the emphasis and heading-id rules have run.
Strip both forms with a small state machine that tracks the open delimiter
across lines. It runs after the inline-code escaping added in facebook#11821, so
comment syntax written inside inline code is already escaped by then and stays
intact.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Hi @pucedoteth! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
✅ [V2]
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎ Awaiting the start of a new Argos build… |
Motivation
createExcerpt()strips HTML with a per-line tag regex:That regex cannot see a comment. It stops at the first
>, and it has no state to carry an unterminated comment onto the next line. A document that opens with a comment therefore excerpts the comment itself:<!--Copyright (c) Meta Platforms, Inc.--><!--How to configure the sidebar.<!-- TODO: rewrite this pageonce v4 ships --><!-- TODO: rewrite this pageInstall the package.<!-- a > b -->b -->Some content.<!-- notemore --> Real text.<!-- noteReal text.MDX's
{/* ... */}form leaks the same way, and leaks even on a single line —{/* note */}comes out as{/ note /}once the emphasis and heading-id rules have run on it.This is not confined to the excerpt. Both content plugins fall back to it for the page description:
—
docs.tsandblogUtils.ts. So for any doc or blog post without an explicitdescriptionfront matter, the leaked comment is published in<meta name="description">, the Open Graph tags and the blog feed.That is what makes this more than cosmetic. Comments are precisely the syntax authors use for text addressed to editors rather than readers — license headers,
prettier-ignoremarkers, "do not translate", "TODO: rewrite this". Those are the strings that end up in the search snippet and the social preview.The fix
A small state machine strips both comment forms, tracking which delimiter is open so it survives across lines and so
{/*inside an HTML comment can't hijack a span that is already open.Placement matters: it runs after the inline-code escaping added in #11821.
escapeMDXalready escapes<,>,!,{and*, so by that point inline code cannot contain a literal<!--or{/*, and comment syntax written inside backticks stays intact for free. There's a test pinning that.Test Plan
8 tests added to the existing
createExcerptdescribe block. Reverting onlymarkdownUtils.tsand keeping the tests turns 5 of them red, with exactly the values in the table above:The other 3 pass before and after by design — they are regression guards for behaviour that is already correct: comment syntax inside inline code (#11821), comment syntax inside fenced code blocks, and a document that is nothing but a comment yielding no excerpt.
With the fix,
markdownUtils.test.tsis 92/92 and the wholedocusaurus-utilspackage is 407/408. The one failure isgitUtils.test.ts > rejects for cwd of untracked dir, which fails identically on a clean checkout here — it depends on whether the checkout's parent directory happens to be a git repo, and is unrelated to this change.oxfmtandeslintare clean on both changed files (the 3 remainingmax-lenwarnings inmarkdownUtils.tsare pre-existing, on the import/export comment block).🤖 Generated with Claude Code