mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
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:
1 parent
78a84d75c0
commit
b46f4fcebd
112 files changed
+5156
-797
No files matched your search
@@ -27,11 +27,11 @@ import {
|
||||
semanticEffectTiming,
|
||||
} from "./javascriptSemanticMutationInitializers.js";
|
||||
import {
|
||||
builtinDataEffectMethod as builtinMethod,
|
||||
builtinDataEffectIdentity,
|
||||
dataEffectArgumentBindingId as argumentBindingId,
|
||||
dataEffectLiteralString as literalString,
|
||||
dataEffectMemberCallee as memberCallee,
|
||||
isSemanticProcessObject as isProcessObject,
|
||||
semanticProcessObjectIdentity,
|
||||
outerDataEffectBinding as outerAssignedBinding,
|
||||
assignedSemanticResultBindings,
|
||||
semanticProjectedBindingFacts,
|
||||
@@ -103,6 +103,9 @@ const collectConfigurations = (
|
||||
key: details.key,
|
||||
sourceConfigId: null,
|
||||
value: null,
|
||||
...(details.builtinAuthority === undefined
|
||||
? {}
|
||||
: { builtinAuthority: details.builtinAuthority }),
|
||||
resolution: details.resolution,
|
||||
};
|
||||
output.push({ node, operation });
|
||||
@@ -116,6 +119,7 @@ const configurationDetails = (
|
||||
): {
|
||||
readonly kind: "environment" | "argv" | "file";
|
||||
readonly key: string | null;
|
||||
readonly builtinAuthority?: "candidate";
|
||||
readonly resolution: "complete" | "partial";
|
||||
} | null => {
|
||||
if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
|
||||
@@ -124,19 +128,32 @@ const configurationDetails = (
|
||||
}
|
||||
if (!t.isCallExpression(node) && !t.isOptionalCallExpression(node))
|
||||
return null;
|
||||
const fsMethod = builtinMethod(node.callee, context.state, ["fs", "node:fs"]);
|
||||
const fs = builtinDataEffectIdentity(node.callee, context.state, [
|
||||
"fs",
|
||||
"node:fs",
|
||||
]);
|
||||
const fsMethod = fs?.path.length === 1 ? fs.path[0] : null;
|
||||
const promises =
|
||||
fsMethod === null
|
||||
? builtinDataEffectIdentity(node.callee, context.state, [
|
||||
"fs/promises",
|
||||
"node:fs/promises",
|
||||
])
|
||||
: null;
|
||||
const isFileRead =
|
||||
fsMethod === "readFile" ||
|
||||
fsMethod === "readFileSync" ||
|
||||
(fsMethod === null &&
|
||||
builtinMethod(node.callee, context.state, [
|
||||
"fs/promises",
|
||||
"node:fs/promises",
|
||||
]) === "readFile");
|
||||
promises?.path.length === 1 &&
|
||||
promises.path[0] === "readFile");
|
||||
return isFileRead
|
||||
? {
|
||||
kind: "file",
|
||||
key: literalString(node.arguments[0]),
|
||||
...((fsMethod === null ? promises : fs)?.builtinAuthority ===
|
||||
"candidate"
|
||||
? { builtinAuthority: "candidate" as const }
|
||||
: {}),
|
||||
resolution:
|
||||
literalString(node.arguments[0]) === null ? "partial" : "complete",
|
||||
}
|
||||
@@ -149,6 +166,7 @@ const processConfigurationMember = (
|
||||
): {
|
||||
readonly kind: "environment" | "argv";
|
||||
readonly key: string | null;
|
||||
readonly builtinAuthority?: "candidate";
|
||||
readonly resolution: "complete" | "partial";
|
||||
} | null => {
|
||||
const object = node.object;
|
||||
@@ -159,10 +177,19 @@ const processConfigurationMember = (
|
||||
// `process.env[""]` names an exact (empty) key; only a dynamic key is unknown.
|
||||
const key = semanticStaticPropertyKey(node.property, node.computed);
|
||||
if (family === "argv" && key !== null && !isArrayIndexKey(key)) return null;
|
||||
if (!isProcessObject(object.object, state, family, key)) return null;
|
||||
const processIdentity = semanticProcessObjectIdentity(
|
||||
object.object,
|
||||
state,
|
||||
family,
|
||||
key,
|
||||
);
|
||||
if (processIdentity === null) return null;
|
||||
return {
|
||||
kind: family === "env" ? "environment" : "argv",
|
||||
key,
|
||||
...(processIdentity.builtinAuthority === undefined
|
||||
? {}
|
||||
: { builtinAuthority: processIdentity.builtinAuthority }),
|
||||
resolution: key === null ? "partial" : "complete",
|
||||
};
|
||||
};
|
||||
@@ -203,6 +230,9 @@ const collectDefaults = (
|
||||
ownerCallableId: context.callableStack.at(-1) ?? null,
|
||||
resultBindingId: outerAssignedBinding(node, context),
|
||||
key: candidate.operation.key,
|
||||
...(candidate.operation.builtinAuthority === undefined
|
||||
? {}
|
||||
: { builtinAuthority: candidate.operation.builtinAuthority }),
|
||||
sourceConfigId: candidate.operation.configId,
|
||||
value: value.status === "literal" ? value.value : null,
|
||||
...(value.status === "unknown" && value.resourceLimit !== undefined
|
||||
@@ -226,8 +256,9 @@ const collectRequests = (
|
||||
!t.isNewExpression(node)
|
||||
)
|
||||
return;
|
||||
const method = requestMethod(node, context.state);
|
||||
if (method === null) return;
|
||||
const identity = requestMethod(node, context.state);
|
||||
if (identity === null) return;
|
||||
const method = identity.method;
|
||||
const endpoint = requestEndpoint(node);
|
||||
// `http.get`/`http.request` parse a string target with `new URL` before the
|
||||
// request exists, so a literal that is not an absolute URL throws
|
||||
@@ -246,6 +277,9 @@ const collectRequests = (
|
||||
requestId: `request:${String(node.start ?? -1)}:${String(node.end ?? -1)}`,
|
||||
kind: "request",
|
||||
method,
|
||||
...(identity.builtinAuthority === undefined
|
||||
? {}
|
||||
: { builtinAuthority: identity.builtinAuthority }),
|
||||
location: range(node),
|
||||
ownerCallableId: context.callableStack.at(-1) ?? null,
|
||||
resultBindingId: outerAssignedBinding(node, context),
|
||||
@@ -478,7 +512,10 @@ const boundaryDetails = (
|
||||
const requestMethod = (
|
||||
node: t.CallExpression | t.OptionalCallExpression | t.NewExpression,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): JavaScriptSemanticRequestOperation["method"] | null => {
|
||||
): {
|
||||
readonly method: JavaScriptSemanticRequestOperation["method"];
|
||||
readonly builtinAuthority?: "candidate";
|
||||
} | null => {
|
||||
if (t.isIdentifier(node.callee)) {
|
||||
const name = node.callee.name;
|
||||
const unbound =
|
||||
@@ -490,15 +527,23 @@ const requestMethod = (
|
||||
name === global &&
|
||||
isUnmodifiedGlobalReference(node.callee, state, name)
|
||||
)
|
||||
return global;
|
||||
return { method: global };
|
||||
}
|
||||
const method = builtinMethod(node.callee, state, [
|
||||
const identity = builtinDataEffectIdentity(node.callee, state, [
|
||||
"http",
|
||||
"https",
|
||||
"node:http",
|
||||
"node:https",
|
||||
]);
|
||||
return method === "request" || method === "get" ? method : null;
|
||||
const method = identity?.path.length === 1 ? identity.path[0] : null;
|
||||
return method === "request" || method === "get"
|
||||
? {
|
||||
method,
|
||||
...(identity?.builtinAuthority === undefined
|
||||
? {}
|
||||
: { builtinAuthority: identity.builtinAuthority }),
|
||||
}
|
||||
: null;
|
||||
};
|
||||
|
||||
const requestFields = (
|
||||
|
||||
Reference in new issue
Block a user