Files
reverse-engineering-anything/tests/acceptance/applications/javascriptAsarCollisionCli.test.ts
T
morluto 83cd1e04c9 fix(javascript)!: report ambiguous artifact paths (#7864)
* fix(javascript): report ambiguous artifact paths

* fix(javascript): retain unavailable colliding sources
2026-10-29 05:10:18 +08:00

82 lines
2.6 KiB
TypeScript

import { createHash } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect } from "vitest";
import { asarHeaderBytes } from "../../fixtures/asarHeader.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"reports normalized ASAR collisions as path failures",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-asar-collision-cli-");
const path = join(root, "twins.asar");
const entries = [
["café.js", "console.log(1)\n"],
["cafe\u0301.js", "console.log(2)\n"],
] as const;
let offset = 0;
const files = Object.fromEntries(
entries.map(([name, text]) => {
const bytes = Buffer.from(text);
const record = {
size: bytes.length,
offset: String(offset),
integrity: {
algorithm: "SHA256",
hash: createHash("sha256").update(bytes).digest("hex"),
},
};
offset += bytes.length;
return [name, record];
}),
);
await writeFile(
path,
Buffer.concat([
asarHeaderBytes(JSON.stringify({ files })),
...entries.map(([, text]) => Buffer.from(text)),
]),
);
const result = await cli.run({
arguments: ["analyze-javascript-application", path, "--json"],
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "artifact_operation_failed",
details: { reason: "path", detail: expect.stringContaining("café.js") },
});
expect(result.stdout).not.toContain("changed after inventory");
},
);
cliTest(
"analyzes readable sources when all colliding siblings are unavailable",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-asar-missing-cli-");
const path = join(root, "missing.asar");
const main = Buffer.from('require("./café.js");\n');
const files = {
"main.js": { size: main.length, offset: "0" },
"café.js": { size: 10, unpacked: true },
"cafe\u0301.js": { size: 10, unpacked: true },
};
await writeFile(
path,
Buffer.concat([asarHeaderBytes(JSON.stringify({ files })), main]),
);
const result = await cli.run({
arguments: ["analyze-javascript-application", path, "--json"],
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({
normalized_result: {
statistics: { parsed_javascript_files: 1 },
},
});
expect(result.stdout).toContain("café.js");
expect(result.stdout).toContain("unknown");
},
);