Skip to content

size tilde code fences by the longest tilde run in commonmark renderer - #645

Merged
jgm merged 1 commit into
commonmark:masterfrom
zayeem06:tilde-fence-length
Oct 21, 2026
Merged

jgm merged 1 commit into
commonmark:masterfrom
zayeem06:tilde-fence-length

Conversation

@zayeem06

Copy link
Copy Markdown
Contributor

Tilde code fences can be closed by the code they contain

When a code block's info string contains a backtick, the commonmark renderer switches to a ~ fence, but it still picks the fence length from the longest run of backticks in the code. So a code block containing a ~~~ line gets written with a three-tilde fence, and that line closes the block early when the output is parsed again; everything after it is read as Markdown, so raw HTML that was inert inside the code block becomes live:

$ printf '~~~~~ a`b\n~~~\n<b>x</b>\n~~~~~\n' | cmark -t commonmark | cmark --unsafe
<pre><code class="language-a`b"></code></pre>
<b>x</b>
<pre><code></code></pre>

The fix makes the helper count runs of whichever fence character is used, so the fence comes out one longer than the longest tilde run. Backtick fences behave as before. I added a case to the render_commonmark api test. It fails without the change, and the full ctest suite (including roundtrip and an ASan/UBSan build) passes with it. Worth checking: I renamed longest_backtick_sequence to longest_char_sequence since it now takes the character; it has only this one caller.

When a code block's info string contains a backtick, the commonmark
renderer writes a tilde fence, but it still sized the fence from the
longest run of backticks in the code. A line of three or more tildes
inside the code then closes the fence early, and the rest of the code
block is parsed as Markdown when the output is read back.

Count runs of the fence character actually used.
@jgm
jgm merged commit 65d9644 into commonmark:master Oct 21, 2026
15 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