fix(javascript): preserve loader authority for exact suffixes (#9477)

* 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>
This commit is contained in:
morlutoandShuaixinHuang authored and GitHub committed 2026-11-09 13:21:24 +08:00
1 parent 78a84d75c0
commit b46f4fcebd
112 files changed
+5156 -797

No files matched your search

@@ -1,6 +1,7 @@
import { expect, it } from "vitest";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
import { analyzeCommonJsStaticFixture } from "../../../tests/fixtures/javascriptCommonJsAnalysis.js";
it.each([
"module.require = replacement;",
@@ -20,7 +21,11 @@ it.each([
);
it.each([
['const { app } = require("electron"); app.setAppPath("./other");', true],
[
'const { app } = require("electron"); app.setAppPath("./other");',
true,
true,
],
[
'import { app as runtime } from "electron/main"; runtime.setAppPath(path);',
true,
@@ -32,14 +37,17 @@ it.each([
[
'const { app } = require("electron"); const runtime = app; runtime.setAppPath("./other");',
true,
true,
],
[
'const { app } = require("electron"); const copy = { ...{ app } }; copy.app.setAppPath("./other");',
true,
true,
],
[
'const { app } = require("electron"); const change = app.setAppPath; change("./other");',
true,
true,
],
['const app = { setAppPath() {} }; app.setAppPath("./other");', false],
[
@@ -52,8 +60,10 @@ it.each([
],
])(
"retains Electron application path changes by binding identity: %s",
(source, expected) => {
const analysis = analyzeJavaScriptStaticSource(source);
(source, expected, commonJs = false) => {
const analysis = commonJs
? analyzeCommonJsStaticFixture(source)
: analyzeJavaScriptStaticSource(source);
expect(analysis.parse_error_count).toBe(0);
expect(analysis.electron.app_path_changes ?? []).toEqual(
expected
@@ -112,7 +122,7 @@ it.each([
])(
"retains indirect application path changes by Electron identity: %s",
(call, expected) => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
const { app } = require("electron");
${call}
`);
@@ -160,7 +170,7 @@ it("recovers APIs through an ES module default import of Electron", () => {
});
it("recovers APIs and sender checks written with optional chaining", () => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
const { contextBridge, ipcMain, utilityProcess } = require("electron");
contextBridge?.exposeInMainWorld("api", {});
utilityProcess?.fork("./worker.js");
@@ -202,7 +212,7 @@ it("recovers APIs and sender checks written with optional chaining", () => {
});
it("preserves empty and computed literal contextBridge member keys", () => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
const { contextBridge } = require("electron");
const dynamicKey = getKey();
contextBridge.exposeInMainWorld("api", {
@@ -232,7 +242,7 @@ it("preserves empty and computed literal contextBridge member keys", () => {
});
it("follows bundler namespace interop helpers without accepting other writes", () => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
var __toESM = (mod) => mod;
var __importStar = (mod) => mod;
let electron = require("electron");
@@ -279,7 +289,7 @@ it("does not trust unbound helper names or non-function helper values", () => {
});
it("follows stable declaration aliases but not an assigned default parameter", () => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
const direct = require("electron");
const constAlias = direct;
new constAlias.BrowserWindow({webPreferences:{preload:"./const.js"}});
@@ -302,7 +312,7 @@ it("follows stable declaration aliases but not an assigned default parameter", (
});
it("preserves one initializer across variable redeclarations without accepting writes", () => {
const analysis = analyzeJavaScriptStaticSource(`
const analysis = analyzeCommonJsStaticFixture(`
var electron;
var electron = require("electron");
var electron;