mirror of
https://github.com/morluto/rea.git
synced 2026-11-13 18:22:42 +00:00
fix(native): bind initializer evidence to selected Mach-O slices (#10013)
* fix(native): bind initializer evidence to selected Mach-O slices * fix(native): reject initializer slices outside the artifact * test(native): retain completed initializer evidence on late cancellation completeProviderEvidence keeps the finished report on AnalysisCancelledError.partialObservation and the caller's abort reason. The regression only checked the error tag, so dropping that evidence would pass. Restore both structured assertions. * fix(native): bind initializer facts to the selected slice label and range A universal report could keep an arm64 cpu_type beside an x86_64 slice label, and entry file offsets only had to fall inside the container. Require the slice architecture to match the request, and require each slot and value file offset to lie in that slice. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
1 parent
7f0555b75e
commit
5b02119b69
2 files changed
+233
-6
No files matched your search
@@ -12,6 +12,7 @@ import {
|
||||
import { err, type Result } from "../../domain/result.js";
|
||||
import { completeProviderEvidence } from "../ProviderOperationExecution.js";
|
||||
import { parseAnalysisInput } from "../AnalysisInput.js";
|
||||
import { MACHO_CPU_TYPES } from "../../domain/apple/machoTargetSelection.js";
|
||||
|
||||
const OPERATION = "inspect_native_initializers";
|
||||
|
||||
@@ -67,7 +68,7 @@ export class NativeInitializersService {
|
||||
createEvidence(
|
||||
{
|
||||
path: value.artifact.path,
|
||||
format: value.format,
|
||||
format: value.slice === null ? value.format : "mach-o-universal",
|
||||
sha256: value.artifact.sha256,
|
||||
...(value.architecture === null
|
||||
? {}
|
||||
@@ -93,9 +94,28 @@ const validReport = (
|
||||
input: InspectNativeInitializersInput,
|
||||
): boolean => {
|
||||
const { coverage } = report;
|
||||
const inside = (offset: number | null, bytes: number): boolean =>
|
||||
offset === null || offset <= report.artifact.bytes - bytes;
|
||||
const slice = report.slice;
|
||||
if (
|
||||
slice === null
|
||||
? input.architecture !== undefined
|
||||
: report.format !== "mach-o" ||
|
||||
input.architecture === undefined ||
|
||||
slice.cpu_type !== MACHO_CPU_TYPES[input.architecture] ||
|
||||
slice.architecture !== input.architecture ||
|
||||
report.machine !== slice.cpu_type ||
|
||||
report.architecture !== input.architecture
|
||||
)
|
||||
return false;
|
||||
const insideArtifact = (offset: number, bytes: number): boolean =>
|
||||
offset <= report.artifact.bytes - bytes;
|
||||
// Entry file offsets name the selected image, not another slice in the container.
|
||||
const imageStart = slice?.file_offset ?? 0;
|
||||
const imageEnd =
|
||||
slice === null ? report.artifact.bytes : slice.file_offset + slice.size;
|
||||
const insideImage = (offset: number | null, bytes: number): boolean =>
|
||||
offset === null || (offset >= imageStart && bytes <= imageEnd - offset);
|
||||
if (
|
||||
(slice !== null && !insideArtifact(slice.file_offset, slice.size)) ||
|
||||
report.artifact.bytes > input.max_file_bytes ||
|
||||
coverage.offset !== input.offset ||
|
||||
coverage.limit !== input.limit ||
|
||||
@@ -109,7 +129,7 @@ const validReport = (
|
||||
return report.entries.every(
|
||||
(entry, position) =>
|
||||
entry.index === coverage.offset + position &&
|
||||
inside(entry.slot_file_offset, entry.slot_bytes) &&
|
||||
inside(entry.value_file_offset, 1),
|
||||
insideImage(entry.slot_file_offset, entry.slot_bytes) &&
|
||||
insideImage(entry.value_file_offset, 1),
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user