Files
rea/src/domain/javascript/electronStaticAnalysisIdentity.test.ts
T
2a9fdde5db fix(javascript): retain stable declarations and bound intrinsic writes
Keep repeated variable declarations with one unconditional initializer while
rejecting assignments, conditional initialization and multiple values.
Normalize known intrinsic calls, aliases and bound argument prefixes at the
semantic owner, retaining opaque targets without tainting unused bindings or
fresh local objects. Cover both regressions through source and CLI/MCP tests.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-11 16:25:15 +00:00

173 lines
6.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
describe("Electron API identity", () => {
it("recovers APIs through an ES module default import of Electron", () => {
const analysis = analyzeJavaScriptStaticSource(`
import electron from "electron";
const { ipcMain } = electron;
new electron.BrowserWindow({ webPreferences: { preload: "./preload.js" } });
electron.contextBridge.exposeInMainWorld("api", { ping: true });
electron.ipcRenderer.invoke("default:ping");
ipcMain.handle("destructured:ping", () => "pong");
electron.default.ipcMain.handle("nested-default", () => "local");
`);
expect(analysis.electron.browser_windows).toMatchObject([
{ preload_path: "./preload.js" },
]);
expect(analysis.electron.context_bridge_apis).toMatchObject([
{ api_key: "api", members: ["ping"] },
]);
expect(
analysis.electron.ipc.map(({ side, operation, channel }) => ({
side,
operation,
channel,
})),
).toEqual([
{ side: "renderer", operation: "invoke", channel: "default:ping" },
{ side: "main", operation: "handle", channel: "destructured:ping" },
]);
});
it("recovers APIs and sender checks written with optional chaining", () => {
const analysis = analyzeJavaScriptStaticSource(`
const { contextBridge, ipcMain, utilityProcess } = require("electron");
contextBridge?.exposeInMainWorld("api", {});
utilityProcess?.fork("./worker.js");
ipcMain?.handle("optional:ping", (event) => {
if (!event.senderFrame?.url.startsWith("file://")) return null;
return event.sender?.getURL() === "file:///index.html";
});
`);
expect(analysis.electron.context_bridge_apis).toMatchObject([
{ api_key: "api" },
]);
expect(analysis.electron.utility_processes).toMatchObject([
{ module_path: "./worker.js" },
]);
expect(analysis.electron.ipc).toMatchObject([
{ side: "main", operation: "handle", channel: "optional:ping" },
]);
expect(
analysis.electron.sender_validations.map(
({ subject, mechanism, expected }) => ({
subject,
mechanism,
expected: expected.value,
}),
),
).toEqual([
{
subject: "sender-url",
mechanism: "call:startsWith",
expected: "file://",
},
{
subject: "sender-url",
mechanism: "comparison:===",
expected: "file:///index.html",
},
]);
});
it("follows bundler namespace interop helpers without accepting other writes", () => {
const analysis = analyzeJavaScriptStaticSource(`
var __toESM = (mod) => mod;
var __importStar = (mod) => mod;
let electron = require("electron");
electron = __toESM(electron);
new electron.BrowserWindow({ webPreferences: { preload: "./rolldown.js" } });
var import_electron = __toESM(require("electron"));
new import_electron.BrowserWindow({ webPreferences: { preload: "./esbuild.js" } });
function _interopRequireWildcard(mod) { return mod; }
const Electron = __importStar(require("electron"));
new Electron.BrowserWindow({ webPreferences: { preload: "./tsc.js" } });
let replaced = require("electron");
replaced = __toESM(require("./fake"));
new replaced.BrowserWindow({ webPreferences: { preload: "./replaced.js" } });
let rewritten = require("electron");
rewritten = __toESM(rewritten);
rewritten = fake;
new rewritten.BrowserWindow({ webPreferences: { preload: "./rewritten.js" } });
const babel = _interopRequireWildcard(require("electron"));
new babel.BrowserWindow({ webPreferences: { preload: "./babel.js" } });
function nested() {
const __toESM = (mod) => mod;
const scoped = __toESM(require("electron"));
new scoped.BrowserWindow({ webPreferences: { preload: "./nested.js" } });
}
`);
expect(
analysis.electron.browser_windows.map(({ preload_path }) => preload_path),
).toEqual(["./rolldown.js", "./esbuild.js", "./tsc.js", "./babel.js"]);
});
it("does not trust unbound helper names or non-function helper values", () => {
const analysis = analyzeJavaScriptStaticSource(`
const __toESM = makeLookalike();
const electron = __toESM(require("electron"));
new electron.BrowserWindow({});
let unbound = require("electron");
unbound = __importStar(unbound);
new unbound.BrowserWindow({});
`);
expect(analysis.electron.browser_windows).toEqual([]);
});
it("follows stable declaration aliases but not an assigned default parameter", () => {
const analysis = analyzeJavaScriptStaticSource(`
const direct = require("electron");
const constAlias = direct;
new constAlias.BrowserWindow({webPreferences:{preload:"./const.js"}});
let letAlias = require("electron");
new letAlias.BrowserWindow({webPreferences:{preload:"./let.js"}});
const { BrowserWindow } = require("electron");
new BrowserWindow({webPreferences:{preload:"./destructured.js"}});
function withDefault(electron = require("./not-electron")) {
if (flag) electron = require("electron");
new electron.BrowserWindow({webPreferences:{preload:"./default.js"}});
}
`);
expect(
analysis.electron.browser_windows.map(({ preload_path }) => preload_path),
).toEqual(["./const.js", "./let.js", "./destructured.js"]);
});
it("preserves one initializer across variable redeclarations without accepting writes", () => {
const analysis = analyzeJavaScriptStaticSource(`
var electron;
var electron = require("electron");
var electron;
new electron.BrowserWindow({webPreferences:{preload:"./redeclared.js"}});
var replaced;
var replaced = require("electron");
replaced = fake;
new replaced.BrowserWindow({webPreferences:{preload:"./replaced.js"}});
var initializedTwice = require("electron");
var initializedTwice = fake;
new initializedTwice.BrowserWindow({});
var conditional;
if (flag) { var conditional = require("electron"); }
new conditional.BrowserWindow({});
`);
expect(
analysis.electron.browser_windows.map(({ preload_path }) => preload_path),
).toEqual(["./redeclared.js"]);
});
});