Repository navigation
Lengthen a code fence when the snippet contains one - #106
Merged
Merged
Conversation
When a snippet contained a bare fence line such as ```, sync wrote it inside the existing ``` fence. That line closed the block early, so the rest of the snippet landed in the document as Markdown (or raw HTML), check reported the block out of sync forever, and every sync appended another copy. renderBlock now picks a fence one longer than the longest bare run of the fence character in the new body (CommonMark's rule) and applies it to the opening and closing fence. Fences are never shortened, runs of the other fence character and runs followed by an info string don't count, and unclosed blocks get a longer opening fence only.
Split body lines on lone CRs too, keep a closing fence that is already long enough, rename helpers, and note fence lengthening in the README.
Owner
Author
Second-pass reviewTwo passes: an adversarial pass trying to break out of the block, and a standards pass. Adversarial: 47 hostile inputs through
Every CLI case gave exactly one code block whose content equals the snippet, a no-op second Fixed in e1c507a
Not changed (pre-existing, same on
CI green on Node 22 and 24; 317 tests pass locally. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A snippet containing a bare fence line (
```) broke out of its code block. Onmain, syncing thisa.jsinto a```js snippet=a.jsblock:writes the
<img>intoREADME.mdas raw HTML, outside any code block.checkthen reports the block out of sync forever, and everysyncappends another copy of the injected content. With remote snippets, whoever controls the URL controls that HTML.Fix
renderBlockinmarkdown-document.tsuses CommonMark's rule: when the new body contains a bare run of the fence character at least as long as the fence, both the opening and closing fence become one longer than the longest such run.\r\n,\ror\n, so a lone-CR body passed to the library API can't hide a fence line.~~~inside a```block is fine), and runs followed by an info string (```js) don't count because they can't close a block.Documents already corrupted by this bug aren't repaired: the injected text now sits outside the block as ordinary content and needs a manual cleanup.
Tests
markdown-document.test.ts: the injection case round-trips throughparse; one-longer-than-longest; other fence character ignored; info strings ignored; long-enough closing fence kept; lone\rline breaks; longer existing fence kept; nested in a list; unclosed block.cli.test.ts: syncing a Markdown snippet that contains a code block gives a 4-backtick fence. A secondsyncchanges nothing andcheckexits 0.main. The info-string and longer-existing-fence cases are regression guards that already pass there.syncmay lengthen a fence.Not covered: fences inside blockquotes. Rewritten blockquote bodies already lose their
>prefix (a known follow-up from #98), so a test there would lock in that bug.npm run lintand fixed any issues.npm run buildto verify the project builds.npm testto ensure all tests pass. (317 passed)