[PR #1673] [MERGED] fix(javascript): recover Electron APIs through default imports and optional calls #4741

Closed
opened 2026-10-31 00:54:35 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1673
Author: @kaoru0822-kitauji
Created: 10/11/2026
Status: ✅ Merged
Merged: 10/11/2026
Merged by: @morluto

Base: main ← Head: fix/electron-default-import-optional-calls


📝 Commits (2)

  • f90b04a fix(javascript): recover Electron APIs through default imports and optional calls
  • 1559b03 Merge remote-tracking branch 'origin/main' into fix/electron-default-import-optional-calls

📊 Changes

5 files changed (+99 additions, -11 deletions)

View changed files

📝 src/domain/javascript/electronStaticAnalysisBrowser.ts (+3 -3)
➕ src/domain/javascript/electronStaticAnalysisIdentity.test.ts (+76 -0)
📝 src/domain/javascript/electronStaticAnalysisIpc.ts (+7 -6)
📝 src/domain/javascript/javascriptElectronMemberWrites.ts (+10 -0)
📝 src/domain/javascript/javascriptSemanticAnalysis.ts (+3 -2)

📄 Description

Summary

Follow-up to #1656 (fixed by 2612e474b). Three Electron API shapes on current main still report 0 findings with no limitation that names the miss:

Shape (otherwise identical to the control) main this PR
import electron from "electron"; electron.ipcMain.handle("ch:ping", …) main_handlers: 0 1
import electron from "electron"; const { ipcMain } = electron; ipcMain.handle(…) 0 1
import electron from "electron"; new electron.BrowserWindow(…) and electron.contextBridge.exposeInMainWorld(…) browser_windows: 0, context_bridge_apis: 0 1, 1
ipcMain?.handle(…), contextBridge?.exposeInMainWorld(…), utilityProcess?.fork(…) 0 1
if (!event.senderFrame?.url.startsWith("file://")) … inside a handler sender_validation_observations: 0 1

The default import is the pattern used by libraries such as electron-util and electron-store.

Causes

  • bindImports gives a default import the origin path ["default"], so the classifier produced ["default", "ipcMain"], which no Electron matcher accepts. Electron's CommonJS exports define no default member, so the segment can only mean the module object (the ES module default import of a CommonJS module is module.exports). The new electronExportPath drops the leading default only when the classifier returns an Electron path. The semantic IR keeps its exact ["default"] origin. electron.default.ipcMain still matches nothing.
  • classifyParsedJavaScriptElectronBindingsSteps already records OptionalCallExpression roots, and electronCalleePath walks OptionalMemberExpression. But the IPC, context-bridge, utility-process and sender-validation visitors accepted only CallExpression. Babel parses any call in a ?. chain, including event.senderFrame?.url.startsWith(x), as an OptionalCallExpression. So the existing optional-member branch in inspectValidationCall could never run for that chain.

Not changed: data-flow shapes the identity limitation already calls unresolved (let ipc; ipc = ipcMain, passing ipcMain as an argument, { ipc: ipcMain }.ipc, ipcMain || null, .bind). Bundler interop wrappers (__importDefault(require("electron")).default) remain unrecognized, as before.

Verification

  • New src/domain/javascript/electronStaticAnalysisIdentity.test.ts (2 tests). Both fail with the source changes stashed and pass with them.
  • npm run test:focused -- all 43 src/domain/javascript/*.test.ts files plus tests/composition/javascript-applications/electronApplicationAnalysis.test.ts: 808 passed.
  • tests/acceptance/applications/applicationWorkflowCli.test.ts (after build:cached): 31 passed.
  • npm run typecheck, npm run check:fast pass. jscpd stays at 2.489%.
  • Built CLI, analyze-javascript-application <dir> --artifact-format directory, compared main vs branch on the shapes in the table.

No Hopper/Ghidra involvement; no real Electron runtime execution.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1673 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/11/2026 **Status:** ✅ Merged **Merged:** 10/11/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/electron-default-import-optional-calls` --- ### 📝 Commits (2) - [`f90b04a`](https://github.com/morluto/rea/commit/f90b04ae0f21d0d6e93dc6c98ce66d966db93b6a) fix(javascript): recover Electron APIs through default imports and optional calls - [`1559b03`](https://github.com/morluto/rea/commit/1559b038f6ac468062078afd93aa9dfcf82bd0c1) Merge remote-tracking branch 'origin/main' into fix/electron-default-import-optional-calls ### 📊 Changes **5 files changed** (+99 additions, -11 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascript/electronStaticAnalysisBrowser.ts` (+3 -3) ➕ `src/domain/javascript/electronStaticAnalysisIdentity.test.ts` (+76 -0) 📝 `src/domain/javascript/electronStaticAnalysisIpc.ts` (+7 -6) 📝 `src/domain/javascript/javascriptElectronMemberWrites.ts` (+10 -0) 📝 `src/domain/javascript/javascriptSemanticAnalysis.ts` (+3 -2) </details> ### 📄 Description ## Summary Follow-up to #1656 (fixed by 2612e474b). Three Electron API shapes on current main still report `0` findings with no limitation that names the miss: | Shape (otherwise identical to the control) | main | this PR | |---|---|---| | `import electron from "electron"; electron.ipcMain.handle("ch:ping", …)` | `main_handlers: 0` | `1` | | `import electron from "electron"; const { ipcMain } = electron; ipcMain.handle(…)` | `0` | `1` | | `import electron from "electron"; new electron.BrowserWindow(…)` and `electron.contextBridge.exposeInMainWorld(…)` | `browser_windows: 0`, `context_bridge_apis: 0` | `1`, `1` | | `ipcMain?.handle(…)`, `contextBridge?.exposeInMainWorld(…)`, `utilityProcess?.fork(…)` | `0` | `1` | | `if (!event.senderFrame?.url.startsWith("file://")) …` inside a handler | `sender_validation_observations: 0` | `1` | The default import is the pattern used by libraries such as electron-util and electron-store. ## Causes - `bindImports` gives a default import the origin path `["default"]`, so the classifier produced `["default", "ipcMain"]`, which no Electron matcher accepts. Electron's CommonJS exports define no `default` member, so the segment can only mean the module object (the ES module default import of a CommonJS module is `module.exports`). The new `electronExportPath` drops the leading `default` only when the classifier returns an Electron path. The semantic IR keeps its exact `["default"]` origin. `electron.default.ipcMain` still matches nothing. - `classifyParsedJavaScriptElectronBindingsSteps` already records `OptionalCallExpression` roots, and `electronCalleePath` walks `OptionalMemberExpression`. But the IPC, context-bridge, utility-process and sender-validation visitors accepted only `CallExpression`. Babel parses any call in a `?.` chain, including `event.senderFrame?.url.startsWith(x)`, as an `OptionalCallExpression`. So the existing optional-member branch in `inspectValidationCall` could never run for that chain. Not changed: data-flow shapes the identity limitation already calls unresolved (`let ipc; ipc = ipcMain`, passing `ipcMain` as an argument, `{ ipc: ipcMain }.ipc`, `ipcMain || null`, `.bind`). Bundler interop wrappers (`__importDefault(require("electron")).default`) remain unrecognized, as before. ## Verification - New `src/domain/javascript/electronStaticAnalysisIdentity.test.ts` (2 tests). Both fail with the source changes stashed and pass with them. - `npm run test:focused --` all 43 `src/domain/javascript/*.test.ts` files plus `tests/composition/javascript-applications/electronApplicationAnalysis.test.ts`: 808 passed. - `tests/acceptance/applications/applicationWorkflowCli.test.ts` (after `build:cached`): 31 passed. - `npm run typecheck`, `npm run check:fast` pass. jscpd stays at 2.489%. - Built CLI, `analyze-javascript-application <dir> --artifact-format directory`, compared main vs branch on the shapes in the table. No Hopper/Ghidra involvement; no real Electron runtime execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:54:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4741
No description provided.