mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 14:26:07 +00:00
Interpret the validated, depth-bounded DOM directly. Collect source number facts during the same traversal and share them with keyed archives, Interface Builder and native plist projections. Remove the second XML parse, key aliases, source-location rewriting and both duplicate XML numeric scanners. Preserve character references, container/null behavior, safe own-property construction and prototype omission accounting. Decode signed hexadecimal integers and combine real text/CDATA. Retain exact integer identity when a finite integer exceeds even Number's finite range, using the shared scalar projector. Keep unsupported mixed integer syntax conservative and report incomplete metadata. Adapt @apitoagents's hexadecimal regression and literal-parsing proposal from PR #3475. Native plutil controls establish the supported hex/real cases and confirm that the synthetic 401-digit overflow case exceeds native bounds; retaining accepted input does not claim native-format support. Validation: 274 focused checks in 30 files pass, one skipped; build, check:fast and docs:check pass. Built CLI/actual stdio MCP, native plist and Interface Builder controls cover kinds, references, exact digits and digests. Eight baseline checks fail; native binary conversion independently verifies updated CDATA real expectations. 48 tiny completed CLI cost comparisons preserve ordinary XML/binary and all three native replies byte for byte. Two read-only reviews clear. No statistical speed claim, heavy profiler, investigated-target execution or real deep-provider verification. Fixes #3373 Fixes #4042 Fixes #4789
170 lines
5.1 KiB
TypeScript
170 lines
5.1 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { build } from "plist";
|
|
import { expect } from "vitest";
|
|
|
|
import { keyedArchiveResultSchema } from "../../src/domain/apple/keyedArchive.js";
|
|
import type { JsonValue } from "../../src/domain/jsonValue.js";
|
|
import { createTestTempDirectory } from "./temporaryDirectory.js";
|
|
|
|
const EXACT_INTEGER = { $plist_type: "integer", decimal: "9007199254740993" };
|
|
const ROUNDED = 9007199254740992;
|
|
|
|
/** Accepted decoder representations whose supplemental metadata needs care. */
|
|
export const mixedArchiveNumberElements = [
|
|
"<integer>9007199254740992<!-- split -->3</integer>",
|
|
"<integer>9007199254740992<![CDATA[3]]></integer>",
|
|
"<integer><![CDATA[9007199254740992]]>3</integer>",
|
|
"<integer><![CDATA[90071992547409923]]></integer>",
|
|
"<integer>9007199254740992<?rea split?>3</integer>",
|
|
"<integer>9007199254740992<string>3</string></integer>",
|
|
"<integer>9007199254740992x</integer>",
|
|
] as const;
|
|
|
|
/** Ordinary dictionaries and malformed numeric references at the same boundary. */
|
|
export const archiveNumberMetadataCases = [
|
|
...[
|
|
{
|
|
element: "<real>9007199254740992<![CDATA[0]]></real>",
|
|
value: 90071992547409920,
|
|
},
|
|
{
|
|
element: "<real><![CDATA[1]]>9007199254740992</real>",
|
|
value: Number("19007199254740992"),
|
|
},
|
|
].map(({ element, value }) => ({
|
|
name: element,
|
|
source: { first: "__INTEGER__", other: "__OTHER__" },
|
|
element,
|
|
expected: { first: EXACT_INTEGER, other: value },
|
|
incomplete: false,
|
|
malformedReference: false,
|
|
})),
|
|
...mixedArchiveNumberElements.map((element) => ({
|
|
name: element,
|
|
source: { first: "__INTEGER__", other: "__OTHER__" },
|
|
element,
|
|
expected: { first: ROUNDED, other: ROUNDED },
|
|
incomplete: true,
|
|
malformedReference: false,
|
|
})),
|
|
...(["UID", "CF$UID"] as const).flatMap((key) => [
|
|
{
|
|
name: `${key} dictionary data`,
|
|
source: { [key]: { amount: "__INTEGER__" } },
|
|
element: "",
|
|
expected: { [key]: { amount: EXACT_INTEGER } },
|
|
incomplete: false,
|
|
malformedReference: false,
|
|
},
|
|
{
|
|
name: `${key} array data`,
|
|
source: { [key]: ["__INTEGER__"] },
|
|
element: "",
|
|
expected: { [key]: [EXACT_INTEGER] },
|
|
incomplete: false,
|
|
malformedReference: false,
|
|
},
|
|
{
|
|
name: `${key} malformed numeric reference`,
|
|
source: { [key]: "__INTEGER__" },
|
|
element: "",
|
|
expected: { [key]: ROUNDED },
|
|
incomplete: false,
|
|
malformedReference: true,
|
|
},
|
|
]),
|
|
{
|
|
name: "entity-encoded integer text",
|
|
source: { amount: "__INTEGER__" },
|
|
element: "",
|
|
expected: { amount: EXACT_INTEGER },
|
|
incomplete: false,
|
|
malformedReference: false,
|
|
integerElement: "<integer>9007199254740993</integer>",
|
|
},
|
|
] satisfies readonly {
|
|
name: string;
|
|
source: JsonValue;
|
|
element: string;
|
|
expected: JsonValue;
|
|
incomplete: boolean;
|
|
malformedReference: boolean;
|
|
integerElement?: string;
|
|
}[];
|
|
|
|
type MetadataCase = (typeof archiveNumberMetadataCases)[number];
|
|
|
|
/** Write one inert archive and retain the original byte digest for assertions. */
|
|
export const keyedArchiveNumberMetadataFixture = async (item: MetadataCase) => {
|
|
const root = await createTestTempDirectory("rea-keyed-number-metadata-");
|
|
const xml = build({
|
|
$archiver: "NSKeyedArchiver",
|
|
$version: 100000,
|
|
$objects: ["$null", item.source],
|
|
$top: { root: { CF$UID: 1 } },
|
|
})
|
|
.replace(
|
|
"<string>__INTEGER__</string>",
|
|
"integerElement" in item
|
|
? item.integerElement
|
|
: "<integer>9007199254740993</integer>",
|
|
)
|
|
.replace("<string>__OTHER__</string>", item.element);
|
|
const bytes = Buffer.from(xml);
|
|
const path = join(root, "archive.plist");
|
|
await writeFile(path, bytes);
|
|
return {
|
|
root,
|
|
path,
|
|
digest: createHash("sha256").update(bytes).digest("hex"),
|
|
};
|
|
};
|
|
|
|
/** Require exact ordinary values and honest limitations for incomplete metadata. */
|
|
export const expectKeyedArchiveNumberMetadata = (
|
|
value: unknown,
|
|
item: MetadataCase,
|
|
digest: string,
|
|
) => {
|
|
const result = keyedArchiveResultSchema.parse(value);
|
|
expect(result.archive_sha256).toBe(digest);
|
|
expect(result.roots).toEqual({ root: { CF$UID: 1 } });
|
|
expect(result.objects).toHaveLength(2);
|
|
expect(result.objects[1]).toMatchObject({
|
|
id: 1,
|
|
kind: "dictionary",
|
|
value: item.expected,
|
|
});
|
|
expect(result.references).toContainEqual({
|
|
source: null,
|
|
path: ["root"],
|
|
target: 1,
|
|
status: "resolved",
|
|
raw: { CF$UID: 1 },
|
|
});
|
|
if (item.incomplete) {
|
|
expect(result.limitations).toContainEqual(
|
|
expect.stringMatching(/metadata.*completely observed.*precision/u),
|
|
);
|
|
expect(
|
|
result.limitations.some((note) => note.includes("unambiguous integer")),
|
|
).toBe(false);
|
|
} else if (item.malformedReference) {
|
|
expect(result.references).toContainEqual({
|
|
source: 1,
|
|
path: [],
|
|
target: null,
|
|
status: "malformed",
|
|
raw: item.expected,
|
|
});
|
|
} else {
|
|
expect(result.references).toHaveLength(1);
|
|
expect(result.limitations).toContainEqual(
|
|
expect.stringMatching(/^1 unambiguous integer value/u),
|
|
);
|
|
}
|
|
};
|