0.9.29#442
Merged
Merged
Conversation
…; improve MathJax 4 performance WaveDrom (shd101wyy/vscode-markdown-preview-enhanced#2315): - Replace window.eval with JSON5.parse in renderWavedrom() to prevent arbitrary code execution from user-controlled fenced code blocks - JSON5.parse safely handles unquoted keys, comments, trailing commas, and single-quoted strings without executing code Bitfield: - Replace interpretJS (vm.runInNewContext) with JSON5.parse in renderBitfield() — bitfield register definitions are purely data MathJax 4 (shd101wyy/vscode-markdown-preview-enhanced#2312): - Disable enableAssistiveMml, enableMenu, enableExplorer in default MathJax 4 config to reduce per-formula overhead - Remove redundant typesetClear() and texReset() calls before typesetPromise() since DOM is freshly rebuilt on every render
WaveDrom (#2315): the previous fix only patched the live-preview path. The
bundled WaveDrom.ProcessAll()/eva() helpers used in presentation mode and HTML
export still eval'd <script type="WaveDrom"> content, and that script can be
injected via raw HTML in markdown. Move the defense to the trust boundary: the
HTML sanitizer (server + client) now validates and normalizes every WaveDrom
data script to inert strict JSON via a shared normalizeWavedromSource() helper
(escaping `<` to prevent </script> breakout, dropping non-data scripts), so no
downstream eval can execute attacker-controlled JavaScript.
MathJax (#2312): the prior config (enableAssistiveMml/enableMenu/enableExplorer)
gave ~0 speedup — MathJax ignores those flags in the config block, and
assistiveMml is already off by default. The real cost is a11y semantic
enrichment (speech-rule-engine), ~890ms vs ~42ms for 127 formulas in Chrome
(~21x). Disable it via options.enableEnrichment:false, re-applied onto the live
MathDocument through a startup.ready hook (buildMathJaxConfigScript), since the
config-block flag is otherwise reset during startup. Users can opt back in.
Also restore typesetClear()/texReset() in the webview: dropping them leaked
MathJax's internal math list across re-renders and broke equation numbering
("Label multiply defined").
Tests:
- unit: normalizeWavedromSource, sanitizer WaveDrom normalization,
buildMathJaxConfigScript, getDefaultMathjaxConfig
- browser (Playwright, new `pnpm test:browser` + CI job): MathJax equation
numbering across re-renders, enrichment-disabled-by-default/opt-in, and the
WaveDrom security fix exercised through the real eval-based ProcessAll path
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… filenames Reported by @byte16384: openFile() opened external/unsupported link targets with child_process.exec(`start ${href}`), which runs through cmd.exe. The href comes from the markdown file and is URL-decoded, so a crafted link like [x](mailto:a%26%20calc.exe) decoded to `mailto:a& calc.exe` and cmd.exe ran `calc.exe` as a second command — one-click RCE on Windows. - openFile(): spawn via execFile('explorer.exe', [target]) (no shell) so the target is always one uninterpreted argument; `open --` on macOS to block option injection. - Similar sinks: the diagram `filename` attribute flows into converters that shell out (ImageMagick via imagemagick-cli's child_process.exec; mermaid-cli spawned with shell:true). Added sanitizeImageFilename() (allowlist + no path traversal) applied where filenames are resolved in process-graphs. - pdf2svg (@import of a .pdf, auto-rendered on preview) no longer spawns with shell:true / manual quoting. Tests: test/command-injection.test.ts covers the byte16384 PoC (no shell, href passed as a single arg) across win32/darwin/linux, plus sanitizeImageFilename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Promote the [Unreleased] CHANGELOG section to [0.9.29] and bump package.json. Includes the WaveDrom eval RCE fix (#2315), MathJax 4 enrichment performance fix (#2312), and the Windows command-injection fix for clicked preview links and diagram filenames (reported by @byte16384). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…x shell)
From code review of fix/wavedrom-security:
- normalizeWavedromSource: reject non-finite numbers (Infinity/NaN/-Infinity)
instead of letting JSON.stringify silently coerce them to `null`, and reject
top-level array roots (WaveDrom roots must be objects). Drops the diagram
rather than rendering corrupted data.
- latex.ts: drop `shell: true` + manual quoting, matching the pdf2svg fix.
`latexEngine` comes from the `latex_engine` code-chunk attribute
(attacker-controlled markdown); spawning without a shell prevents command
chaining. Code-chunk execution remains gated behind enableScriptExecution.
- tests: cover Infinity/NaN and array-root rejection; fix a mislabeled
wavedrom-parser test ("backtick" -> "arrow-function IIFE").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avoid publishing exploit details (decoded payload / mechanism) before users have updated; keep the entry to the mitigation and the credit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace [@user](https://github.com/user) links with plain @user tags. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The owner/repo#num shorthand doesn't autolink in a rendered Markdown file; use [vscode-mpe#NNNN](…/issues/NNNN) to match the existing CHANGELOG style. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sanitizeImageFilename previously rejected a leading `/`, treating it as an absolute path. But in MPE `/xxx` is the project-root-relative convention (same as imageFolderPath, e.g. default `/assets`), not a filesystem-absolute path. - sanitizeImageFilename: allow a leading `/`; keep the shell-safe allowlist and the `..`-traversal rejection (so the path stays inside the root). - process-graphs: new resolveOutputImagePath() resolves a leading-`/` name against projectDirectoryPath (via `'.' + name`), else against the image output dir — mirroring markdown-convert's imageFolderPath handling. This also fixes the latent bug where `path.resolve(imageDir, '/x.png')` wrote to the filesystem root instead of the project root. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…I allowlist)
The previous ASCII-only allowlist (^[A-Za-z0-9_./-]+$) silently rejected
non-English filenames like 图表.png or schéma.png, falling back to an
auto-generated name. Unicode letters have no shell meaning, so the security
goal is to block shell metacharacters, not non-ASCII letters.
Switch to a denylist: reject shell metacharacters, quotes, whitespace, the
backslash, and Unicode control/format chars (\p{C}, e.g. NUL / RTL override),
plus the existing `..` traversal check. Everything else — including CJK and
accented Latin — is allowed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the UNSAFE_IMAGE_FILENAME_CHARS const above the JSDoc so the doc comment sits directly on the function (no behavior change). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
No description provided.