mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
7ad75bdc80
Restore source-position-aware ambient aliases, scalar env/argv reads, candidate endpoint worker data, Chrome DOMSnapshot empty strings, and accumulated Ghidra LaunchSupport diagnostics. Align regression fixtures with declared current contracts, while preserving identity, provenance, cancellation, and cleanup checks. Assert workflow caveats independently at both established locations. Validation: original five source failures reproduced on main; 307 focused tests passed with one platform skip, 22 fixture follow-up tests and 22 workflow/MCP tests passed; full static and docs checks passed. Real public http-server CLI analyses preserve identical artifact identity, statistics, and 581-token selected output. Real Chromium confirms restored DOM form destinations; isolated real service-worker verification passes on main and the change. The complete local browser run retained an unclassified later marker timeout; current-head CI provides complete real-browser and recovery lane results. Native IDA/Ghidra execution and complete local suite execution are not claimed. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
240 lines
8.1 KiB
TypeScript
240 lines
8.1 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { expect, it } from "vitest";
|
|
|
|
import { reconstructJavaScriptArtifact } from "../../support/javascriptApplicationScope.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import {
|
|
parseJavaScriptApplicationGraph,
|
|
serializeJavaScriptApplicationGraph,
|
|
} from "../../../src/domain/javascript/javascriptApplicationGraph.js";
|
|
|
|
it.each(["\n", "\r\n", "\r", "\u2028", "\u2029"])(
|
|
"preserves source-map graph evidence coordinates after %j",
|
|
async (separator) => {
|
|
const root = await createTestTempDirectory("rea-source-map-locations-");
|
|
const directive = "//# sourceMappingURL=app.js.map";
|
|
const source = `const marker = "😀";${separator} ${directive}`;
|
|
await writeFile(join(root, "app.js"), source);
|
|
const result = await reconstructJavaScriptArtifact({ input_path: root });
|
|
expect(result.statistics.parse_failures).toBe(0);
|
|
const nodes = new Map(
|
|
result.graph.nodes.map((node) => [node.node_id, node]),
|
|
);
|
|
const edge = result.graph.edges.find(
|
|
({ relation, target_node_id }) =>
|
|
relation === "maps_to" &&
|
|
nodes.get(target_node_id)?.kind === "source-map",
|
|
);
|
|
expect(edge).toMatchObject({
|
|
properties: {
|
|
declared_url_sha256: createHash("sha256")
|
|
.update("app.js.map")
|
|
.digest("hex"),
|
|
resolved_path: null,
|
|
},
|
|
evidence: {
|
|
state: "inferred",
|
|
artifact: {
|
|
sha256: createHash("sha256").update(source).digest("hex"),
|
|
},
|
|
location: {
|
|
available: true,
|
|
value: {
|
|
kind: "source-range",
|
|
source: "app.js",
|
|
start: { line: 2, column: 2 },
|
|
end: { line: 2, column: directive.length + 2 },
|
|
},
|
|
},
|
|
},
|
|
});
|
|
expect(
|
|
nodes
|
|
.get(edge?.target_node_id ?? "")
|
|
?.observations.some(
|
|
({ properties }) => properties.declared_url === "app.js.map",
|
|
),
|
|
).toBe(true);
|
|
},
|
|
);
|
|
|
|
it("owns an inline source-map URL once and recovers it from the target after JSON roundtrip", async () => {
|
|
const root = await createTestTempDirectory("rea-inline-source-map-url-");
|
|
const sourceContent = "source;".repeat(16_384);
|
|
const sourceMap = JSON.stringify({
|
|
version: 3,
|
|
sources: ["src/app.js"],
|
|
sourcesContent: [sourceContent],
|
|
names: [],
|
|
mappings: "AAAA",
|
|
});
|
|
const declaredUrl = `data:application/json;base64,${Buffer.from(sourceMap).toString("base64")}`;
|
|
await writeFile(
|
|
join(root, "app.js"),
|
|
`const app = true;\n//# sourceMappingURL=${declaredUrl}\n`,
|
|
);
|
|
|
|
const result = await reconstructJavaScriptArtifact({ input_path: root });
|
|
const serialized = serializeJavaScriptApplicationGraph(result.graph);
|
|
const graph = parseJavaScriptApplicationGraph(JSON.parse(serialized));
|
|
const edge = graph.edges.find(
|
|
({ relation, target_node_id }) =>
|
|
relation === "maps_to" &&
|
|
graph.nodes.some(
|
|
({ kind, node_id }) =>
|
|
kind === "source-map" && node_id === target_node_id,
|
|
),
|
|
);
|
|
const target = graph.nodes.find(
|
|
({ node_id }) => node_id === edge?.target_node_id,
|
|
);
|
|
|
|
const edgeUrlSha256 = edge?.properties.declared_url_sha256;
|
|
const observation = target?.observations.find(
|
|
({ properties }) => properties.declared_url_sha256 === edgeUrlSha256,
|
|
);
|
|
expect(edgeUrlSha256).toBe(
|
|
createHash("sha256").update(declaredUrl).digest("hex"),
|
|
);
|
|
expect(observation?.properties.declared_url).toBe(declaredUrl);
|
|
expect(observation?.properties).toMatchObject({
|
|
resolved_path: null,
|
|
available: false,
|
|
});
|
|
expect(serialized.split(declaredUrl)).toHaveLength(2);
|
|
});
|
|
|
|
it("associates each source-map URL with its edge when aliases share one physical map", async () => {
|
|
const root = await createTestTempDirectory("rea-source-map-aliases-");
|
|
await mkdir(join(root, "dist"));
|
|
await writeFile(
|
|
join(root, "dist", "app.js.map"),
|
|
JSON.stringify({ version: 3, sources: [], names: [], mappings: "" }),
|
|
);
|
|
await writeFile(
|
|
join(root, "dist", "one.js"),
|
|
"//# sourceMappingURL=app.js.map\n",
|
|
);
|
|
await writeFile(
|
|
join(root, "dist", "two.js"),
|
|
"//# sourceMappingURL=./app.js.map\n",
|
|
);
|
|
|
|
const result = await reconstructJavaScriptArtifact({ input_path: root });
|
|
const serialized = serializeJavaScriptApplicationGraph(result.graph);
|
|
const graph = parseJavaScriptApplicationGraph(JSON.parse(serialized));
|
|
const nodes = new Map(graph.nodes.map((node) => [node.node_id, node]));
|
|
const mapEdges = graph.edges.filter(
|
|
({ relation, target_node_id }) =>
|
|
relation === "maps_to" &&
|
|
nodes.get(target_node_id)?.kind === "source-map",
|
|
);
|
|
expect(mapEdges).toHaveLength(2);
|
|
expect(mapEdges[0]?.target_node_id).toBe(mapEdges[1]?.target_node_id);
|
|
// Edge order follows content-derived edge IDs, so pair each edge with the
|
|
// script whose comment declared it.
|
|
const declaredBySource = new Map(
|
|
mapEdges.map((edge) => {
|
|
const target = nodes.get(edge.target_node_id);
|
|
const observation = target?.observations.find(
|
|
({ properties }) =>
|
|
properties.declared_url_sha256 ===
|
|
edge.properties.declared_url_sha256,
|
|
);
|
|
const location = edge.evidence.location;
|
|
return [
|
|
location.available && location.value.kind === "source-range"
|
|
? location.value.source
|
|
: null,
|
|
{
|
|
declared_url: observation?.properties.declared_url,
|
|
resolved_path: edge.properties.resolved_path,
|
|
},
|
|
];
|
|
}),
|
|
);
|
|
expect(Object.fromEntries(declaredBySource)).toEqual({
|
|
"dist/one.js": {
|
|
declared_url: "app.js.map",
|
|
resolved_path: "dist/app.js.map",
|
|
},
|
|
"dist/two.js": {
|
|
declared_url: "./app.js.map",
|
|
resolved_path: "dist/app.js.map",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("resolves a bare source-map file name and worker URL next to the script", async () => {
|
|
const root = await createTestTempDirectory("rea-source-map-relative-");
|
|
await mkdir(join(root, "dist"));
|
|
await writeFile(
|
|
join(root, "dist", "app.js"),
|
|
[
|
|
'new Worker("worker.js");',
|
|
'navigator.serviceWorker.register("sw.js");',
|
|
"//# sourceMappingURL=app.js.map",
|
|
].join("\n"),
|
|
);
|
|
await writeFile(
|
|
join(root, "dist", "worker.js"),
|
|
"self.onmessage = () => {};",
|
|
);
|
|
await writeFile(join(root, "dist", "sw.js"), "self.onfetch = () => {};");
|
|
await writeFile(
|
|
join(root, "dist", "app.js.map"),
|
|
JSON.stringify({
|
|
version: 3,
|
|
sources: ["../src/app.js"],
|
|
sourcesContent: ['new Worker("worker.js");'],
|
|
names: [],
|
|
mappings: "AAAA",
|
|
}),
|
|
);
|
|
const result = await reconstructJavaScriptArtifact({ input_path: root });
|
|
const nodes = new Map(result.graph.nodes.map((node) => [node.node_id, node]));
|
|
const mapEdge = result.graph.edges.find(
|
|
({ relation, target_node_id }) =>
|
|
relation === "maps_to" &&
|
|
nodes.get(target_node_id)?.kind === "source-map",
|
|
);
|
|
expect(mapEdge?.properties).toEqual({
|
|
declared_url_sha256: createHash("sha256")
|
|
.update("app.js.map")
|
|
.digest("hex"),
|
|
resolved_path: "dist/app.js.map",
|
|
resolution_status: "resolved",
|
|
});
|
|
expect(
|
|
nodes
|
|
.get(mapEdge?.target_node_id ?? "")
|
|
?.observations.some(
|
|
({ properties }) =>
|
|
properties.declared_url === "app.js.map" &&
|
|
properties.resolved_path === "dist/app.js.map" &&
|
|
properties.available === true,
|
|
),
|
|
).toBe(true);
|
|
expect(nodes.get(mapEdge?.target_node_id ?? "")?.identity.strategy).toBe(
|
|
"content-digest",
|
|
);
|
|
const workerEdge = result.graph.edges.find(
|
|
({ relation, source_node_id }) =>
|
|
relation === "maps_to" && nodes.get(source_node_id)?.kind === "worker",
|
|
);
|
|
expect(workerEdge?.properties).toMatchObject({
|
|
resolved_path: "dist/worker.js",
|
|
});
|
|
const serviceWorkerEdge = result.graph.edges.find(
|
|
({ relation, source_node_id }) =>
|
|
relation === "maps_to" &&
|
|
nodes.get(source_node_id)?.kind === "service-worker",
|
|
);
|
|
expect(serviceWorkerEdge?.properties).toMatchObject({
|
|
resolved_path: "dist/sw.js",
|
|
});
|
|
});
|