mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 22:36:08 +00:00
Require automatically discovered Hopper launchers to be executable regular files so POSIX directory search permission cannot hide a later valid application bundle. Preserve file symlinks, explicit caller configuration, and the shared candidate ordering. Cover canonical and renamed user bundles through the production filesystem predicate; respect existing canonical or renamed system installations in the isolated fixtures. Clarify launcher eligibility in the installation guide. Follow-up to #3085 and #3054 after their shared path discovery landed on main. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
99 lines
3.4 KiB
TypeScript
99 lines
3.4 KiB
TypeScript
import { accessSync, constants, statSync } from "node:fs";
|
|
|
|
import type { ConfigurationError } from "../domain/configurationErrors.js";
|
|
import { ok, type Result } from "../domain/result.js";
|
|
import { parseEnvironment } from "./environment.js";
|
|
import { homeDirectoryFromEnvironment } from "./homeDirectory.js";
|
|
import type { AppConfig } from "./types.js";
|
|
import {
|
|
linuxHopperLauncherCandidates,
|
|
REA_MANAGED_LINUX_HOPPER_LAUNCHER,
|
|
} from "../application/LinuxHopper.js";
|
|
import {
|
|
MAC_HOPPER_SYSTEM_LAUNCHER,
|
|
macHopperLauncherCandidates,
|
|
} from "../application/MacHopperPaths.js";
|
|
const executableAvailable = (path: string): boolean => {
|
|
try {
|
|
accessSync(path, constants.X_OK);
|
|
return statSync(path).isFile();
|
|
} catch {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const defaultHopperLauncherPath = (
|
|
platform: NodeJS.Platform,
|
|
homeDirectory: string,
|
|
executable: (path: string) => boolean = executableAvailable,
|
|
): string => {
|
|
if (platform === "darwin") {
|
|
for (const candidate of macHopperLauncherCandidates(homeDirectory))
|
|
if (executable(candidate)) return candidate;
|
|
return MAC_HOPPER_SYSTEM_LAUNCHER;
|
|
}
|
|
if (platform !== "linux") return MAC_HOPPER_SYSTEM_LAUNCHER;
|
|
return (
|
|
linuxHopperLauncherCandidates(homeDirectory).find(executable) ??
|
|
REA_MANAGED_LINUX_HOPPER_LAUNCHER
|
|
);
|
|
};
|
|
|
|
/** Parse provider configuration and runtime prerequisites at the composition root. */
|
|
export const parseConfig = (
|
|
environment: Readonly<Record<string, string | undefined>>,
|
|
): Result<AppConfig, ConfigurationError> => {
|
|
const parsed = parseEnvironment(environment);
|
|
if (!parsed.ok) return parsed;
|
|
const env = parsed.value;
|
|
return ok({
|
|
...(env.REA_MCP_MAX_RESPONSE_BYTES === undefined
|
|
? {}
|
|
: { mcpMaxResponseBytes: env.REA_MCP_MAX_RESPONSE_BYTES }),
|
|
...(env.REA_MCP_INPUT_SCHEMA_PROFILE === undefined
|
|
? {}
|
|
: { mcpInputSchemaProfile: env.REA_MCP_INPUT_SCHEMA_PROFILE }),
|
|
analysisProvider: env.REA_ANALYSIS_PROVIDER,
|
|
...(env.REA_IDA_MCP_CONFIG === undefined
|
|
? {}
|
|
: { idaMcpConfigPath: env.REA_IDA_MCP_CONFIG }),
|
|
ghidraInstallDir: env.GHIDRA_INSTALL_DIR,
|
|
ghidraJavaHome: env.JAVA_HOME,
|
|
ghidraStartupTimeoutMs: env.REA_GHIDRA_STARTUP_TIMEOUT_MS,
|
|
...(env.REA_GHIDRA_LANGUAGE_ID === undefined
|
|
? {}
|
|
: {
|
|
ghidraLanguageOverride: {
|
|
languageId: env.REA_GHIDRA_LANGUAGE_ID,
|
|
...(env.REA_GHIDRA_COMPILER_SPEC_ID === undefined
|
|
? {}
|
|
: { compilerSpecId: env.REA_GHIDRA_COMPILER_SPEC_ID }),
|
|
},
|
|
}),
|
|
...(env.REA_GHIDRA_SEED_FILE === undefined
|
|
? {}
|
|
: { ghidraSeedFile: env.REA_GHIDRA_SEED_FILE }),
|
|
...(env.REA_GHIDRA_DISABLED_ANALYZERS === undefined
|
|
? {}
|
|
: { ghidraDisabledAnalyzers: env.REA_GHIDRA_DISABLED_ANALYZERS }),
|
|
...(env.REA_GHIDRA_NATIVEAOT_JAR === undefined
|
|
? {}
|
|
: { ghidraNativeAotJar: env.REA_GHIDRA_NATIVEAOT_JAR }),
|
|
ilspyCmdPath: env.REA_ILSPY_CMD_PATH,
|
|
hopperLauncherPath:
|
|
env.HOPPER_LAUNCHER_PATH ??
|
|
defaultHopperLauncherPath(
|
|
process.platform,
|
|
homeDirectoryFromEnvironment(environment, process.platform),
|
|
),
|
|
hopperStartupTimeoutMs: env.REA_HOPPER_STARTUP_TIMEOUT_MS,
|
|
hopperTargetPath: env.HOPPER_TARGET_PATH,
|
|
hopperTargetKind: env.HOPPER_TARGET_KIND,
|
|
hopperLoaderArgs: env.loaderArgs,
|
|
logLevel: env.REA_LOG_LEVEL,
|
|
referenceSourcePolicy: {
|
|
secretPatterns: env.referenceSecretPatterns,
|
|
},
|
|
});
|
|
};
|