diff --git a/src/il2cpp/Il2cppGhidraSeedWriter.ts b/src/il2cpp/Il2cppGhidraSeedWriter.ts index 56f996e24a..f54023cc2d 100644 --- a/src/il2cpp/Il2cppGhidraSeedWriter.ts +++ b/src/il2cpp/Il2cppGhidraSeedWriter.ts @@ -69,6 +69,13 @@ export class Il2cppGhidraSeedWriter implements Il2cppSeedWriterPort { } catch (cause) { if (cause instanceof Error && "code" in cause && cause.code === "ENOENT") return ok(undefined); + if (cause instanceof Error && "code" in cause && cause.code === "ENOTDIR") + return err( + invalid( + "ghidra_seeds", + `--ghidra-seeds ${output.path} has a parent path component that is not a directory; choose an output path inside an existing directory.`, + ), + ); return err( new EvidenceFileError("write", "io", { path: output.path, cause }), ); diff --git a/tests/acceptance/il2cppMetadataCli.test.ts b/tests/acceptance/il2cppMetadataCli.test.ts index 95ff5bf731..2d7bb5517d 100644 --- a/tests/acceptance/il2cppMetadataCli.test.ts +++ b/tests/acceptance/il2cppMetadataCli.test.ts @@ -978,3 +978,41 @@ cliTest( }); }, ); + +cliTest.skipIf(process.platform === "win32")( + "refuses a Ghidra seed path below a regular file as caller input", + async ({ cli }) => { + const root = await createTestTempDirectory("rea-il2cpp-seeds-parent-"); + const path = join(root, "global-metadata.dat"); + const binaryPath = join(root, "libil2cpp.so"); + const parent = join(root, "regular-file"); + await writeFile(path, createIl2cppMetadataFixture().bytes); + await writeFile(binaryPath, createElfFixture(createIl2cppBinaryFixture())); + await writeFile(parent, "unchanged"); + const result = await runFileCli(cli, { + arguments: [ + "inspect-il2cpp-metadata", + path, + "--binary", + binaryPath, + "--ghidra-seeds", + join(parent, "seeds.tsv"), + "--json", + ], + }); + expect(result.exitCode).not.toBe(0); + expect(result.json).toMatchObject({ + code: "invalid_request", + category: "invalid_input", + details: { + issues: [ + { + path: ["ghidra_seeds"], + message: expect.stringContaining("not a directory"), + }, + ], + }, + }); + expect(await readFile(parent, "utf8")).toBe("unchanged"); + }, +);