fix(il2cpp): reject module image references outside retained inventory (#8956)
This commit is contained in:
1 parent
4362a0848e
commit
da79ea0baa
3 files changed
+103
No files matched your search
@@ -482,6 +482,34 @@ const linkedReport = (): Il2cppMetadata => ({
|
||||
parameter_types: [{ type: 0, name: "int" }],
|
||||
});
|
||||
|
||||
it.each([-1, 1, 99])(
|
||||
"rejects imported code-generation module image reference %i",
|
||||
(image) => {
|
||||
const value = linkedReport();
|
||||
value.binary!.code_gen_modules[0]!.image = image;
|
||||
const parsed = il2cppMetadataParentSchema.safeParse(value);
|
||||
expect(parsed.success).toBe(false);
|
||||
if (!parsed.success)
|
||||
expect(parsed.error.issues).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
path: ["binary", "code_gen_modules", 0, "image"],
|
||||
}),
|
||||
]),
|
||||
);
|
||||
for (const selection of [{}, { image_indices: [image] }]) {
|
||||
const view = projectIl2cppMetadataView(parent(value, false), {
|
||||
kind: "il2cpp-metadata",
|
||||
collection: "code_gen_modules",
|
||||
...selection,
|
||||
offset: 0,
|
||||
limit: 64,
|
||||
});
|
||||
expect(view.ok).toBe(false);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("selects every folded method by numeric address with stable indices and both source identities", () => {
|
||||
const source = parent(freezeJsonSnapshot(linkedReport()), true);
|
||||
const view = projectIl2cppMetadataView(source, {
|
||||
|
||||
@@ -444,6 +444,14 @@ const validateMetadataFacts = (
|
||||
"Type reference is outside the linked type table or names an unavailable type.",
|
||||
});
|
||||
});
|
||||
report.binary?.code_gen_modules.forEach((row, index) => {
|
||||
if (row.image >= report.images.length)
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
path: ["binary", "code_gen_modules", index, "image"],
|
||||
message: "Code-generation module image is outside the retained images.",
|
||||
});
|
||||
});
|
||||
report.method_addresses?.forEach((row, index) => {
|
||||
if (codeRowContradicts(row, report.binary?.image_base))
|
||||
context.addIssue({
|
||||
|
||||
@@ -56,6 +56,73 @@ const parseMetadataSummary = (value: unknown) =>
|
||||
parseEvidence(value).normalized_result,
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"rejects out-of-range module image references through CLI and MCP",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-il2cpp-module-image-");
|
||||
const path = join(root, "global-metadata.dat");
|
||||
const binaryPath = join(root, "GameAssembly.dylib");
|
||||
await writeFile(
|
||||
path,
|
||||
createLinkedIl2cppMetadataFixture({ version: 39 }).bytes,
|
||||
);
|
||||
await writeFile(binaryPath, createIl2cppBinaryFixture());
|
||||
const produced = await runFileCli(cli, {
|
||||
arguments: [
|
||||
"inspect-il2cpp-metadata",
|
||||
path,
|
||||
"--binary",
|
||||
binaryPath,
|
||||
"--detail",
|
||||
"complete",
|
||||
"--json",
|
||||
],
|
||||
});
|
||||
expect(produced.exitCode, produced.stderr).toBe(0);
|
||||
const original = parseCliMetadata(produced.json);
|
||||
expect(original.binary!.code_gen_modules.length).toBeGreaterThan(0);
|
||||
const { call } = await connectLocalToolsMcp();
|
||||
for (const image of [
|
||||
0,
|
||||
original.images.length - 1,
|
||||
-1,
|
||||
original.images.length,
|
||||
99,
|
||||
]) {
|
||||
const report = structuredClone(original);
|
||||
report.binary!.code_gen_modules[0]!.image = image;
|
||||
const evidence = createEvidence(
|
||||
{ path, format: "file", sha256: report.artifact.sha256 },
|
||||
{ id: "il2cpp-metadata", name: "IL2CPP", version: "1" },
|
||||
{
|
||||
operation: "inspect_il2cpp_metadata",
|
||||
parameters: { path },
|
||||
result: report,
|
||||
},
|
||||
);
|
||||
const request = {
|
||||
source: { kind: "inline", evidence },
|
||||
view: { kind: "il2cpp-metadata", collection: "code_gen_modules" },
|
||||
};
|
||||
const query = join(root, `image-${image}.json`);
|
||||
await writeFile(query, JSON.stringify(request));
|
||||
const result = await runFileCli(cli, {
|
||||
arguments: ["inspect-analysis-view", query, "--json"],
|
||||
});
|
||||
const mcp = await call("inspect_analysis_view", request);
|
||||
if (image >= 0 && image < original.images.length) {
|
||||
expect(result.exitCode, result.stderr).toBe(0);
|
||||
expect(mcp.isError, JSON.stringify(mcp)).not.toBe(true);
|
||||
} else {
|
||||
expect(result.exitCode, `image ${image}`).toBe(1);
|
||||
expect(result.json).toMatchObject({ code: "invalid_request" });
|
||||
expect(parseMcpToolError(mcp).error.code).toBe("invalid_request");
|
||||
}
|
||||
}
|
||||
},
|
||||
30000,
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"rejects impossible imported metadata owners through CLI and MCP",
|
||||
async ({ cli }) => {
|
||||
|
||||
Reference in new issue
Block a user