From 2cd42792e4b9424c14738e2bbfc981478539a144 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Tue, 18 Aug 2026 22:23:19 +0200 Subject: [PATCH 1/2] fix(echarts): replace every newline in the tooltip, not just the first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeQL alert #103 (js/incomplete-sanitization) on plots/bar-heart-rate-zones/implementations/javascript/echarts.js:55. `.replace("\n", " ")` with a string argument replaces only the first occurrence. Nothing renders differently today: every entry in zoneNames carries exactly one newline, so first-occurrence and all-occurrences agree. The defect is latent — a zone label gaining a second line break would render with a raw newline inside a tooltip's HTML. Worth fixing anyway, because the alert is real and the cost is one character. The file is pipeline output, so a regeneration of this spec will overwrite it. If the pattern recurs across the catalogue it belongs in the generation prompt rather than here; it appears exactly once today. Co-Authored-By: Claude Opus 5 (1M context) --- .../bar-heart-rate-zones/implementations/javascript/echarts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plots/bar-heart-rate-zones/implementations/javascript/echarts.js b/plots/bar-heart-rate-zones/implementations/javascript/echarts.js index 459ff9d930..e0d3f57108 100644 --- a/plots/bar-heart-rate-zones/implementations/javascript/echarts.js +++ b/plots/bar-heart-rate-zones/implementations/javascript/echarts.js @@ -52,7 +52,7 @@ chart.setOption({ formatter: (params) => { const idx = params[0].dataIndex; return ( - `${zoneNames[idx].replace("\n", " ")}
` + + `${zoneNames[idx].replace(/\n/g, " ")}
` + `Duration: ${minutes[idx]} min
` + `HR range: ${hrRanges[idx]}` ); From 9e5bc90c48d79eb1f37d6ed6a132359ac7bb8c8f Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Tue, 18 Aug 2026 22:33:17 +0200 Subject: [PATCH 2/2] docs(changelog): record the CodeQL fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The exemption in CLAUDE.md covers the plot pipeline's own output, not a manual fix to a generated file — and a resolved security alert is worth the line. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2f610e8ec..4108de0b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -232,6 +232,14 @@ aggregate instead: an italic *Catalog* line at the end of the version section an ### Fixed +- **CodeQL alert #103** — an ECharts tooltip called `.replace("\n", " ")` with a string argument, + which replaces only the first occurrence + (`plots/bar-heart-rate-zones/implementations/javascript/echarts.js`). Nothing renders differently + today, since every zone label carries exactly one newline; the defect is latent, and a label + gaining a second line break would put a raw newline inside the tooltip's HTML. The pattern occurs + exactly once across the catalogue — were it recurring it would belong in the generation prompt, + since `plots/` is pipeline output and a regeneration overwrites this file (#10480). + - **The bot analytics recorded nothing at all** — Plausible identifies crawler user agents and discards their events, so forwarding the real one guaranteed an empty dashboard. Verified against the live API: the same event sent as `Claude-User` never appears, sent as a browser agent it does,