2026-07-13 22:21:58 +08:00
|
|
|
import { execFile } from "node:child_process";
|
|
|
|
|
import { promisify } from "node:util";
|
2026-10-16 00:11:19 +06:00
|
|
|
import { GHIDRA_BRIDGE_SOURCES } from "../src/ghidra/GhidraBridgeSources.ts";
|
2026-07-13 22:21:58 +08:00
|
|
|
|
|
|
|
|
const exec = promisify(execFile);
|
2026-07-16 00:02:49 +08:00
|
|
|
const packedHopperBridge = "package/bridge/hopper_bridge.py";
|
2026-10-14 04:47:34 +08:00
|
|
|
const packedCutterBridge = "package/bridge/cutter/rea_bridge.py";
|
2026-07-13 22:21:58 +08:00
|
|
|
|
2026-10-09 05:53:52 +08:00
|
|
|
/** Check shipped bridge files; real-provider lanes verify runtime behavior. */
|
2026-10-17 18:35:31 +08:00
|
|
|
export async function verifyPackedBridge({ tarball, packedFiles }) {
|
2026-10-12 02:46:32 +08:00
|
|
|
for (const path of [
|
|
|
|
|
packedHopperBridge,
|
2026-10-14 04:47:34 +08:00
|
|
|
packedCutterBridge,
|
2026-10-16 00:11:19 +06:00
|
|
|
...Object.values(GHIDRA_BRIDGE_SOURCES).map(
|
|
|
|
|
(name) => `package/bridge/ghidra/${name}`,
|
|
|
|
|
),
|
2026-10-12 02:46:32 +08:00
|
|
|
]) {
|
2026-10-09 05:53:52 +08:00
|
|
|
if (!packedFiles.includes(path)) throw new Error(`package omitted ${path}`);
|
|
|
|
|
}
|
2026-10-17 18:35:31 +08:00
|
|
|
// Read the packed source without extracting into the caller's leased root.
|
2026-10-09 05:53:52 +08:00
|
|
|
await exec("python3", [
|
|
|
|
|
"-c",
|
2026-10-17 18:35:31 +08:00
|
|
|
[
|
|
|
|
|
"import ast, sys, tarfile",
|
|
|
|
|
"with tarfile.open(sys.argv[1]) as archive:",
|
|
|
|
|
" member = archive.getmember(sys.argv[2])",
|
|
|
|
|
" if not member.isfile():",
|
|
|
|
|
" raise ValueError(f'{member.name} is not a regular file')",
|
|
|
|
|
" with archive.extractfile(member) as source:",
|
|
|
|
|
" ast.parse(source.read().decode('utf-8'), filename=sys.argv[2])",
|
|
|
|
|
].join("\n"),
|
|
|
|
|
tarball,
|
|
|
|
|
packedHopperBridge,
|
2026-10-09 05:53:52 +08:00
|
|
|
]);
|
2026-07-13 22:21:58 +08:00
|
|
|
}
|