Skip to content

fix(codeql): close remaining 6 alerts — fs races + dead code#54

Merged
Manavarya09 merged 1 commit intomainfrom
fix/codeql-remaining
May 3, 2026
Merged

fix(codeql): close remaining 6 alerts — fs races + dead code#54
Manavarya09 merged 1 commit intomainfrom
fix/codeql-remaining

Conversation

@Manavarya09
Copy link
Copy Markdown
Owner

Summary

Closes the last 6 open CodeQL alerts on `main`.

High — `js/file-system-race`

# File Fix
#70 `src/sync.js` `updateIfExists()` rewritten with `openSync('r+')` → `ftruncateSync` → `writeSync` through one fd. Atomically requires-existing-file + acquires write descriptor; no TOCTOU window. ENOENT semantics verified.
#71 `src/studio.js` Static-file handler dropped the redundant `statSync` — `readFileSync` already surfaces ENOENT/EISDIR/EACCES which we catch. One syscall, no race.

Note — `js/unused-local-variable` (dead code)

# File Removed
#76, #77 `src/chat.js` `hexToRgb`, `rgbToHex` helper functions — never called
#74, #75 `website/app/components/HeroExtractor.js` `copied` state + `handleCopyMarkdown` callback — never wired into JSX

Test plan

  • `npm test` — 336/336 pass
  • All modules import-load cleanly
  • Manual repl test: `openSync('r+')` correctly throws ENOENT on missing file, truncates + writes on existing file
  • Vercel preview will exercise the studio handler at runtime

After this lands, the open CodeQL alert count should drop from 6 → 0.

🤖 Generated with Claude Code

Closes the last 6 open CodeQL alerts on main.

HIGH — js/file-system-race (two TOCTOU windows):

- src/sync.js #70 — updateIfExists() previously did
  `if (statSync(path).isFile()) writeFileSync(...)`. The window between
  stat and write was exploitable on shared filesystems. Replaced with
  `openSync(path, 'r+')` which atomically requires-existing-file +
  acquires a write descriptor in one syscall, then ftruncate + writeSync
  through that fd. Verified ENOENT semantics with a quick repl test.

- src/studio.js #71 — the local studio's static-file handler did
  `if (statSync(p).isFile()) readFileSync(p)`. The stat was redundant —
  readFileSync surfaces ENOENT / EISDIR / EACCES on its own and we catch
  all of them. Dropped the stat; now one syscall, no race.

NOTE — js/unused-local-variable (dead code):

- src/chat.js #76, #77 — hexToRgb / rgbToHex helpers were defined but
  never called. Color ops in chat.js work directly on hex strings.
- website/app/components/HeroExtractor.js #74, #75 — `copied` state and
  `handleCopyMarkdown` callback were a never-wired feature (no JSX call
  site). Deleted both. If we want a "Copy markdown" button later, that's
  feature work, not cleanup.

336/336 tests pass. All touched modules import-load cleanly.
Copilot AI review requested due to automatic review settings May 3, 2026 07:36
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment May 3, 2026 7:37am

@Manavarya09 Manavarya09 merged commit 92b7670 into main May 3, 2026
3 of 4 checks passed
@Manavarya09 Manavarya09 deleted the fix/codeql-remaining branch May 3, 2026 07:36
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to clear the remaining CodeQL alerts by removing dead code and hardening two filesystem access paths against check-then-use races. In the broader codebase, these changes affect the CLI sync workflow, the local studio server’s static file serving, and the website extractor UI component.

Changes:

  • Reworked src/sync.js to update existing output files through a single opened file descriptor instead of a stat + write sequence.
  • Simplified src/studio.js static file serving by removing a redundant statSync before readFileSync.
  • Removed unused helper/state code from src/chat.js and website/app/components/HeroExtractor.js.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
website/app/components/HeroExtractor.js Removes unused clipboard-related state and callback from the extractor UI.
src/sync.js Replaces the previous existence-check/write flow with fd-based truncate/write logic for sync output files.
src/studio.js Simplifies static file reads to avoid a stat/read race window.
src/chat.js Deletes unused color conversion helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/sync.js
Comment on lines +20 to +21
ftruncateSync(fd, 0);
writeSync(fd, content, 0, 'utf-8');
Comment thread src/sync.js
Comment on lines +11 to +15
// Race-free "update only if file exists" — open with 'r+' atomically
// requires an existing file (throws ENOENT otherwise) and gives us a
// write-capable descriptor in one syscall, eliminating the toctou window
// that statSync→writeFileSync would have. Truncate then write through the
// same fd so no other process can sneak between check and write.
akasaj-uet pushed a commit to akasaj-uet/design-extract that referenced this pull request May 4, 2026
Closes 8 CodeQL js/unused-local-variable alerts. All deletions are pure
import-list trims — no runtime behavior changes:

  src/history.js          -- existsSync          (Manavarya09#72)
  src/sync.js             -- readFileSync        (#73)
  src/visual-diff.js      -- basename            (Manavarya09#62)
  src/index.js            -- formatAnatomyStubs  (Manavarya09#57; still re-exported)
  src/index.js            -- formatMotionTokens  (Manavarya09#58; still re-exported)
  src/formatters/tailwind.js   -- rgbToHex       (Manavarya09#54)
  src/formatters/vue-theme.js  -- rgbToHsl       (Manavarya09#55)
  src/formatters/css-vars.js   -- pxToRem        (Manavarya09#52)
  tests/wide-gamut.test.js -- oklchToSrgb, oklabToSrgb (Manavarya09#64)

Confirmed via grep that none of the removed names had call sites in
their source file. The two src/index.js entries still appear as
`export { … } from '…'` re-exports on lines 201–202 — those are
self-contained re-exports, not affected by the removed imports.

Skipped intentionally:
- Unused functions (Manavarya09#66Manavarya09#69, Manavarya09#61, #76–#77) — may be retained as
  internal API surface; need per-call review.
- File-system race conditions (Manavarya09#70, Manavarya09#71) in sync.js / studio.js — real
  bugs, but need a dedicated atomic-write fix, not in scope.

336/336 tests pass; all touched modules load cleanly.
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.

2 participants