Conversation
📝 WalkthroughWalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@package.json`:
- Line 62: The project depends on a vulnerable marked@3.0.8; update package.json
to use marked version >=4.0.10 (preferably the latest stable) and run your
package manager to refresh lockfiles so the new version is installed; then
verify the call site marked(...) in src/js/tabs/firmware_flasher.js still works
(adjust any breaking API changes if needed) and run the app/tests to ensure
release-note rendering and renderer performance are unaffected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1ec1c33a-e715-45ec-8256-97cfffb05696
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (1)
package.json
| "jquery-ui-npm": "1.12.0", | ||
| "lru_map": "^0.3.3", | ||
| "marked": "^2.0.7", | ||
| "marked": "3.0.8", |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What is the latest stable release of the marked npm package, and does marked 3.0.8 work with a bare marked(markdownString) call returning a synchronous string?
💡 Result:
The latest stable release of the marked npm package is 18.0.0, released on 2026-04-07. Marked 3.0.8 works with a bare marked(markdownString) call, which returns a synchronous HTML string. This API has been consistent since at least version 3.0.0 (2021), where marked is the default export functioning as the synchronous parser. The async: false default (since v4.1.0) ensures synchronous string output unless async extensions are used.
Citations:
- 1: https://github.com/markedjs/marked/releases
- 2: https://www.npmjs.com/package/marked
- 3: https://github.com/markedjs/marked
- 4: https://github.com/markedjs/marked/releases/tag/v3.0.0
- 5: https://marked.js.org/using_advanced
- 6: https://marked.js.org/
🏁 Script executed:
find . -name "firmware_flasher.js" -o -name "*firmware*flasher*" | head -20Repository: emuflight/EmuConfigurator
Length of output: 217
🌐 Web query:
GHSA-rrrm-qjm4-v8hf marked ReDoS block.def vulnerability
💡 Result:
GHSA-rrrm-qjm4-v8hf is a high-severity (CVSS 7.5) Regular Expression Denial of Service (ReDoS) vulnerability in the npm package 'marked' (a Markdown parser), corresponding to CVE-2022-21680. It affects versions < 4.0.10 and was patched in 4.0.10. The vulnerability is due to inefficient regular expression complexity (catastrophic backtracking) in the block.def regex, which can be triggered by specially crafted Markdown strings, such as [x]:${' '.repeat(1500)}x ${' '.repeat(1500)} x. This leads to denial of service by excessive CPU usage when processing untrusted input without time limits or worker threads. Impact: Anyone parsing untrusted Markdown with vulnerable versions of marked. Workarounds: Avoid untrusted Markdown or use worker threads with time limits. Official advisory last updated November 29, 2023. Upgrade to marked >= 4.0.10 to remediate.
Citations:
🌐 Web query:
GHSA-5v2h-r2cx-5xgj marked ReDoS inline.reflinkSearch vulnerability patched version
💡 Result:
GHSA-5v2h-r2cx-5xgj is a ReDoS (Regular Expression Denial of Service) vulnerability in the marked npm package due to inefficient regular expression complexity in inline.reflinkSearch, which can cause catastrophic backtracking on certain strings, leading to denial of service. Affected versions are marked < 4.0.10 (or < 4.0.9 per some sources). The patched version is 4.0.10.
Citations:
🏁 Script executed:
cat -n ./src/js/tabs/firmware_flasher.js | sed -n '60,85p'Repository: emuflight/EmuConfigurator
Length of output: 1634
marked@3.0.8 ships with known ReDoS advisories — upgrade to 4.0.10 or later.
Two published GitHub advisories affect marked versions prior to 4.0.10, including 3.0.8:
- GHSA-rrrm-qjm4-v8hf (CVE-2022-21680) — Regular expression denial of service via catastrophic backtracking in
block.def. - GHSA-5v2h-r2cx-5xgj (CVE-2022-21681) — Regular expression denial of service via catastrophic backtracking in
inline.reflinkSearch.
In this app, marked() is called on GitHub release notes in src/js/tabs/firmware_flasher.js (line 72). While the source is semi-trusted, a compromised or malicious release body could trigger catastrophic backtracking and hang the renderer. Upgrade to marked >= 4.0.10 to resolve both vulnerabilities (or jump to the latest 18.0.0).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` at line 62, The project depends on a vulnerable marked@3.0.8;
update package.json to use marked version >=4.0.10 (preferably the latest
stable) and run your package manager to refresh lockfiles so the new version is
installed; then verify the call site marked(...) in
src/js/tabs/firmware_flasher.js still works (adjust any breaking API changes if
needed) and run the app/tests to ensure release-note rendering and renderer
performance are unaffected.
There was a problem hiding this comment.
@coderabbitai, fine, but you will need to scour the codebase and offer compatibility upgrades to accommodate newer marked.
There was a problem hiding this comment.
🧩 Analysis chain
I'll scour the codebase for every marked usage and simultaneously check the breaking-change history so I can propose precise compatibility patches.
🏁 Script executed:
#!/bin/bash
echo "=== Files importing/requiring marked ==="
rg -rn --type=js "require.*['\"]marked['\"]|import.*['\"]marked['\"]" .
echo ""
echo "=== All lines calling marked() or using marked.* ==="
rg -rn --type=js "\bmarked\b" . -C2
echo ""
echo "=== package.json marked entry ==="
grep -n "marked" package.json
Length of output: 6392
🌐 Web query:
marked npm breaking changes v3 to v4 v5 v6 migration guide API changes
💡 Result:
marked (markedjs/marked) major-version migration highlights (v3 → v4 → v5 → v6)
v5 → v6 (6.0.0)
- Breaking: project migrated to TypeScript (expect TS types, build/packaging changes). [1]
v4 → v5 (5.0.0)
- Breaking: many options were deprecated (some later removed in newer majors). [2]
- Breaking: minimum supported Node.js is v18. [2]
v3 → v4 (4.0.0)
- I wasn’t able to pull the v4.0.0 tag notes within the remaining tool budget in this run, so I can’t reliably list v3→v4 breaking changes from primary sources here. (If you share your current marked v3 usage—options + any custom renderer/tokenizer code—I can provide a targeted checklist.)
Sources
- [1] marked v6.0.0 tag notes (Breaking: “Migrate to Typescript”). (github.com)
- [2] marked v5.0.0 tag notes (Breaking: “deprecate options”, “minimum supported node version v18”). (github.com)
Citations:
- 1: https://github.com/markedjs/marked/tags?after=v9.0.1
- 2: https://github.com/markedjs/marked/tags?after=v6.0.0
The marked call is aliased — I need to trace the import and check all HTML entry points and build scripts.
🏁 Script executed:
#!/bin/bash
echo "=== Top 30 lines of firmware_flasher.js ==="
head -30 ./src/js/tabs/firmware_flasher.js
echo ""
echo "=== Lines 60-90 of firmware_flasher.js ==="
sed -n '60,90p' ./src/js/tabs/firmware_flasher.js
echo ""
echo "=== HTML files that reference 'marked' ==="
rg -rn "marked" --type=html .
echo ""
echo "=== All JS requires/imports at top of firmware_flasher.js (first 60 lines) ==="
sed -n '1,60p' ./src/js/tabs/firmware_flasher.js
echo ""
echo "=== Build script references to marked ==="
rg -rn "marked" ./scripts/ 2>/dev/null || echo "(no scripts/ dir or no results)"
echo ""
echo "=== preload.js references to marked ==="
find . -name "preload.js" | xargs grep -l "marked" 2>/dev/null || echo "(none)"
echo ""
echo "=== Any JS file that assigns marked to a short variable ==="
rg -rn --type=js "= require\(['\"]marked['\"]|= marked\b|{.*marked.*}" . | head -30
echo ""
echo "=== firmware_flasher.js full content (first 150 lines) ==="
head -150 ./src/js/tabs/firmware_flasher.js
Length of output: 11507
🌐 Web query:
marked v4 breaking changes from v3 deprecated options async renderer
💡 Result:
marked v4 (from v3): breaking changes
- Converted to ESM. The default export was removed:
- Use
import { marked } from 'marked'(ESM) orconst { marked } = require('marked')(CJS). [1]
- Use
- Browser/script-tag build changed:
/lib/marked.jswas removed (use/marked.min.jsinstead). [1]- In a script tag, call
marked.parse(...)instead ofmarked(...). [1]
“Deprecated options” (what to expect around v4 → v5)
Starting in v5.0.0, marked began logging deprecation warnings (some are on by default) and recommends extensions instead, e.g.:
mangle→marked-mangleheaderIds/headerPrefix→marked-gfm-heading-idhighlight/langPrefix/callback→marked-highlight- plus
baseUrl,smartypants,xhtmlreplacements. [2]
(Those options are later listed as removed in the docs, with the same “use an extension / external lib” guidance.) [3]
Async renderer support (“async renderer”)
Marked’s async mode is not “async renderer methods”. Instead:
- Setting
async: truemakesmarked.parse()return a Promise, and marked will await asyncwalkTokensbefore rendering. [4]
So if you need async work (fetching, DB lookups, etc.), do it in walkTokens (or an extension’s walkTokens) with async: true, not by making renderer methods async. [4]
Example
import { marked } from 'marked';
marked.use({
async: true,
async walkTokens(token) {
if (token.type === 'link') {
// async work here
}
}
});
const html = await marked.parse(markdown);[4]
Sources
[1] marked v4.0.0 release notes (breaking changes) (github.com)
[2] marked v5.0.0 release notes (deprecated-option warnings + replacements) (github.com)
[3] marked “Using Advanced” options list (removed options + recommended replacements) (marked.js.org)
[4] marked docs: “Async Marked” (async: true + awaits walkTokens) (marked.js.org)
Citations:
- 1: https://github.com/markedjs/marked/releases/tag/v4.0.0
- 2: https://github.com/markedjs/marked/releases/tag/v5.0.0
- 3: https://marked.js.org/using_advanced
- 4: https://marked.js.org/using_pro
Good — I can see marked(formattedNotes) at line 72. Now let me inspect exactly how marked is loaded/exposed as a global in main.html.
🏁 Script executed:
#!/bin/bash
echo "=== main.html full content ==="
cat ./src/main.html
echo ""
echo "=== Check for any other HTML files that load marked ==="
fd -e html . | xargs grep -l "marked" 2>/dev/null
echo ""
echo "=== Anything named 'marked' in the libraries folder ==="
find . -path "*/libraries*marked*" -o -name "marked.js" -o -name "marked.min.js" 2>/dev/null | head -20
Length of output: 28726
@nerdCopter, I've traced every marked reference in the codebase. There is one call site and one loading point — both are simple to patch. Here is everything that needs to change for full compatibility with marked v4+ (through the current latest, 18.0.0):
Root cause of the incompatibility
In marked v4, the default export was removed. You must now use const { marked } = require('marked') (CJS) instead of treating the whole module as the function, and marked.parse(...) replaces the direct marked(...) call in script-tag contexts.
Change 1 — package.json
Bump to at least 4.0.10 (the ReDoS fix floor) or jump straight to latest:
- "marked": "3.0.8",
+ "marked": "^18.0.0",Change 2 — src/main.html
The current loader uses the v3 default-export pattern. In v4+ require('marked') returns the module object, not the function itself, so window.marked would be set to a plain object and the call in firmware_flasher.js would throw marked is not a function. Fix by destructuring:
try {
- window.marked = require('marked');
+ window.marked = require('marked').marked;
console.log('[OK] marked loaded');
} catch(e) {
console.error('ERROR: Failed to load marked:', e.message);
}Change 3 — src/js/tabs/firmware_flasher.js (line 72)
The preferred synchronous API from v4 onward is marked.parse(). The bare marked() call became the deprecated form, and marked.parse() is the consistent entry point across v4–v18.
var formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/emuflight/EmuFlight/pull/$1)');
- formattedNotes = marked(formattedNotes);
+ formattedNotes = marked.parse(formattedNotes);
$('div.release_info .notes').html(formattedNotes);Summary
| File | Change |
|---|---|
package.json |
3.0.8 → ^18.0.0 |
src/main.html |
require('marked') → require('marked').marked |
src/js/tabs/firmware_flasher.js |
marked(formattedNotes) → marked.parse(formattedNotes) |
No other files reference marked. Because the project sets no custom options, renderers, or extensions, there are no further deprecation concerns from marked v5's removed options (mangle, headerIds, highlight, etc.) — none of those are used here.
✏️ Learnings added
Learnt from: nerdCopter
Repo: emuflight/EmuConfigurator PR: 553
File: package.json:62-62
Timestamp: 2026-04-16T20:04:32.879Z
Learning: In emuflight/EmuConfigurator, `marked` is loaded as a global in `src/main.html` via `window.marked = require('marked').marked` (named CJS export, required for marked v4+). The single call site is `src/js/tabs/firmware_flasher.js` line 72, which uses `marked.parse(formattedNotes)` (preferred API from marked v4 onward). No custom options, renderers, or extensions are used. Upgrading past v3 requires exactly these two code changes plus the package.json version bump.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: nerdCopter
Repo: emuflight/EmuConfigurator PR: 0
File: :0-0
Timestamp: 2026-04-09T19:41:26.051Z
Learning: In emuflight/EmuConfigurator PR `#549`, the security concern about `nodeIntegration: true` / `contextIsolation: false` in `main.js` webPreferences was deliberately deferred. Migrating to `contextIsolation: true` + `contextBridge.exposeInMainWorld()` requires rewriting `src/support/preload.js` (currently assigns APIs directly to `window`/global), updating all renderer-side callers of `ipcRenderer`, `chrome.*` polyfills and injected Node APIs, plus comprehensive regression testing. Risk is considered low because only local `file://` content is loaded with no remote URLs. This hardening is tracked for a dedicated follow-up PR.
Learnt from: nerdCopter
Repo: emuflight/EmuConfigurator PR: 544
File: src/js/tabs/pid_tuning.js:1712-1714
Timestamp: 2026-03-09T14:03:45.141Z
Learning: Emuflight is a fork of Betaflight ~3.8.7. Emuflight's minimum API version is 1.40.0 — API versions below 1.40.0 (including 1.20.0) are never present in Emuflight firmware. Legacy semver checks like `semver.gte(CONFIG.apiVersion, "1.20.0")` in `src/js/tabs/pid_tuning.js` are dead code in Emuflight's context. Emuflight always has 3 PID profiles in its firmware lifetime.
Upgrade marked to the highest available 3.x release and validate markdown rendering for firmware release notes.
Summary by CodeRabbit