fix(il2cpp): validate generic-container extents before index widths

Validate the fixed 16-byte version-39 records before using their count to select the serialized index width. Reject contradictory count and byte extents while preserving valid zero, one and 300-record controls.

Validation: 89 focused reader/provider/compiled CLI and stdio MCP tests; check:ci; seven reproduced CLI and SDK-validated MCP cases with unchanged fixture hashes. Version-specific source and independent parser evidence distinguish fixed records from compressed indices. Synthetic metadata only; no real-game or target-execution qualification.

Fixes #5751
This commit is contained in:
morluto
2026-10-21 12:55:35 +08:00
parent afa5da745e
commit fa8b87c470
3 changed files with 143 additions and 10 deletions
+13 -3
View File
@@ -253,15 +253,25 @@ const FIXED_WIDTHS: Il2cppMetadataDecoded["index_widths"] = {
type_width_source: "fixed-width-version",
};
const GENERIC_CONTAINER_RECORD_BYTES = 16;
const resolveWidths = (
section: (name: SectionName) => Il2cppMetadataSection,
): Il2cppMetadataDecoded["index_widths"] => {
const genericContainers = section("genericContainers");
const genericContainerBytes = recordBytes(genericContainers);
if (
genericContainerBytes !== null &&
genericContainerBytes !== GENERIC_CONTAINER_RECORD_BYTES
)
throw new Il2cppMetadataFormatFailure(
"record-size-mismatch",
`section genericContainers records are ${genericContainerBytes} bytes, but each record is ${GENERIC_CONTAINER_RECORD_BYTES}`,
);
const type_definition = il2cppIndexWidth(
headerCount(section("typeDefinitions")),
);
const generic_container = il2cppIndexWidth(
headerCount(section("genericContainers")),
);
const generic_container = il2cppIndexWidth(headerCount(genericContainers));
const parameter = il2cppIndexWidth(headerCount(section("parameters")));
// TypeIndex counts native types, so its width is recovered from records.
const interfaceOffset = recordBytes(section("interfaceOffsets"));