mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(metadata): preserve canonical PowerPC subject identity
This commit is contained in:
@@ -200,3 +200,8 @@ those questions require a disassembler.
|
||||
`npm run verify:go:binary` exercises compiler-built fixtures through the public
|
||||
CLI and MCP, comparing their metadata with Go's standard `debug/buildinfo`
|
||||
reader. The verification lane requires Go; normal inspection does not.
|
||||
|
||||
Reader architecture names remain verbatim in the report. Evidence subjects use
|
||||
the recognized canonical family: `386` maps to `x86`, `amd64` to `x86_64`, and
|
||||
`ppc` to `powerpc`. Unknown families such as `ppc64` remain unknown rather than
|
||||
being inferred from a related spelling.
|
||||
|
||||
@@ -165,3 +165,8 @@ Package and dependency counts are checked against the minimum required JSON
|
||||
representation before graph allocation or schema cloning. Oversized graphs
|
||||
report the output byte budget; the compiler-path capacity reports
|
||||
`maximum_rustc_hashes` in hashes, independently of byte limits.
|
||||
|
||||
Reader architecture names remain verbatim in the report. Evidence subjects use
|
||||
the recognized canonical family: `386` maps to `x86`, `amd64` to `x86_64`, and
|
||||
`ppc` to `powerpc`. Unknown families such as `ppc64` remain unknown rather than
|
||||
being inferred from a related spelling.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { binaryMetadataArchitecture } from "../../domain/binaryMetadataArchitecture.js";
|
||||
import { metadataReportSubjectFormat } from "../../domain/apple/machoTargetSelection.js";
|
||||
import type { ExecutionOptions } from "../AnalysisProvider.js";
|
||||
import type { GoBinaryPort } from "./GoBinaryPort.js";
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
} from "../../domain/analysisErrorCore.js";
|
||||
import { createEvidence, type Evidence } from "../../domain/evidence.js";
|
||||
import {
|
||||
goArchitectureForSubject,
|
||||
goBinarySchema,
|
||||
inspectGoBinaryInputSchema,
|
||||
} from "../../domain/go/goBinary.js";
|
||||
@@ -68,7 +68,7 @@ export class GoBinaryService {
|
||||
),
|
||||
);
|
||||
const value = report.data;
|
||||
const architecture = goArchitectureForSubject(value.architecture);
|
||||
const architecture = binaryMetadataArchitecture(value.architecture);
|
||||
const completed = completeProviderEvidence(
|
||||
createEvidence(
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { binaryMetadataArchitecture } from "../../domain/binaryMetadataArchitecture.js";
|
||||
import { metadataReportSubjectFormat } from "../../domain/apple/machoTargetSelection.js";
|
||||
import type { ExecutionOptions } from "../AnalysisProvider.js";
|
||||
import type { RustBinaryPort } from "./RustBinaryPort.js";
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
} from "../../domain/analysisErrorCore.js";
|
||||
import { createEvidence, type Evidence } from "../../domain/evidence.js";
|
||||
import {
|
||||
rustArchitectureForSubject,
|
||||
rustBinarySchema,
|
||||
type InspectRustBinaryInput,
|
||||
} from "../../domain/rust/rustBinary.js";
|
||||
@@ -87,7 +87,7 @@ const evidenceFor = (
|
||||
parameters: InspectRustBinaryInput,
|
||||
value: ReturnType<typeof rustBinarySchema.parse>,
|
||||
): Evidence => {
|
||||
const architecture = rustArchitectureForSubject(value.architecture);
|
||||
const architecture = binaryMetadataArchitecture(value.architecture);
|
||||
const section = value.auditable_metadata;
|
||||
return createEvidence(
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { binaryMetadataArchitecture } from "../binaryMetadataArchitecture.js";
|
||||
import { metadataReportSubjectFormat } from "../apple/machoTargetSelection.js";
|
||||
import { z } from "zod";
|
||||
import type { AnalysisError } from "../analysisErrorBase.js";
|
||||
import {
|
||||
goArchitectureForSubject,
|
||||
goBinarySchema,
|
||||
goBuildInfoSchema,
|
||||
goModuleMetadataSchema,
|
||||
@@ -149,7 +149,7 @@ export const projectGoBinaryView = (
|
||||
parent.subject.digest.sha256 !== report.artifact.sha256 ||
|
||||
parent.subject.format !== metadataReportSubjectFormat(report) ||
|
||||
parent.subject.architecture !==
|
||||
(goArchitectureForSubject(report.architecture) ?? null)
|
||||
(binaryMetadataArchitecture(report.architecture) ?? null)
|
||||
)
|
||||
return err(
|
||||
analysisViewInputError([
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { binaryMetadataArchitecture } from "../binaryMetadataArchitecture.js";
|
||||
import { metadataReportSubjectFormat } from "../apple/machoTargetSelection.js";
|
||||
import { z } from "zod";
|
||||
import type { AnalysisError } from "../analysisErrorBase.js";
|
||||
import {
|
||||
rustArchitectureForSubject,
|
||||
rustBinarySchema,
|
||||
rustAuditableMetadataSchema,
|
||||
rustcCommitSchema,
|
||||
@@ -159,7 +159,7 @@ export const projectRustBinaryView = (
|
||||
subject.digest.sha256 !== report.artifact.sha256 ||
|
||||
subject.format !== metadataReportSubjectFormat(report) ||
|
||||
subject.architecture !==
|
||||
(rustArchitectureForSubject(report.architecture) ?? null)
|
||||
(binaryMetadataArchitecture(report.architecture) ?? null)
|
||||
)
|
||||
return err(
|
||||
analysisViewInputError([
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { BINARY_ARCHITECTURES } from "./binaryTargetTypes.js";
|
||||
|
||||
/** Preserve reader spellings while retaining recognized Evidence CPU families. */
|
||||
export const binaryMetadataArchitecture = (architecture: string) => {
|
||||
switch (architecture) {
|
||||
case "386":
|
||||
return "x86";
|
||||
case "amd64":
|
||||
return "x86_64";
|
||||
case "ppc":
|
||||
return "powerpc";
|
||||
default:
|
||||
return BINARY_ARCHITECTURES.find(
|
||||
(supported) => supported === architecture,
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import { BINARY_ARCHITECTURES } from "../binaryTargetTypes.js";
|
||||
import { binaryMetadataArchitecture } from "../binaryMetadataArchitecture.js";
|
||||
import {
|
||||
machoSelectionContainsRange,
|
||||
selectedSliceAgreesWithReport,
|
||||
@@ -13,20 +13,6 @@ import {
|
||||
} from "../localPath.js";
|
||||
import { canonicalBase64Schema } from "../stringPatterns.js";
|
||||
|
||||
/** Map reader architecture names into Evidence identity; unknown names stay unknown. */
|
||||
export const goArchitectureForSubject = (architecture: string) => {
|
||||
switch (architecture) {
|
||||
case "386":
|
||||
return "x86";
|
||||
case "amd64":
|
||||
return "x86_64";
|
||||
default:
|
||||
return BINARY_ARCHITECTURES.find(
|
||||
(supported) => supported === architecture,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const sourceRangeSchema = z.strictObject({
|
||||
offset: z.int().nonnegative(),
|
||||
bytes: z.int().nonnegative(),
|
||||
@@ -105,7 +91,7 @@ export const goBinarySchema = z
|
||||
(!selectedSliceAgreesWithReport(
|
||||
slice,
|
||||
report.format,
|
||||
goArchitectureForSubject(report.architecture),
|
||||
binaryMetadataArchitecture(report.architecture),
|
||||
) ||
|
||||
!machoSelectionContainsRange(
|
||||
slice,
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
absoluteLocalPathStringSchema,
|
||||
localPathStringSchema,
|
||||
} from "../localPath.js";
|
||||
import { BINARY_ARCHITECTURES } from "../binaryTargetTypes.js";
|
||||
import { binaryMetadataArchitecture } from "../binaryMetadataArchitecture.js";
|
||||
import {
|
||||
machoSelectionContainsRange,
|
||||
selectedSliceAgreesWithReport,
|
||||
@@ -12,20 +12,6 @@ import {
|
||||
machoTargetSelectionSchema,
|
||||
} from "../apple/machoTargetSelection.js";
|
||||
|
||||
/** Preserve the format owner's architecture spelling separately from Evidence vocabulary. */
|
||||
export const rustArchitectureForSubject = (architecture: string) => {
|
||||
switch (architecture) {
|
||||
case "386":
|
||||
return "x86";
|
||||
case "amd64":
|
||||
return "x86_64";
|
||||
default:
|
||||
return BINARY_ARCHITECTURES.find(
|
||||
(supported) => supported === architecture,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/** Known revisions used to interpret compatible cargo-auditable documents. */
|
||||
export const RUST_AUDITABLE_FORMAT_VERSIONS = [0, 1, 8] as const;
|
||||
|
||||
@@ -331,7 +317,7 @@ const checkSlice = (report: RustBinary, context: z.RefinementCtx): void => {
|
||||
!selectedSliceAgreesWithReport(
|
||||
slice,
|
||||
report.format,
|
||||
rustArchitectureForSubject(report.architecture),
|
||||
binaryMetadataArchitecture(report.architecture),
|
||||
) ||
|
||||
ranges.some(
|
||||
({ offset, bytes }) =>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect, it } from "vitest";
|
||||
import { GoBinaryService } from "../../src/application/go/GoBinaryService.js";
|
||||
import { RustBinaryService } from "../../src/application/rust/RustBinaryService.js";
|
||||
import { elf } from "../../src/domain/binaryTarget.fixture.js";
|
||||
import { GoBinaryProvider } from "../../src/go/GoBinaryProvider.js";
|
||||
import { RustBinaryProvider } from "../../src/rust/RustBinaryProvider.js";
|
||||
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
||||
|
||||
it.each([
|
||||
[1, 1, 20, "ppc", "powerpc"],
|
||||
[1, 2, 20, "ppc", "powerpc"],
|
||||
[1, 1, 3, "386", "x86"],
|
||||
[2, 1, 62, "amd64", "x86_64"],
|
||||
[2, 2, 21, "ppc64", null],
|
||||
] as const)(
|
||||
"preserves ELF class%d byte-order%d machine%d in Go and Rust subjects",
|
||||
async (bits, endian, machine, local, canonical) => {
|
||||
const root = await createTestTempDirectory("rea-metadata-subject-");
|
||||
const path = join(root, "header.elf");
|
||||
const bytes = elf(bits, endian, machine);
|
||||
await writeFile(path, bytes);
|
||||
for (const service of [
|
||||
new GoBinaryService(new GoBinaryProvider()),
|
||||
new RustBinaryService(new RustBinaryProvider()),
|
||||
]) {
|
||||
const result = await service.inspect({ path });
|
||||
expect(result.ok).toBe(true);
|
||||
if (!result.ok) throw result.error;
|
||||
expect(result.value.subject).toMatchObject({
|
||||
architecture: canonical,
|
||||
digest: { sha256: createHash("sha256").update(bytes).digest("hex") },
|
||||
});
|
||||
expect(result.value.normalized_result).toMatchObject({
|
||||
architecture: local,
|
||||
bits: bits === 1 ? 32 : 64,
|
||||
byte_order: endian === 1 ? "little" : "big",
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user