fix(javascript): match exact empty literal channels and seeds

Pair the same empty IPC channel, context-bridge key, or endpoint value
across application versions by its exact value, and accept an exact
empty feature seed while rejecting an empty containment seed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Iwakurakaoru0822andClaude Opus 5.5 committed 2026-10-06 21:35:59 -07:00
1 parent 527b76ef78
commit e20da1f205
8 files changed
+136 -27

No files matched your search

@@ -5,7 +5,9 @@ import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
import { matchJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionKeys.js";
import { findApplicationFeatureSeeds } from "../domain/javascriptFeatureSeed.js";
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
const analyzeSource = async (
@@ -152,3 +154,74 @@ it("does not match an empty endpoint with a literal two-quote seed", async () =>
'""',
]);
});
const IPC_SOURCE =
"const { ipcMain } = require('electron'); ipcMain.handle('', () => 1); ipcMain.handle('\"\"', () => 2);";
const ipcChannels = (
nodes: Awaited<ReturnType<typeof analyzeSource>>["graph"]["nodes"],
) =>
new Map(
nodes
.filter(({ kind }) => kind === "ipc-channel")
.map((node) => [node.node_id, node.observations[0]?.properties.channel]),
);
it("selects an empty IPC channel with an exact empty seed", async () => {
const output = await analyzeSource(IPC_SOURCE);
const channels = ipcChannels(output.graph.nodes);
const matches = findApplicationFeatureSeeds(output.graph.nodes, {
kind: "channel",
value: "",
match: "exact",
case_sensitive: true,
});
expect(matches.map(({ node_id: nodeId }) => channels.get(nodeId))).toEqual([
"",
]);
});
it.each([
{ kind: "channel", value: "" },
{ kind: "string", value: "", match: "exact" },
])("accepts an exact empty seed: %j", (seed) => {
expect(
traceApplicationFeatureInputSchema.shape.seed.safeParse(seed).success,
).toBe(true);
});
it.each([
{ kind: "string", value: "" },
{ kind: "channel", value: "", match: "contains" },
{ kind: "node-id", value: "", match: "exact" },
])("rejects an empty seed that is not an exact literal: %j", (seed) => {
const parsed = traceApplicationFeatureInputSchema.shape.seed.safeParse(seed);
expect(parsed.success).toBe(false);
});
it("pairs the same empty IPC channel across application versions", async () => {
const left = await analyzeSource(IPC_SOURCE);
const right = await analyzeSource(`${IPC_SOURCE} // v2`);
const leftChannels = ipcChannels(left.graph.nodes);
const rightChannels = ipcChannels(right.graph.nodes);
const matching = matchJavaScriptApplicationVersions(
left.graph.nodes,
right.graph.nodes,
);
expect(
matching.pairs
.filter(({ left: node }) => node.kind === "ipc-channel")
.map(({ left: leftNode, right: rightNode }) => [
leftChannels.get(leftNode.node_id),
rightChannels.get(rightNode.node_id),
]),
).toEqual(
expect.arrayContaining([
["", ""],
['""', '""'],
]),
);
expect(matching.unmatchedLeft.map(({ kind }) => kind)).not.toContain(
"ipc-channel",
);
});