mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
fix(il2cpp): validate retained declaring type relationships (#7946)
This commit is contained in:
1 parent
5147b6e306
commit
ef9ab91e42
5 files changed
+124
-24
No files matched your search
@@ -0,0 +1,26 @@
|
||||
/** Find a cycle in positional declaring-type links, yielding during long walks. */
|
||||
export function* firstDeclaringTypeCycle(
|
||||
types: readonly { readonly declaring_type: number }[],
|
||||
): Generator<void, number | null> {
|
||||
// 0 unvisited, 1 on the current chain, 2 already examined.
|
||||
const state = new Uint8Array(types.length);
|
||||
let work = 0;
|
||||
for (let first = 0; first < types.length; first += 1) {
|
||||
if (work++ % 256 === 0) yield;
|
||||
const chain: number[] = [];
|
||||
let current = first;
|
||||
while (current >= 0 && current < types.length && state[current] === 0) {
|
||||
if (work++ % 256 === 0) yield;
|
||||
state[current] = 1;
|
||||
chain.push(current);
|
||||
current = types[current]!.declaring_type;
|
||||
}
|
||||
if (current >= 0 && current < types.length && state[current] === 1)
|
||||
return current;
|
||||
for (const index of chain) {
|
||||
if (work++ % 256 === 0) yield;
|
||||
state[index] = 2;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
localPathStringSchema,
|
||||
} from "../localPath.js";
|
||||
import { canonicalBase64Schema } from "../stringPatterns.js";
|
||||
import { firstDeclaringTypeCycle } from "./il2cppDeclaringTypes.js";
|
||||
|
||||
/** Unsigned little-endian signature observed at file offset zero. */
|
||||
export const IL2CPP_METADATA_MAGIC = 0xfab11baf;
|
||||
@@ -452,7 +453,29 @@ const validateMetadataFacts = (
|
||||
"Only a code row carries an address and RVA; both are then present.",
|
||||
});
|
||||
});
|
||||
for (const collection of ["fields", "properties", "events"] as const)
|
||||
report.types.forEach((row, index) => {
|
||||
if (row.declaring_type >= report.types.length)
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
path: ["types", index, "declaring_type"],
|
||||
message: "Enclosing type is outside the retained type definitions.",
|
||||
});
|
||||
});
|
||||
const cycleWalk = firstDeclaringTypeCycle(report.types);
|
||||
let cycle = cycleWalk.next();
|
||||
while (!cycle.done) cycle = cycleWalk.next();
|
||||
if (cycle.value !== null)
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
path: ["types", cycle.value, "declaring_type"],
|
||||
message: "Enclosing type relationships contain a cycle.",
|
||||
});
|
||||
for (const collection of [
|
||||
"methods",
|
||||
"fields",
|
||||
"properties",
|
||||
"events",
|
||||
] as const)
|
||||
report[collection]?.forEach((row, index) => {
|
||||
if (row.declaring_type >= report.types.length)
|
||||
context.addIssue({
|
||||
|
||||
Reference in new issue
Block a user