mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 01:41:21 +00:00
* fix(javascript): require exact loader suffix case * fix(javascript): share exact loader mode across import resolution * test(process): align symlink fixture with filesystem checkpoints * test(javascript): normalize the module resolution oracle path separators * test(frida): assert the CLI spawn Evidence contract * test(mcp): use an unsupported analysis-view parent * test(browser): separate source-location line bounds from parity * fix(javascript): preserve uncertain loader provenance * test(javascript): cover uncertain require resolution * fix(javascript): retain conditional Electron evidence * fix(javascript): preserve timed semantic provenance * fix(javascript): retain conditional builtin effects * test(javascript): distinguish bundled host authority * fix(javascript): preserve nested loader invocation identity * test(javascript): qualify Electron fixture authority * fix(javascript): preserve loader invocation authority * fix(javascript): respect source order for resolver escapes * fix(javascript): check nested loader callable mutations * fix(javascript): retain conditional constructor requests * fix(reference): retain constructor loader relationships * fix(reference): follow nested loader callable paths * refactor(javascript): share callable mutation interpretation * fix(javascript): require exact package loader suffixes * refactor(javascript): unify conditional relation evidence * refactor(javascript): unify conditional node evidence * fix(javascript): retain unknown authority for mixed case sources * fix(javascript): preserve loader uncertainty for dotfiles * fix(reference): classify javascript suffix dotfiles * test(reference): cover suffix dotfiles through cli * fix(javascript): retain equivalent conditional built-in origins * fix(javascript): preserve wrapped resolver operation * fix(javascript): retain nested conditional built-in receivers * test(javascript): declare CommonJS in native addon fixtures * fix(javascript): retain wrapped resolver candidates * style: format merged native command schema * fix(javascript): preserve uncertain loader authority * test(javascript): require candidate preload evidence * test(javascript): cover reference loader member writes --------- Co-authored-by: ShuaixinHuang <1836656514@qq.com>
84 lines
3.0 KiB
TypeScript
84 lines
3.0 KiB
TypeScript
import { expect, it } from "vitest";
|
|
|
|
import { inspectElectronIpcNode } from "./electronStaticAnalysisIpc.js";
|
|
import { resolveElectronBrowserWindowReceiver } from "./electronStaticRenderer.js";
|
|
import { createJavaScriptRpcScan } from "./javascriptRpcEndpoints.js";
|
|
import {
|
|
indexJavaScriptBindingsWithReceiversSteps,
|
|
indexJavaScriptElectronIdentitySteps,
|
|
} from "./javascriptSemanticAnalysis.js";
|
|
import { createSemanticExpressionShapeResolver } from "./javascriptSemanticExpressionShapes.js";
|
|
import {
|
|
completeSemanticSteps as complete,
|
|
traverseJavaScriptAst,
|
|
} from "./javascriptSemanticTraversal.js";
|
|
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
|
|
import {
|
|
createJavaScriptAnalysisAccumulator,
|
|
type JavaScriptFindingContext,
|
|
} from "./javascriptStaticAnalysisState.js";
|
|
|
|
const inspect = (source: string, path?: string) => {
|
|
const file = parseJavaScriptSource(source, path);
|
|
if (file === null) throw new Error("Fixture must parse");
|
|
const index = complete(
|
|
indexJavaScriptBindingsWithReceiversSteps(file.program),
|
|
);
|
|
complete(index.indexAmbientWritesSteps());
|
|
const identity = complete(
|
|
indexJavaScriptElectronIdentitySteps(file.program, index.bindings),
|
|
);
|
|
let mutationIndexCalls = 0;
|
|
const original = index.indexMemberMutationFactsSteps.bind(index);
|
|
index.indexMemberMutationFactsSteps = function* () {
|
|
mutationIndexCalls += 1;
|
|
yield* original();
|
|
};
|
|
const context: JavaScriptFindingContext = {
|
|
source,
|
|
accumulator: createJavaScriptAnalysisAccumulator(source.length),
|
|
vitePreloadDependencyTable: null,
|
|
electronBindings: identity.bindings,
|
|
electronExportIntact: identity.intactExport,
|
|
rpcScan: createJavaScriptRpcScan(
|
|
source,
|
|
index.receivers.rpcClientRoots,
|
|
index,
|
|
),
|
|
expressionShapes: createSemanticExpressionShapeResolver(index.bindings),
|
|
browserWindowReceiver: (node, site, suffix) =>
|
|
resolveElectronBrowserWindowReceiver(node, site, suffix, context, index),
|
|
};
|
|
traverseJavaScriptAst(file, {
|
|
enter: (node) => inspectElectronIpcNode(node, context),
|
|
});
|
|
return { findings: context.accumulator.ipc, mutationIndexCalls };
|
|
};
|
|
|
|
it.each([
|
|
[
|
|
"ordinary EventEmitter",
|
|
`import {EventEmitter} from "node:events";
|
|
const emitter = new EventEmitter(); emitter.on("event", listener);`,
|
|
],
|
|
[
|
|
"unsupported BrowserWindow path",
|
|
`const {BrowserWindow} = require("electron");
|
|
const window = new BrowserWindow(); window.on("ready", listener);`,
|
|
],
|
|
])("does not request whole-file mutation facts for %s", (_, source) => {
|
|
const result = inspect(source);
|
|
expect(result.findings).toEqual([]);
|
|
expect(result.mutationIndexCalls).toBe(0);
|
|
});
|
|
|
|
it("still checks mutations for a source-proven scoped Electron receiver", () => {
|
|
const result = inspect(
|
|
`const {BrowserWindow} = require("electron");
|
|
const window = new BrowserWindow(); window.webContents.ipc.handle("channel", () => {});`,
|
|
"fixture.cts",
|
|
);
|
|
expect(result.findings).toHaveLength(1);
|
|
expect(result.mutationIndexCalls).toBeGreaterThan(0);
|
|
});
|