Files
rea/scripts/verify/apple/keyed-archive.mjs
T
morlutoandRudy Mizrahi Celekli 4034883e98 fix(artifacts): preserve keyed archive integer precision
Integrate the numeric precision correction from #1135 with complete supplemental
metadata handling. Keep decoded numbers with an explicit limitation for mixed XML
content or unclassified integer text, rather than assigning another literal's
exact decimal. Project nonnumeric UID and CF$UID dictionary values recursively
while preserving numeric references, graph identity and original byte digests.

Add filesystem, built CLI and MCP regressions for the review findings, adjacent
XML representations and numeric reference controls. Retain the original native
Foundation qualification fixtures and verifier.

Verification: 84 focused tests; npm run check; npm run docs:check;
npm run verify:test-discovery; npm run verify:keyed-archive (real Foundation,
CLI and stdio MCP). No real Hopper or Ghidra verification was needed or run.

Co-authored-by: Rudy Mizrahi Celekli <47457359+rudycelekli@users.noreply.github.com>
Signed-off-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 07:13:32 +08:00

192 lines
5.1 KiB
JavaScript

import { execFile, spawnSync } from "node:child_process";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { promisify } from "node:util";
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import {
artifactCli,
artifactMcpResult,
withArtifactMcp,
} from "../../lib/artifact-e2e.mjs";
if (process.platform !== "darwin")
throw new Error(
"Real Foundation keyed archive verification requires macOS and Xcode Swift tools",
);
const root = await mkdtemp(join(tmpdir(), "rea-keyed-fixture-"));
let report;
try {
const archive = join(root, "model.plist");
await promisify(execFile)("/usr/bin/xcrun", [
"swift",
"-module-cache-path",
join(root, "modules"),
fileURLToPath(
new URL(
"../../../tests/conformance/native/keyed-archive.swift",
import.meta.url,
),
),
archive,
]);
const graph = await artifactCli("inspect-keyed-archive", archive);
const digest = createHash("sha256")
.update(await readFile(archive))
.digest("hex");
assert.equal(graph.archive_sha256, digest);
assert.equal(graph.target_sha256, digest);
await withArtifactMcp(archive, async (client) => {
assert.deepEqual(
await artifactMcpResult(client, "inspect_keyed_archive"),
graph,
);
const page = await artifactMcpResult(client, "inspect_keyed_archive", {
offset: 1,
limit: 1,
});
assert.deepEqual(page.objects, [graph.objects[1]]);
assert.equal(page.next_offset, 2);
const invalid = await client.callTool({
name: "inspect_keyed_archive",
arguments: { path: "../other.plist" },
});
assert.equal(invalid.isError, true);
});
const xml = join(root, "model.xml.plist");
await promisify(execFile)("/usr/bin/plutil", [
"-convert",
"xml1",
"-o",
xml,
archive,
]);
const xmlGraph = await artifactCli("inspect-keyed-archive", xml);
const expected = JSON.parse(
await readFile(
new URL(
"../../../tests/fixtures/golden/keyed-archive/graph.json",
import.meta.url,
),
"utf8",
),
);
assert.deepEqual(
Object.fromEntries(
Object.entries(xmlGraph).filter(
([key]) =>
!["archive_path", "archive_sha256", "target_sha256"].includes(key),
),
),
expected,
);
assert.deepEqual(
graph.references.map(({ source, path, target, status }) => ({
source,
path,
target,
status,
})),
xmlGraph.references.map(({ source, path, target, status }) => ({
source,
path,
target,
status,
})),
);
if (
graph?.archive_format !== "binary-plist" ||
!graph.references.some(
(link) =>
link.source !== null &&
link.source === link.target &&
link.status === "resolved",
) ||
!graph.objects.some((item) => item.class_name?.includes("ReaArchiveRecord"))
)
throw new Error(
`Real Foundation archive graph drifted: ${JSON.stringify(graph)}`,
);
const record = graph.objects.find((item) =>
item.class_name?.includes("ReaArchiveRecord"),
);
if (
graph.references.filter(
(link) => link.target === record.id && link.source !== record.id,
).length < 2
)
throw new Error("Real shared object identity was not preserved");
const uidRoot = join(root, "uid-root.plist");
await promisify(execFile)("/usr/bin/xcrun", [
"swift",
"-module-cache-path",
join(root, "modules"),
fileURLToPath(
new URL(
"../../../tests/conformance/native/keyed-archive-uid-root.swift",
import.meta.url,
),
),
uidRoot,
]);
const uidRootXml = join(root, "uid-root.xml.plist");
await promisify(execFile)("/usr/bin/plutil", [
"-convert",
"xml1",
"-o",
uidRootXml,
uidRoot,
]);
for (const path of [uidRoot, uidRootXml]) {
const uidGraph = await artifactCli("inspect-keyed-archive", path);
assert.deepEqual(
uidGraph.references.map(({ source, path, target, status }) => ({
source,
path,
target,
status,
})),
[{ source: null, path: ["UID"], target: 1, status: "resolved" }],
);
}
const numericTests = spawnSync(
"npm",
[
"run",
"test:focused",
"--",
"tests/boundary/filesystem/keyedArchiveNativeIntegers.test.ts",
],
{
cwd: fileURLToPath(new URL("../../../", import.meta.url)),
stdio: "inherit",
timeout: 240_000,
},
);
if (numericTests.error) throw numericTests.error;
assert.equal(
numericTests.status,
0,
"Native Foundation integer cases failed",
);
report = {
ok: true,
mocked: false,
cli: true,
stdio_mcp: true,
xml_golden: true,
uid_named_root: true,
format: graph.archive_format,
objects: graph.total_objects,
references: graph.total_references,
shared_identity: true,
cyclic_identity: true,
target_classes_instantiated_by_reader: false,
};
} finally {
await rm(root, { recursive: true, force: true });
}
process.stdout.write(`${JSON.stringify(report)}\n`);