Skip to content

Fix all open CodeQL alerts, clear report-ui typecheck debt, refresh README screenshots - #96

Merged
JosephMaynard merged 3 commits into
masterfrom
fix/codeql-alerts
Jul 24, 2026
Merged

JosephMaynard merged 3 commits into
masterfrom
fix/codeql-alerts

Conversation

@JosephMaynard

@JosephMaynard JosephMaynard commented Jul 24, 2026 •

Copy link
Copy Markdown
Owner

Closes out all 8 pre-existing open CodeQL alerts on master, plus batched quality work while we're spending a CodeRabbit review anyway.

CodeQL alerts

Alert Rule Fix
#7, #8 js/file-system-race (high) readInstallScriptFile / readInspectablePackageFile stat and read through one FileHandle, so the checked file and the read file cannot differ
#6 js/file-system-race (high) build-report.ts reads built assets with try/catch instead of exists-then-read
#3 js/log-injection (error-level) build-spdx error logging strips line breaks (same treatment that unblocked #95)
#1, #4 shell/command injection (medium) --open on Windows now uses rundll32 url.dll,FileProtocolHandler instead of cmd /c start, so the report path is never shell-parsed
#2 js/xss-through-dom (high) the results summary is built with DOM nodes, removing the innerHTML sink
#5 js/http-to-file-access (medium) vendored SPDX ids are validated against the strict SPDX charset before writing; alert dismissed as won't-fix — writing pinned upstream data to the generated file is the vendoring script's purpose

Genuine bug found along the way

Abbreviated packuments larger than 4 MiB failed the maintenance lookup — and typescript's is ~9 MiB, so any project depending on TypeScript got a "maintenance collection is partial" banner and an unknown maintenance chip. Packument fetches now allow 16 MiB.

Refactoring

  • report-ui typechecks cleanly for the first time (css module declaration, null narrowing in graphView, structural parameter type for buildWorkspaceFilterOptions).
  • New npm run typecheck covers both tsconfigs and runs as a CI step, so the debt can't come back.

Docs

README screenshots regenerated from a current report — the old ones still showed the retired SaaS "Upgrade this scan" banner. The new ones show the header stat chips (including the e18e Replacements count), the Maintenance column with the new drift tiers, and the current graph and detail views.

Testing

  • 189 unit tests pass, both typechecks clean, full build regenerated.
  • Report verified in-browser (screenshots are from that session).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved focus switching between graph elements and popovers.
    • Corrected the “showing X of Y” report summary rendering to use safe DOM updates.
    • Improved Windows report launching by using a file:// URL.
  • Quality Improvements
    • Added automated TypeScript typechecking in CI for both CLI and report UI (via a new typecheck script).
    • Improved report UI compatibility for CSS side-effect imports.
    • Hardened report building/SPDX generation and limited unusually large fetched package data.

…creenshots

CodeQL alerts (all 8 pre-existing open alerts addressed):
- js/file-system-race x3: readInstallScriptFile and readInspectablePackageFile
  now stat and read through a single FileHandle, and build-report.ts reads
  built assets directly with try/catch instead of exists-then-read.
- js/log-injection (build-spdx.ts): error messages are logged with line
  breaks stripped, matching the sanitizer form the query recognizes.
- js/shell-command-injection-from-environment + js/indirect-command-line-injection
  (cli.ts --open on Windows): replaced `cmd /c start` with
  `rundll32 url.dll,FileProtocolHandler` so the report path is never parsed
  by a shell.
- js/xss-through-dom (report-ui): the results summary is built with DOM
  nodes instead of innerHTML, removing the sink.
- js/http-to-file-access (build-spdx.ts): vendored SPDX ids are now
  validated against the strict SPDX charset before writing; the alert
  itself is dismissed as won't-fix since writing pinned upstream data to
  the generated file is the script's purpose.

Maintenance fix found along the way: abbreviated packuments over 4 MiB
(typescript's is ~9 MiB) failed the registry lookup and marked the whole
maintenance collector partial for any project using TypeScript. Packument
fetches now allow 16 MiB.

Refactoring/quality:
- report-ui now typechecks cleanly (css module declaration, null narrowing
  in graphView, structural param for buildWorkspaceFilterOptions) and a new
  `npm run typecheck` script covering both tsconfigs runs in CI.

Docs: README screenshots regenerated from a current report - the old ones
showed the retired SaaS upsell banner; the new ones show the maintenance
column with drift tiers, the header stat chips, and replacement counts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e4080015-2e1c-4692-bf91-a09c8b877f34

📥 Commits

Reviewing files that changed from the base of the PR and between d59d158 and aeb3edd.

📒 Files selected for processing (1)
  • scripts/build-report.ts

📝 Walkthrough

Walkthrough

Adds CI typechecking for the CLI and report UI, updates report UI behavior and generated assets, and hardens artifact reads, SPDX validation, filesystem inspection, network payload limits, and Windows report launching.

Changes

Report runtime and hardening

Layer / File(s) Summary
UI typecheck and runtime updates
package.json, .github/workflows/ci.yml, report-ui/*, src/workspaceFilter.ts, src/report-assets.ts
Adds root and report UI typechecks, declares CSS modules, updates report UI focus and summary rendering, narrows the workspace filter input type, and regenerates the embedded JavaScript bundle.
Build artifact and identifier validation
scripts/build-report.ts, scripts/build-spdx.ts
Reads optional report artifacts with try/catch, validates SPDX identifiers, and sanitizes multiline build errors.
Bounded local and network reads
src/aggregator.ts, src/runners/maintenanceSignals.ts
Uses shared file handles for inspected reads and limits abbreviated packument responses to 16 MiB.
Windows report launching
src/cli.ts
Uses rundll32 url.dll,FileProtocolHandler to open reports without shell argument parsing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: CodeQL fixes, report-ui typecheck work, and screenshot refreshes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/codeql-alerts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/build-report.ts`:
- Around line 50-70: Update the CSS and JS file handling around cssPath and
jsPath so each catch only treats an ENOENT filesystem error as the missing-asset
case. Rethrow all other errors, including permission, directory, disk, and write
failures, while preserving the existing warnings for genuinely missing
report.css or report.iife.js files.

In `@src/aggregator.ts`:
- Around line 2166-2176: Update the file-reading helper around handle, fs.open,
and handle.readFile to enforce the byte limit during reading rather than relying
only on stat.size: read at most maxBytes + 1 bytes (or use an equivalent hard
cap), reject the result when it exceeds the limit, and preserve the existing
undefined behavior for non-files and read errors. Apply this enforcement
consistently at both call sites using INSTALL_SCRIPT_MAX_BYTES and maxBytes.

In `@src/cli.ts`:
- Around line 1434-1438: Update the rundll32 invocation in the report-opening
flow to pass pathToFileURL(filePath).href instead of the raw normalizedPath,
ensuring Windows handles spaces, special characters, and UNC paths as a
canonical file URL. Add a Windows regression test covering a path with spaces
and special characters.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a7b3a40-f323-4f7a-b956-40d65e2ad014

📥 Commits

Reviewing files that changed from the base of the PR and between 80b5d20 and 626f508.

⛔ Files ignored due to path filters (8)
  • dist/aggregator.js is excluded by !**/dist/**
  • dist/cli.js is excluded by !**/dist/**
  • dist/report-assets.js is excluded by !**/dist/**
  • dist/runners/maintenanceSignals.js is excluded by !**/dist/**
  • docs/screenshot-01.jpg is excluded by !**/*.jpg
  • docs/screenshot-02.jpg is excluded by !**/*.jpg
  • docs/screenshot-03.jpg is excluded by !**/*.jpg
  • report-ui/dist/report.iife.js is excluded by !**/dist/**
📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • package.json
  • report-ui/env.d.ts
  • report-ui/graphView.ts
  • report-ui/main.ts
  • scripts/build-report.ts
  • scripts/build-spdx.ts
  • src/aggregator.ts
  • src/cli.ts
  • src/report-assets.ts
  • src/runners/maintenanceSignals.ts
  • src/workspaceFilter.ts

Comment thread scripts/build-report.ts
Comment thread src/aggregator.ts
Comment thread src/cli.ts Outdated
…e URL for rundll32

- build-report.ts rethrows any read/write error that is not ENOENT, so
  permission or disk failures fail the build instead of silently emitting
  empty assets.
- readHandleCapped enforces the per-file byte limit during the read
  (maxBytes + 1 hard cap), so a file growing after fstat cannot exceed it;
  both aggregator call sites use it.
- The Windows --open flow passes pathToFileURL(...).href to rundll32's
  FileProtocolHandler so spaces, special characters, and UNC paths survive
  its argument handling. No unit test added: the conversion is Node's own
  pathToFileURL and openInBrowser's only behavior is spawning a real
  process.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/build-report.ts (1)

69-75: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not treat write failures as missing JavaScript.

This catch covers both readFileSync and writeFileSync. If the read succeeds but the output directory disappears before the write, writeFileSync can throw ENOENT; the code then silently emits a report with empty JavaScript. Handle the read and write in separate blocks so only read-time ENOENT produces the missing-artifact warning.

🛠️ Proposed fix
 let jsContent = '';
+let jsReadSucceeded = false;
 try {
   jsContent = fs.readFileSync(jsPath, 'utf8');
-  jsContent = sanitizeMinifiedJs(jsContent);
-  fs.writeFileSync(jsPath, jsContent, 'utf8');
-  console.log(`✓ Read JS: ${jsPath} (${jsContent.length} bytes)`);
+  jsReadSucceeded = true;
 } catch (err) {
   if (!isMissingFile(err)) throw err;
   console.warn('Warning: report.iife.js not found, JS will be empty');
 }
+
+if (jsReadSucceeded) {
+  jsContent = sanitizeMinifiedJs(jsContent);
+  fs.writeFileSync(jsPath, jsContent, 'utf8');
+  console.log(`✓ Read JS: ${jsPath} (${jsContent.length} bytes)`);
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build-report.ts` around lines 69 - 75, Separate the read and write
operations in the JavaScript processing flow so the catch around fs.readFileSync
only suppresses read-time ENOENT via isMissingFile(err), while failures from
fs.writeFileSync propagate normally. Preserve the existing missing-artifact
warning behavior for absent input files and ensure successful reads are still
sanitized, written, and reported.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/build-report.ts`:
- Around line 69-75: Separate the read and write operations in the JavaScript
processing flow so the catch around fs.readFileSync only suppresses read-time
ENOENT via isMissingFile(err), while failures from fs.writeFileSync propagate
normally. Preserve the existing missing-artifact warning behavior for absent
input files and ensure successful reads are still sanitized, written, and
reported.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d344d9fd-eaaf-49fa-ab4a-2593831f7f0b

📥 Commits

Reviewing files that changed from the base of the PR and between 626f508 and d59d158.

⛔ Files ignored due to path filters (2)
  • dist/aggregator.js is excluded by !**/dist/**
  • dist/cli.js is excluded by !**/dist/**
📒 Files selected for processing (3)
  • scripts/build-report.ts
  • src/aggregator.ts
  • src/cli.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/cli.ts
  • src/aggregator.ts

A write-time failure inside the same try was misreported as a missing
input artifact; sanitize/write errors now propagate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JosephMaynard
JosephMaynard merged commit 2da233f into master Jul 24, 2026
5 checks passed
@JosephMaynard
JosephMaynard deleted the fix/codeql-alerts branch July 24, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant