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

@@ -14,13 +14,12 @@ import {
type JavaScriptArtifactGraphContext,
type JavaScriptArtifactGraphCoverage,
} from "./JavaScriptArtifactGraphContext.js";
import {
astObservationEvidence,
staticInferenceEvidence,
} from "./JavaScriptArtifactGraphEvidence.js";
import { staticInferenceEvidence } from "./JavaScriptArtifactGraphEvidence.js";
import {
addElectronAstEdge,
addElectronInferenceEdge,
ELECTRON_CANDIDATE_LIMITATION,
electronFindingEvidence,
electronFindingSourceNode,
} from "./ElectronBoundaryGraphContext.js";
import {
@@ -98,6 +97,9 @@ const addBrowserWindow = (
web_preferences: value.web_preferences,
preload_path: value.preload_path,
preload_resolution_context: value.preload_resolution_context,
...(value.loader_authority === "candidate"
? { loader_authority: "candidate" }
: {}),
...(value.resolution_sources === undefined
? {}
: {
@@ -110,21 +112,40 @@ const addBrowserWindow = (
}),
absence_means_default: false,
},
evidence: (value.resolution_sources === undefined
? astObservationEvidence
: staticInferenceEvidence)({
sha256: file.sha256,
path: file.path,
range: value.location,
operation:
value.resolution_sources === undefined
? "observe-browser-window-construction"
: "resolve-browser-window-constant-options",
coverage,
limitations: [
"Only explicitly present webPreferences are reported; omitted properties are not interpreted as Electron defaults.",
],
}),
evidence:
value.resolution_sources === undefined
? electronFindingEvidence(
{
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-browser-window-construction",
coverage,
limitations: [
"Only explicitly present webPreferences are reported; omitted properties are not interpreted as Electron defaults.",
],
},
value.loader_authority,
)
: staticInferenceEvidence({
sha256: file.sha256,
path: file.path,
range: value.location,
operation:
value.resolution_sources === undefined
? "observe-browser-window-construction"
: "resolve-browser-window-constant-options",
coverage,
limitations: [
"Only explicitly present webPreferences are reported; omitted properties are not interpreted as Electron defaults.",
...(value.loader_authority === "candidate"
? [ELECTRON_CANDIDATE_LIMITATION]
: []),
],
...(value.loader_authority === "candidate"
? { confidence: "low" as const }
: {}),
}),
},
],
});
@@ -137,6 +158,7 @@ const addBrowserWindow = (
relation: "contains",
operation: "locate-browser-window-construction",
properties: { source_path: file.path },
loaderAuthority: value.loader_authority,
});
addWindowPreload(input, window);
};
@@ -145,7 +167,11 @@ const addWindowPreload = (
input: FindingInput<ElectronBrowserWindowFinding>,
window: ApplicationNode,
): void => {
if (input.value.preload_path === null) return;
if (
input.value.preload_path === null ||
input.value.loader_authority === "candidate"
)
return;
const {
preload_path: declared,
preload_resolution_context: resolutionContext,
@@ -217,16 +243,35 @@ const addContextBridge = (
members: value.members,
unknown_members: value.unknown_members,
resolution_basis: value.resolution_basis ?? "direct-syntax",
...(value.loader_authority === "candidate"
? { loader_authority: "candidate" }
: {}),
},
evidence: (value.resolution_basis === "wrapper-substitution"
? staticInferenceEvidence
: astObservationEvidence)({
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-context-bridge-api",
coverage,
}),
evidence:
value.resolution_basis !== "wrapper-substitution"
? electronFindingEvidence(
{
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-context-bridge-api",
coverage,
},
value.loader_authority,
)
: staticInferenceEvidence({
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-context-bridge-api",
coverage,
...(value.loader_authority === "candidate"
? {
confidence: "low" as const,
limitations: [ELECTRON_CANDIDATE_LIMITATION],
}
: {}),
}),
},
],
});
@@ -238,6 +283,7 @@ const addContextBridge = (
coverage,
relation: "exposes",
operation: "map-context-bridge-exposure",
loaderAuthority: value.loader_authority,
properties: {
world: value.world,
api_key: value.api_key,
@@ -251,7 +297,7 @@ const addUtilityProcess = (
): void => {
const { context, file, value, coverage } = input;
const resolution =
value.module_path === null
value.module_path === null || value.loader_authority === "candidate"
? undefined
: resolveArtifactPathByContext({
declaredPath: value.module_path,
@@ -283,14 +329,20 @@ const addUtilityProcess = (
module_resolution_context: value.module_resolution_context,
module_expression: value.module_expression,
service_name: value.service_name,
...(value.loader_authority === "candidate"
? { loader_authority: "candidate" }
: {}),
},
evidence: astObservationEvidence({
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-utility-process-fork",
coverage,
}),
evidence: electronFindingEvidence(
{
sha256: file.sha256,
path: file.path,
range: value.location,
operation: "observe-utility-process-fork",
coverage,
},
value.loader_authority,
),
},
...(resolution === undefined
? []
@@ -318,6 +370,7 @@ const addUtilityProcess = (
coverage,
relation: "loads",
operation: "map-utility-process-launch",
loaderAuthority: value.loader_authority,
limitations: resolution?.limitations ?? [],
properties: {
declared_path: value.module_path,