fix(artifacts): preserve NIB key and class name identity (#2109)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
This commit is contained in:
parent
edd9939879
commit
e103a89889
|
|
@ -36,6 +36,22 @@ const archiveWithOverlappingObjectRanges = (objectCount: number): Buffer => {
|
|||
};
|
||||
|
||||
describe("NIBArchive decoder", () => {
|
||||
it("keeps leading U+FEFF in length-prefixed keys and class names", () => {
|
||||
const archive = encodeArchive({
|
||||
classes: ["\uFEFFWidget"],
|
||||
objects: [{ classIndex: 0, values: { count: 1, "\uFEFFcount": 2 } }],
|
||||
});
|
||||
expect(decodeNibArchive(archive).objects).toEqual([
|
||||
{
|
||||
id: 0,
|
||||
class_name: "\uFEFFWidget",
|
||||
values: { count: 1, "\uFEFFcount": 2 },
|
||||
},
|
||||
]);
|
||||
const invalid = Buffer.from(archive);
|
||||
invalid[invalid.indexOf(Buffer.from("\uFEFFcount"))] = 0xff;
|
||||
expect(() => decodeNibArchive(invalid)).toThrow(/not valid UTF-8/u);
|
||||
});
|
||||
it("decodes bounded object, key, class, and reference tables", () => {
|
||||
const archive = encodeArchive({
|
||||
classes: ["NSView\0", "NSString\0"],
|
||||
|
|
|
|||
|
|
@ -696,6 +696,49 @@ describe("NIB projection byte amplification", () => {
|
|||
});
|
||||
});
|
||||
|
||||
cliTest(
|
||||
"compiled CLI preserves distinct NIB keys and class identity",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-nib-name-identity-");
|
||||
const bundle = join(root, "Example.app");
|
||||
const resources = join(bundle, "Contents", "Resources");
|
||||
await mkdir(resources, { recursive: true });
|
||||
await mkdir(join(bundle, "Contents", "MacOS"), { recursive: true });
|
||||
await writeFile(
|
||||
join(bundle, "Contents", "MacOS", "App"),
|
||||
thinMach(0xfeedfacf, 0x0100000c),
|
||||
);
|
||||
await writeFile(
|
||||
join(bundle, "Contents", "Info.plist"),
|
||||
"<plist><dict><key>CFBundleExecutable</key><string>App</string></dict></plist>",
|
||||
);
|
||||
await writeFile(
|
||||
join(resources, "Identity.nib"),
|
||||
encodeNibArchiveFixture({
|
||||
classes: ["\uFEFFWidget"],
|
||||
objects: [{ classIndex: 0, values: { count: 1, "\uFEFFcount": 2 } }],
|
||||
}),
|
||||
);
|
||||
const output = await cli.run({
|
||||
arguments: ["decode-interface-builder", bundle, "--json"],
|
||||
environment: { REA_LOG_LEVEL: "silent", REA_ANALYSIS_PROVIDER: "auto" },
|
||||
});
|
||||
expect(output.exitCode, output.stderr).toBe(0);
|
||||
const result = interfaceBuilderAnalysisSchema.parse(
|
||||
parseEvidence(output.json).normalized_result,
|
||||
);
|
||||
expect(result.graph.nodes).toContainEqual(
|
||||
expect.objectContaining({
|
||||
attributes: expect.objectContaining({
|
||||
class_name: "\uFEFFWidget",
|
||||
nibValues: { count: 1, "\uFEFFcount": 2 },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(JSON.stringify(result)).toContain("\uFEFFWidget");
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"compiled CLI preserves a good archive and reports repeated key and data omissions",
|
||||
async ({ cli }) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue