Skip to content

Commit

Permalink
Test findArch prefered cases
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderOMara committed Jan 20, 2025
1 parent c9098f1 commit 457f5e8
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion macho/architecture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class Architecture {
* @returns Masked subtype ID.
*/
public cpuSubtype(): number {
return this.second & ~CPU_SUBTYPE_MASK;
return (this.second & ~CPU_SUBTYPE_MASK) >>> 0;
}

/**
Expand Down
142 changes: 142 additions & 0 deletions macho/universal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import {
} from '@std/assert';
import {
CPU_ARCH_ABI64,
CPU_SUBTYPE_ARM_ALL,
CPU_SUBTYPE_ARM_V7,
CPU_SUBTYPE_ARM_V8,
CPU_SUBTYPE_LIB64,
CPU_SUBTYPE_X86_ALL,
CPU_TYPE_ARM,
CPU_TYPE_X86,
FAT_MAGIC,
MH_DYLIB,
MH_EXECUTE,
Expand Down Expand Up @@ -262,6 +268,142 @@ Deno.test('open suspicious read error', async () => {
assertEquals(uni.isSuspicious(), true);
});

Deno.test('findArch case 1: prefer full exact match', async () => {
const data = new ArrayBuffer(256 * 3);
const header = new FatHeader(data);
header.magic = FAT_MAGIC;
header.nfatArch = 2;

const arch1 = new FatArch(data, header.byteLength);
arch1.offset = 256;
arch1.size = 256;
arch1.align = 8;
arch1.cputype = CPU_TYPE_ARM;
arch1.cpusubtype = CPU_SUBTYPE_ARM_V8;

const arch2 = new FatArch(data, arch1.byteOffset + arch1.byteLength);
arch2.offset = 256 * 2;
arch2.size = 256;
arch2.align = 8;
arch2.cputype = CPU_TYPE_ARM;
arch2.cpusubtype = CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_ARM_V8;

const uni = new Universal();
await uni.open(new Blob([data]));

assertEquals(
uni.archOffset(
new Architecture(
CPU_TYPE_ARM,
CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_ARM_V8,
),
),
arch2.offset,
);
});

Deno.test('findArch case 2: prefer masked subtype equal to all', async () => {
const data = new ArrayBuffer(256 * 3);
const header = new FatHeader(data);
header.magic = FAT_MAGIC;
header.nfatArch = 2;

const arch1 = new FatArch(data, header.byteLength);
arch1.offset = 256;
arch1.size = 256;
arch1.align = 8;
arch1.cputype = CPU_TYPE_ARM;
arch1.cpusubtype = CPU_SUBTYPE_ARM_ALL;

const arch2 = new FatArch(data, arch1.byteOffset + arch1.byteLength);
arch2.offset = 256 * 2;
arch2.size = 256;
arch2.align = 8;
arch2.cputype = CPU_TYPE_ARM;
arch2.cpusubtype = CPU_SUBTYPE_ARM_V8;

const uni = new Universal();
await uni.open(new Blob([data]));

assertEquals(
uni.archOffset(
new Architecture(
CPU_TYPE_ARM,
CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_ARM_V8,
),
),
arch2.offset,
);
});

Deno.test('findArch case 3: prefer all subtype to mismatch', async () => {
const data = new ArrayBuffer(256 * 3);
const header = new FatHeader(data);
header.magic = FAT_MAGIC;
header.nfatArch = 2;

const arch1 = new FatArch(data, header.byteLength);
arch1.offset = 256;
arch1.size = 256;
arch1.align = 8;
arch1.cputype = CPU_TYPE_ARM;
arch1.cpusubtype = CPU_SUBTYPE_ARM_V7;

const arch2 = new FatArch(data, arch1.byteOffset + arch1.byteLength);
arch2.offset = 256 * 2;
arch2.size = 256;
arch2.align = 8;
arch2.cputype = CPU_TYPE_ARM;
arch2.cpusubtype = CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_ARM_ALL;

const uni = new Universal();
await uni.open(new Blob([data]));

assertEquals(
uni.archOffset(
new Architecture(
CPU_TYPE_ARM,
CPU_SUBTYPE_ARM_V8,
),
),
arch2.offset,
);
});

Deno.test('findArch case 4: accept equal type as last resort', async () => {
const data = new ArrayBuffer(256 * 3);
const header = new FatHeader(data);
header.magic = FAT_MAGIC;
header.nfatArch = 2;

const arch1 = new FatArch(data, header.byteLength);
arch1.offset = 256;
arch1.size = 256;
arch1.align = 8;
arch1.cputype = CPU_TYPE_X86;
arch1.cpusubtype = CPU_SUBTYPE_X86_ALL;

const arch2 = new FatArch(data, arch1.byteOffset + arch1.byteLength);
arch2.offset = 256 * 2;
arch2.size = 256;
arch2.align = 8;
arch2.cputype = CPU_TYPE_ARM;
arch2.cpusubtype = CPU_SUBTYPE_ARM_V7;

const uni = new Universal();
await uni.open(new Blob([data]));

assertEquals(
uni.archOffset(
new Architecture(
CPU_TYPE_ARM,
CPU_SUBTYPE_ARM_V8,
),
),
arch2.offset,
);
});

Deno.test('typeOf under header', async () => {
const blob = new Blob([new ArrayBuffer(MachHeader.BYTE_LENGTH - 1)]);
assertEquals(await Universal.typeOf(blob), 0);
Expand Down

0 comments on commit 457f5e8

Please sign in to comment.