mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
fix(android): validate explicit Java runtime (#742)
This commit is contained in:
@@ -30,21 +30,31 @@ export const resolveJadxConfiguration = async (
|
||||
throw unavailable(
|
||||
"Set REA_JADX_MCP_JAR to the absolute path of a caller-supplied jadx-headless-mcp 0.7.1 JAR. REA does not download or install it.",
|
||||
);
|
||||
const java =
|
||||
environment.JAVA_HOME === undefined
|
||||
? "java"
|
||||
: join(environment.JAVA_HOME, "bin", "java");
|
||||
try {
|
||||
await access(jar, constants.R_OK);
|
||||
if (!(await stat(jar)).isFile())
|
||||
throw unavailable(`REA_JADX_MCP_JAR is not a regular file: ${jar}`);
|
||||
return {
|
||||
jar: await realpath(jar),
|
||||
java:
|
||||
environment.JAVA_HOME === undefined
|
||||
? "java"
|
||||
: join(environment.JAVA_HOME, "bin", "java"),
|
||||
};
|
||||
} catch (cause) {
|
||||
if (cause instanceof AnalysisCapabilityUnavailableError) throw cause;
|
||||
throw unavailable(
|
||||
`Cannot read REA_JADX_MCP_JAR ${jar}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
||||
);
|
||||
}
|
||||
if (environment.JAVA_HOME !== undefined) {
|
||||
try {
|
||||
await access(java, constants.R_OK | constants.X_OK);
|
||||
if (!(await stat(java)).isFile())
|
||||
throw unavailable(`JAVA_HOME java is not a regular file: ${java}`);
|
||||
} catch (cause) {
|
||||
if (cause instanceof AnalysisCapabilityUnavailableError) throw cause;
|
||||
throw unavailable(
|
||||
`Cannot execute JAVA_HOME java ${java}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return { jar: await realpath(jar), java };
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { chmod, mkdir, realpath, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { expect, it as test } from "vitest";
|
||||
|
||||
import { resolveJadxConfiguration } from "../../../src/android/JadxConfiguration.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
const it = test.skipIf(process.platform === "win32");
|
||||
|
||||
it("rejects an explicit JAVA_HOME without an executable java binary", async () => {
|
||||
const root = await createTestTempDirectory("rea-jadx-config-");
|
||||
const jar = join(root, "jadx-headless-mcp.jar");
|
||||
const javaHome = join(root, "missing-jdk");
|
||||
await writeFile(jar, "fixture jar");
|
||||
|
||||
await expect(
|
||||
resolveJadxConfiguration(
|
||||
{ REA_JADX_MCP_JAR: jar, JAVA_HOME: javaHome },
|
||||
"inspect_android_package",
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
_tag: "AnalysisCapabilityUnavailableError",
|
||||
reason: expect.stringContaining(join(javaHome, "bin", "java")),
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts a verified explicit java binary and canonicalizes the JAR", async () => {
|
||||
const root = await createTestTempDirectory("rea-jadx-config-");
|
||||
const jar = join(root, "jadx-headless-mcp.jar");
|
||||
const javaHome = join(root, "jdk");
|
||||
const java = join(javaHome, "bin", "java");
|
||||
await mkdir(join(javaHome, "bin"), { recursive: true });
|
||||
await writeFile(jar, "fixture jar");
|
||||
await writeFile(java, "#!/bin/sh\n");
|
||||
await chmod(java, 0o700);
|
||||
|
||||
await expect(
|
||||
resolveJadxConfiguration(
|
||||
{ REA_JADX_MCP_JAR: jar, JAVA_HOME: javaHome },
|
||||
"inspect_android_package",
|
||||
),
|
||||
).resolves.toEqual({ jar: await realpath(jar), java });
|
||||
});
|
||||
Reference in New Issue
Block a user