fix(markdown): restore extracted blocks verbatim so $& and $$ survive#5768
Open
husamemadH wants to merge 1 commit into
Open
fix(markdown): restore extracted blocks verbatim so $& and $$ survive#5768husamemadH wants to merge 1 commit into
husamemadH wants to merge 1 commit into
Conversation
The placeholder-restore pass in mdToHtml put code, math, mermaid and allowed-HTML blocks back with a string replacement, so String.replace read `$&`, `` $` ``, `$'` and `$$` in the *replacement* as substitution patterns. A fenced block containing them rendered corrupted: `$&` re-inserted the placeholder (`perl -pe 's/world/$& again/'` became `s/world/___CODE_BLOCK_0___amp; again/`), `` $` `` and `$'` spliced in the surrounding document, and `$$` collapsed to a single `$`. Pass a function replacer at all four sites, matching the inline-code site below them, which was already fixed this way. A function's return value is inserted verbatim with no `$` interpretation. The inline-code comment claimed `echo $1` would be read as a back-reference; with a string search value there are no capture groups, so `$1` is already literal. Reworded to name the four sequences that do corrupt. Fixes odysseus-dev#5663
Author
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
mdToHtmllifts fenced code, math, mermaid and allowed-HTML blocks out of the source and parks a placeholder (___CODE_BLOCK_0___) in their place so the markdown rules can't mangle them, then pastes each block back at the end. The paste used a string replacement:With a string replacement,
String.replacereads$&,$`,$'and$$in the replacement as substitution patterns. So a restored block containing any of them is corrupted:$&re-inserts the matched text — i.e. the placeholder itself$`and$'splice in everything before / after the placeholder$$collapses to a single$These are ordinary content in shell and perl snippets, so real code samples render wrong in chat, notes and documents. Reported in #5663.
This passes a function replacer at all four sites, matching the inline-code restore immediately below them which was already fixed this way. A function's return value is inserted verbatim, with no
$interpretation.Target branch
dev, notmain.Linked Issue
Fixes #5663
Type of Change
Checklist
devdocker compose up -d --build) and verified the change works end-to-end. Screenshots below.How to Test
Ask any model: "Write a one-line bash script using
$&and put it in a fenced sh code block."Before the fix, the rendered block shows the placeholder and an orphaned
amp;:(
$&is HTML-escaped to$&before the paste, so$&consumes the placeholder and leavesamp;behind.)After the fix the same prompt renders the snippet verbatim,
$&intact.Deterministic check without a model — DevTools console on the app:
Tests:
The four new tests were confirmed to fail against the unpatched
markdown.jsand pass with it.Note on the issue description
#5663 lists
$1among the corrupting sequences, and an existing comment on the inline-code restore saysecho $1would be treated as a back-reference. Neither is the case: with a string search value there are no capture groups, so JS leaves$1..$99literal. Verified both$1and$10pass through untouched. The four sequences that actually corrupt are$&,$`,$'and$$. The comment has been reworded accordingly; the fix itself is unchanged by this.Visual / UI changes
<pre><code>output.Screenshots
Before —
$&replaced by the placeholder, with the orphanedamp;:After — the snippet renders verbatim:
Files changed
static/js/markdown.js— function replacer at the allowed-HTML, math, mermaid and code restore sites; the shared explanation moved above the group since it now covers all five.tests/test_markdown_rendering_js.py— four regression tests:$&(the reported perl case),$`/$'silent deletion,$$collapsing, and the mermaid restore path.Disclosure
The patch was drafted with Claude Code. I reproduced the bug in my own instance, reviewed the change, and verified before/after in the running app. Flagging it per CONTRIBUTING.md's note on agent-generated PRs — this is a single targeted fix against an existing issue, not a bulk submission.