Skip to content

fix: keep trailing text on HTML block close line for PI, declarations, and CDATA - #3991

Merged
UziTech merged 1 commit into
markedjs:masterfrom
sarathfrancis90:fix-html-block-trailing-text
Jun 30, 2026
Merged

fix: keep trailing text on HTML block close line for PI, declarations, and CDATA#3991
UziTech merged 1 commit into
markedjs:masterfrom
sarathfrancis90:fix-html-block-trailing-text

Conversation

@sarathfrancis90

Copy link
Copy Markdown
Contributor

Description

While checking marked against the CommonMark spec I noticed that text following the closing delimiter of an HTML block on the same line is dropped from the block for type 3 (<?...?>), type 4 (<!...>), and type 5 (<![CDATA[...]]>).

CommonMark ends these blocks on the line containing the closing delimiter, and the entire line — including anything after the delimiter — is part of the raw HTML block. marked already handles this for type 2 comments (spec example 177 shows <!-- foo -->*bar* keeping *bar* as raw text), but rules 3–5 stopped right at the delimiter, so the trailing text got split off and reparsed.

For example:

<?php echo '>'; ?>*not emphasis*

rendered as:

<?php echo '>'; ?><p><em>not emphasis</em></p>

instead of leaving *not emphasis* inside the HTML block like the reference does.

Fix

The comment rule (2) already consumes the rest of the closing line with a trailing [^\n]*. I applied the same to rules 3, 4, and 5 so they consume to the end of the closing line before the newline.

Tests

Added test/specs/new/html_block_trailing_text.md covering all three block types. It fails on master and passes with this change. Full CommonMark/GFM spec suites, unit tests, lint, types, and the ReDoS check are all green, and the CommonMark conformance score is unchanged.

Contributor checklist

  • Tests pass (npm test)
  • Lint passes (npm run lint)
  • Added a test for the fixed behavior
…, and CDATA

CommonMark ends HTML blocks of types 3 (<?...?>), 4 (<!...>), and 5
(<![CDATA[...]]>) on the line that contains the closing delimiter, and
the whole of that line - including any text after the delimiter - is part
of the block (see spec example 177 for the type 2 comment equivalent).

marked already does this for comments via the trailing [^\n]* in rule 2,
but rules 3-5 stopped at the closing delimiter, so trailing text on the
same line was split off and reparsed as a paragraph. For example
'<?php ?>*x*' rendered the '*x*' as emphasis instead of leaving it inside
the raw HTML block.

Match the comment rule by consuming the rest of the closing line before
the newline. Added a new spec test covering all three block types.
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

@sarathfrancis90 is attempting to deploy a commit to the MarkedJS Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marked-website Ready Ready Preview, Comment Jun 12, 2026 2:36pm

Request Review

@UziTech UziTech left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice catch! Thanks for fixing this 💯

@UziTech
UziTech requested review from calculuschild and styfle June 16, 2026 06:20
@UziTech
UziTech merged commit bbb84c8 into markedjs:master Jun 30, 2026
8 checks passed
github-actions Bot pushed a commit that referenced this pull request Jul 9, 2026
## [18.0.6](v18.0.5...v18.0.6) (2026-07-09)

### Bug Fixes

* Avoid O(n^2) backtracking in inline link href regex ([#4013](#4013)) ([a009808](a009808))
* Fix ordered lists after blockquotes ([#4003](#4003)) ([33928d0](33928d0))
* keep trailing text on HTML block close line for PI, declarations, and CDATA ([#3991](#3991)) ([bbb84c8](bbb84c8))
UziTech pushed a commit that referenced this pull request Jul 14, 2026
…t regexes (#4014)

* fix: Avoid O(n^2) backtracking in HTML block close regex

The close branches end in `[^\n]*\n+`; the trailing `\n+` requires a
newline, so at EOF the close can't match and the engine retries every
split of the lazy `[\s\S]*?` before falling through to `$`, which is
O(n^2). `\n*` closes on first match and consumes identical text whenever
a trailing newline is present (the `[^\n]*` was added in #3991).

* fix: Avoid O(n^2) backtracking in tilde paragraph interrupt regex

The backtick branch is guarded by a lookahead but `~{3,}` isn't, and it
overlaps the following `[^\n]*`, so a long newline-less tilde run
backtracks quadratically. Since `~{3,}` is always followed by `[^\n]*`,
`~~~` matches the same strings without the overlap. The real fences
tokenizer is left untouched.
github-actions Bot pushed a commit that referenced this pull request Jul 21, 2026
## [18.0.7](v18.0.6...v18.0.7) (2026-07-21)

### Bug Fixes

* Avoid O(n^2) backtracking in HTML block close and tilde interrupt regexes ([#4014](#4014)) ([f945fc5](f945fc5)), closes [#3991](#3991)
* Avoid O(n^2) masked source rebuild in inline tokenizer ([#4017](#4017)) ([9154f8f](9154f8f))
* keep empty list after blockquote as a sibling block ([#4004](#4004)) ([3f144a0](3f144a0))
* preserve code spans adjacent to tildes ([#4012](#4012)) ([0de7188](0de7188))
* Recognize setext headings whose first line starts with # ([#4015](#4015)) ([f056437](f056437)), closes [#1](#1)
* treat a line of only tabs as a blank line between paragraphs ([#4007](#4007)) ([bc2f121](bc2f121))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants