mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
d72d856f58
Resolve stable local constant BrowserWindow options with retained provenance and shared early-exit mutation queries. Preserve source ordering and unknown results for relevant mutations or escapes. Includes real Joplin correctness/cost receipts and regression coverage. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
399 lines
14 KiB
TypeScript
399 lines
14 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
|
|
|
|
describe("Electron constant option evidence", () => {
|
|
it("keeps mixed constant, inline and unresolved windows in construction order", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(
|
|
[
|
|
'const { BrowserWindow } = require("electron");',
|
|
"const options = { webPreferences: { sandbox: true } };",
|
|
"new BrowserWindow(options);",
|
|
"new BrowserWindow({ webPreferences: { sandbox: false } });",
|
|
"new BrowserWindow(dynamic);",
|
|
"new BrowserWindow(options);",
|
|
].join("\n"),
|
|
);
|
|
expect(
|
|
analysis.electron.browser_windows.map(
|
|
({ location }) => location.start.line,
|
|
),
|
|
).toEqual([3, 4, 5, 6]);
|
|
expect(
|
|
analysis.electron.browser_windows.map(
|
|
({ options_status }) => options_status,
|
|
),
|
|
).toEqual([
|
|
"object-literal",
|
|
"object-literal",
|
|
"dynamic",
|
|
// The first constructor already received this object; later contents
|
|
// remain unknown even though the declarations retain their source order.
|
|
"dynamic",
|
|
]);
|
|
});
|
|
|
|
it("resolves local constant options despite an unrelated option write", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron");
|
|
function open() {
|
|
const preferences = { nodeIntegration: true, contextIsolation: false };
|
|
const options = { webPreferences: preferences };
|
|
if (linux) options.icon = "icon.png";
|
|
new BrowserWindow(options);
|
|
}
|
|
`);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
options_status: "object-literal",
|
|
web_preferences_status: "object-literal",
|
|
web_preferences: [
|
|
{
|
|
name: "contextIsolation",
|
|
value: { status: "literal", value: false },
|
|
},
|
|
{
|
|
name: "nodeIntegration",
|
|
value: { status: "literal", value: true },
|
|
},
|
|
],
|
|
resolution_sources: [expect.any(Object), expect.any(Object)],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it.each([
|
|
"options.webPreferences.sandbox = false;",
|
|
"const alias = options.webPreferences; alias.sandbox = false;",
|
|
"mutate(options);",
|
|
"const { webPreferences: alias } = options; mutate(alias);",
|
|
"Object.assign(options, unknown);",
|
|
"const box = {}; box.options = options; box.options.webPreferences.sandbox = false;",
|
|
"options = replacement;",
|
|
])("keeps changed or escaped constant options unknown: %s", (mutation) => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron");
|
|
const options = { webPreferences: { sandbox: true } };
|
|
${mutation}
|
|
new BrowserWindow(options);
|
|
`);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
options_status: "dynamic",
|
|
web_preferences_status: "dynamic",
|
|
web_preferences: [],
|
|
preload_path: null,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it.each([
|
|
"new BrowserWindow(options); const options = { webPreferences: { sandbox: true } };",
|
|
"const options = alias; const alias = { webPreferences: { sandbox: true } }; new BrowserWindow(options);",
|
|
"const options = alias; const alias = options; new BrowserWindow(options);",
|
|
"const options = { webPreferences: { sandbox: true } }; { const options = unknown; new BrowserWindow(options); }",
|
|
"let options = { webPreferences: { sandbox: true } }; new BrowserWindow(options);",
|
|
])("does not invent a constant initializer: %s", (source) => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron"); ${source}
|
|
`);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
options_status: "dynamic",
|
|
web_preferences_status: "dynamic",
|
|
web_preferences: [],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("preserves constants selected before later mutation and resolves preload context", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron");
|
|
const original = { webPreferences: { preload: require("path").join(__dirname, "preload.js"), sandbox: true } };
|
|
const options = original;
|
|
new BrowserWindow(options);
|
|
original.webPreferences.sandbox = false;
|
|
`);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
options_status: "object-literal",
|
|
preload_path: "preload.js",
|
|
preload_resolution_context: "filesystem-expression",
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("Electron option evidence", () => {
|
|
it.each([
|
|
'({ webPreferences: { preload: "./preload.js", sandbox: true } } as const)',
|
|
'{ webPreferences: ({ preload: "./preload.js", sandbox: true } as const) }',
|
|
'{ webPreferences: { preload: "./preload.js" as const, sandbox: true } }',
|
|
])("unwraps type-only wrappers around inline options: %s", (options) => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
import { BrowserWindow } from "electron";
|
|
new BrowserWindow(${options});
|
|
`);
|
|
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
options_status: "object-literal",
|
|
web_preferences_status: "object-literal",
|
|
preload_path: "./preload.js",
|
|
preload_resolution_context: "module-specifier",
|
|
web_preferences: [
|
|
{
|
|
name: "preload",
|
|
value: { status: "literal", value: "./preload.js" },
|
|
},
|
|
{ name: "sandbox", value: { status: "literal", value: true } },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("keeps the final explicit preload and service name with unrelated keys", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow, utilityProcess } = require("electron");
|
|
new BrowserWindow({ webPreferences: { preload: "./kept.js", sandbox: true }, title: "App" });
|
|
utilityProcess.fork("./worker.js", [], { serviceName: "kept", cwd: "/app" });
|
|
`);
|
|
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.browser_windows[0]).toMatchObject({
|
|
preload_path: "./kept.js",
|
|
preload_resolution_context: "module-specifier",
|
|
web_preferences: [
|
|
{ name: "preload", value: { status: "literal", value: "./kept.js" } },
|
|
{ name: "sandbox", value: { status: "literal", value: true } },
|
|
],
|
|
});
|
|
expect(analysis.electron.utility_processes[0]).toMatchObject({
|
|
module_path: "./worker.js",
|
|
service_name: "kept",
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
["for initializer", 'for (var electron = require("electron"); false;) {}'],
|
|
["do body", 'do { var electron = require("electron"); } while (false);'],
|
|
])(
|
|
"recovers Electron bindings initialized unconditionally in a %s",
|
|
(_name, declaration) => {
|
|
const analysis = analyzeJavaScriptStaticSource(
|
|
`${declaration} new electron.BrowserWindow({webPreferences:{preload:"./preload.js"}});`,
|
|
);
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{ preload_path: "./preload.js" },
|
|
]);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
'for (; false;) { var electron = require("electron"); }',
|
|
'while (false) { var electron = require("electron"); }',
|
|
'if (flag) { for (var electron = require("electron"); false;) {} }',
|
|
])(
|
|
"keeps conditionally skipped loop declarations unresolved: %s",
|
|
(declaration) => {
|
|
const analysis = analyzeJavaScriptStaticSource(
|
|
`${declaration} new electron.BrowserWindow({});`,
|
|
);
|
|
expect(analysis.electron.browser_windows).toEqual([]);
|
|
},
|
|
);
|
|
|
|
it("does not read an audio or video preload attribute as a preload script", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
jsx("audio", { controls: true, preload: "metadata", src });
|
|
(0, React.createElement)(\`video\`, { preload: "auto" });
|
|
jsx("webview", { preload: "./guest.js" });
|
|
const options = { preload: "./preload.js" };
|
|
`);
|
|
|
|
expect(analysis.role_paths.map(({ path }) => path)).toEqual([
|
|
"./guest.js",
|
|
"./preload.js",
|
|
]);
|
|
});
|
|
|
|
it("keeps values unknown when a later computed key can override them", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow, utilityProcess } = require("electron");
|
|
new BrowserWindow({ webPreferences: { preload: "./maybe.js" }, [key]: null });
|
|
utilityProcess.fork("./worker.js", [], { serviceName: "maybe", [key]: null });
|
|
`);
|
|
|
|
expect(analysis.parse_status).toBe("partial");
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.limitations.join(" ")).toContain("remain unknown");
|
|
expect(analysis.electron.browser_windows[0]).toMatchObject({
|
|
preload_path: null,
|
|
preload_resolution_context: null,
|
|
web_preferences_status: "dynamic",
|
|
web_preferences: [],
|
|
});
|
|
expect(analysis.electron.utility_processes[0]).toMatchObject({
|
|
module_path: "./worker.js",
|
|
service_name: null,
|
|
});
|
|
});
|
|
|
|
it("keeps recovered templates with invalid escapes dynamic", () => {
|
|
const source = [
|
|
'const { BrowserWindow } = require("electron");',
|
|
"new BrowserWindow({ webPreferences: { sandbox: `",
|
|
String.raw`\unicode`,
|
|
"` } });",
|
|
].join("");
|
|
const analysis = analyzeJavaScriptStaticSource(source);
|
|
|
|
expect(analysis.parse_status).toBe("partial");
|
|
expect(analysis.parse_error_count).toBe(1);
|
|
expect(
|
|
analysis.electron.browser_windows[0]?.web_preferences,
|
|
).toContainEqual(
|
|
expect.objectContaining({
|
|
name: "sandbox",
|
|
value: expect.objectContaining({ status: "dynamic", value: null }),
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Electron empty option keys", () => {
|
|
describe.each([
|
|
["plain empty string", '[""]'],
|
|
["empty template", "[``]"],
|
|
["wrapped empty string", '["" as const]'],
|
|
])("unrelated %s option keys", (_label, key) => {
|
|
it("retains an earlier explicit webPreferences object", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron");
|
|
new BrowserWindow({
|
|
webPreferences: { preload: "./kept.js", sandbox: true },
|
|
${key}: true
|
|
});
|
|
`);
|
|
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
web_preferences_status: "object-literal",
|
|
preload_path: "./kept.js",
|
|
preload_resolution_context: "module-specifier",
|
|
web_preferences: [
|
|
{
|
|
name: "preload",
|
|
value: { status: "literal", value: "./kept.js" },
|
|
},
|
|
{ name: "sandbox", value: { status: "literal", value: true } },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("retains an earlier explicit preload within webPreferences", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow } = require("electron");
|
|
new BrowserWindow({ webPreferences: {
|
|
preload: "./kept.js", sandbox: true, ${key}: false
|
|
} });
|
|
`);
|
|
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
web_preferences_status: "object-literal",
|
|
preload_path: "./kept.js",
|
|
preload_resolution_context: "module-specifier",
|
|
web_preferences: [
|
|
{ name: "", value: { status: "literal", value: false } },
|
|
{
|
|
name: "preload",
|
|
value: { status: "literal", value: "./kept.js" },
|
|
},
|
|
{ name: "sandbox", value: { status: "literal", value: true } },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("retains an earlier explicit utility-process service name", () => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { utilityProcess } = require("electron");
|
|
utilityProcess.fork("./worker.js", [], {
|
|
serviceName: "kept", ${key}: true
|
|
});
|
|
`);
|
|
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.parse_status).toBe("complete");
|
|
expect(analysis.electron.utility_processes).toMatchObject([
|
|
{ module_path: "./worker.js", service_name: "kept" },
|
|
]);
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
["dynamic key", "[key]: null"],
|
|
["spread", "...options"],
|
|
])(
|
|
"keeps a preceding %s override unknown after an unrelated empty template key",
|
|
(_label, override) => {
|
|
const analysis = analyzeJavaScriptStaticSource(`
|
|
const { BrowserWindow, utilityProcess } = require("electron");
|
|
new BrowserWindow({
|
|
webPreferences: { preload: "./maybe.js" },
|
|
${override}, [\`\`]: true
|
|
});
|
|
new BrowserWindow({ webPreferences: {
|
|
preload: "./maybe.js", ${override}, [\`\`]: true
|
|
} });
|
|
utilityProcess.fork("./worker.js", [], {
|
|
serviceName: "maybe", ${override}, [\`\`]: true
|
|
});
|
|
`);
|
|
|
|
expect(analysis.parse_error_count).toBe(0);
|
|
expect(analysis.parse_status).toBe("partial");
|
|
expect(analysis.electron.browser_windows).toMatchObject([
|
|
{
|
|
web_preferences_status: "dynamic",
|
|
web_preferences: [],
|
|
preload_path: null,
|
|
preload_resolution_context: null,
|
|
},
|
|
{
|
|
web_preferences_status: "object-literal",
|
|
preload_path: null,
|
|
preload_resolution_context: null,
|
|
},
|
|
]);
|
|
expect(analysis.electron.browser_windows[1]?.web_preferences).toEqual(
|
|
expect.arrayContaining([
|
|
{
|
|
name: "",
|
|
value: { status: "literal", value: true, expression: null },
|
|
},
|
|
{
|
|
name: "preload",
|
|
value: { status: "literal", value: "./maybe.js", expression: null },
|
|
},
|
|
expect.objectContaining({
|
|
name: expect.stringMatching(/^\[(?:dynamic|spread)@/u),
|
|
value: expect.objectContaining({ status: "dynamic", value: null }),
|
|
}),
|
|
]),
|
|
);
|
|
expect(analysis.electron.utility_processes).toMatchObject([
|
|
{ module_path: "./worker.js", service_name: null },
|
|
]);
|
|
},
|
|
);
|
|
});
|