fix(electron): report fixed fuse reader bounds as non-retryable

inspect-electron-fuses refused a slice with more than 32 sentinels as a
retryable capacity error advising to wait for an active analysis, and a file
over 1 GiB with advice to raise an evidence-reply file-size allowance. Both
are fixed reader bounds with no caller override, so mark them non-retryable
and name the reported bound in each remediation. Reported limits now come
from ELECTRON_FUSE_LIMITS instead of duplicated literals.

Fixes #5537

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822
2026-10-20 14:51:54 +00:00
parent d2a3269d0c
commit 83da234587
2 changed files with 28 additions and 5 deletions
+16 -3
View File
@@ -25,6 +25,7 @@ import {
} from "../filesystem/RegularFile.js";
import { ElectronFusePathFailure } from "./ElectronFusePath.js";
import {
ELECTRON_FUSE_LIMITS,
ElectronFuseFormatFailure,
ElectronFuseResourceFailure,
} from "./ElectronFuseReader.js";
@@ -91,9 +92,21 @@ export const electronFuseFailure = (
cause.boundary === "file-size" ? "file-size" : "capacity",
cause.message,
cause.boundary === "file-size"
? { maximum_input_bytes: 1024 * 1024 * 1024 }
: { maximum_sentinels_per_slice: 32 },
{ cause },
? { maximum_input_bytes: ELECTRON_FUSE_LIMITS.maximumFileBytes }
: {
maximum_sentinels_per_slice:
ELECTRON_FUSE_LIMITS.maximumSentinelsPerSlice,
},
{
cause,
// Both bounds are fixed reader limits with no caller override, so
// neither waiting nor a larger reply allowance admits the same file.
retryable: false,
remediationAction:
cause.boundary === "file-size"
? "Select an Electron executable within maximum_input_bytes; this fixed reader bound has no override, and retrying the unchanged file will fail again."
: "Select an Electron executable whose slices each contain at most maximum_sentinels_per_slice fuse sentinels; this fixed reader bound has no override, and retrying the unchanged file will fail again.",
},
);
if (cause instanceof ElectronFuseFormatFailure)
return cause.kind === "unsupported"
+12 -2
View File
@@ -573,10 +573,16 @@ it("enforces the 32 sentinel boundary with typed and public limit details", asyn
expect(result.ok).toBe(false);
if (!result.ok) {
expect(result.error._tag).toBe("AnalysisResourceConstraintError");
expect(projectAnalysisError(result.error)).toMatchObject({
const projected = projectAnalysisError(result.error);
expect(projected).toMatchObject({
code: "resource_constraint",
retryable: false,
details: { reported_limits: { maximum_sentinels_per_slice: 32 } },
});
expect(projected.remediation.action).toContain(
"maximum_sentinels_per_slice",
);
expect(projected.remediation.action).not.toMatch(/wait/iu);
}
}
}
@@ -591,10 +597,14 @@ it("rejects a sparse artifact over 1 GiB before scanning", async () => {
expect(result.ok).toBe(false);
if (!result.ok) {
expect(result.error._tag).toBe("AnalysisResourceConstraintError");
expect(projectAnalysisError(result.error)).toMatchObject({
const projected = projectAnalysisError(result.error);
expect(projected).toMatchObject({
code: "resource_constraint",
retryable: false,
details: { reported_limits: { maximum_input_bytes: 1024 * 1024 * 1024 } },
});
expect(projected.remediation.action).toContain("maximum_input_bytes");
expect(projected.remediation.action).not.toMatch(/allowance/iu);
}
});