fix(il2cpp): report the exceeded native-link maximum in the public refusal (#10741)

* fix(il2cpp): report the exceeded native-link maximum in the public refusal

* fix(il2cpp): report each native-link budget's maximum in the unit its producer counts

* refactor(elf): report pointer relocation failures through ParseFailure (#10748)
This commit is contained in:
morluto authored and GitHub committed 2026-11-15 13:44:54 +08:00
1 parent ad6e27e256
commit a090fa7098
13 files changed
+124 -29

No files matched your search

+8
View File
@@ -39,6 +39,9 @@ type Il2cppBinaryFormatReason = Exclude<
Il2cppBinaryCapacityReason
>;
/** What a native-link budget counts, so its maximum is reported with its unit. */
export type NativeBudgetUnit = "entries" | "bytes" | "frames";
/** The ParseFailure format of a native image linked against IL2CPP metadata. */
export const IL2CPP_BINARY_FORMAT = "il2cpp-binary";
@@ -55,16 +58,20 @@ const isUnsupported = (reason: Il2cppBinaryFormatReason) =>
export class Il2cppBinaryFormatFailure extends ParseFailureError<
"malformed" | "unsupported" | "limit"
> {
/** What the exceeded maximum counts; set only for a capacity reason. */
readonly unit: NativeBudgetUnit | undefined;
constructor(reason: Il2cppBinaryFormatReason, message: string);
constructor(
reason: Il2cppBinaryCapacityReason,
message: string,
maximum: number,
unit: NativeBudgetUnit,
);
constructor(
readonly reason: Il2cppBinaryFailureReason,
message: string,
maximum?: number,
unit?: NativeBudgetUnit,
) {
const detail = `${reason}: ${message}`;
super(
@@ -84,6 +91,7 @@ export class Il2cppBinaryFormatFailure extends ParseFailureError<
}
: { kind: "malformed", format: IL2CPP_BINARY_FORMAT, detail },
);
this.unit = unit;
this.name = "Il2cppBinaryFormatFailure";
}
}
+8 -6
View File
@@ -94,6 +94,7 @@ export function* openImageSteps(image: Buffer): Generator<void, NativeImage> {
"native-index-capacity",
cause.message,
cause.failure.limit.maximum,
"bytes",
);
if (cause instanceof BinaryFormatFailure)
throw new Il2cppBinaryFormatFailure(
@@ -126,14 +127,15 @@ export function* openImageSteps(image: Buffer): Generator<void, NativeImage> {
);
} catch (cause) {
if (cause instanceof ElfPointerRelocationFailure) {
if (cause.failure.kind === "limit" && cause.unit !== undefined)
throw new Il2cppBinaryFormatFailure(
"native-index-capacity",
cause.message,
cause.failure.limit.maximum,
cause.unit,
);
if (cause.reason !== "native-index-capacity")
throw new Il2cppBinaryFormatFailure(cause.reason, cause.message);
if (cause.maximum !== undefined)
throw new Il2cppBinaryFormatFailure(
cause.reason,
cause.message,
cause.maximum,
);
}
if (cause instanceof BinaryFormatFailure)
throw new Il2cppBinaryFormatFailure("malformed-container", cause.message);
+4
View File
@@ -113,6 +113,7 @@ function* nameAddresses(
"native-index-capacity",
`module-name trie exceeds its ${TOTAL_NAME_OCCURRENCES}-node workspace`,
TOTAL_NAME_OCCURRENCES,
"entries",
);
let node = root;
const bytes = Buffer.from(name, "utf8");
@@ -125,6 +126,7 @@ function* nameAddresses(
"native-index-capacity",
`module-name trie exceeds its ${TOTAL_NAME_OCCURRENCES}-node workspace`,
TOTAL_NAME_OCCURRENCES,
"entries",
);
next = { next: new Map(), owners: [] };
node.next.set(bytes[at]!, next);
@@ -165,6 +167,7 @@ function* nameAddresses(
"native-index-capacity",
`native name-address index exceeds ${TOTAL_NAME_OCCURRENCES} entries`,
TOTAL_NAME_OCCURRENCES,
"entries",
);
found.set(address, node.owners);
}
@@ -535,6 +538,7 @@ function* findModuleArrayByCode(
"native-index-capacity",
`module-array index exceeds ${MODULE_ARRAY_CANDIDATES} entries`,
MODULE_ARRAY_CANDIDATES,
"entries",
);
}
}
+2
View File
@@ -107,6 +107,7 @@ const createTypeRenderer = (
"native-type-text-capacity",
`rendered type text workspace exceeds ${TYPE_TEXT_BYTES} UTF-8 bytes`,
TYPE_TEXT_BYTES,
"bytes",
);
beforeText?.(bytes);
};
@@ -133,6 +134,7 @@ const createTypeRenderer = (
"type-nesting-capacity",
`type rendering exceeds ${TYPE_DEPTH} nested frames`,
TYPE_DEPTH,
"frames",
);
active.add(address);
try {
+11 -2
View File
@@ -83,12 +83,21 @@ const failureForPrimary = (
const { cause, origin } = facts;
if (origin === "owned-or-classified" && cause instanceof AnalysisError)
return cause;
if (cause instanceof Il2cppBinaryFormatFailure && cause.kind === "limit")
if (
cause instanceof Il2cppBinaryFormatFailure &&
cause.failure.kind === "limit"
)
return new AnalysisResourceConstraintError(
OPERATION,
cause.reason === "native-type-text-capacity" ? "memory" : "capacity",
cause.message,
{},
// The producing site states what its maximum counts.
{
boundary: cause.reason,
...(cause.unit === undefined
? {}
: { [`maximum_${cause.unit}`]: cause.failure.limit.maximum }),
},
{
cause,
...fixedAllowanceOptions(