import { test } from 'node:test'; import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; // 格式断言 fixture:技能里对**字节布局**的断言,可以用纯代码构造的最小样本验证, // 不依赖网络与外部样本。这类断言最贵——写错一个字整条解析链都错。 // 首个 fixture 对应 re-format-elf/references/layout.md 的「扩展编号三套规则」 // (该处原文即注明"建议配 parser fixture 验证这三条路径")。 const U16 = (b, o) => b.readUInt16LE(o); const U32 = (b, o) => b.readUInt32LE(o); const U64 = (b, o) => Number(b.readBigUInt64LE(o)); /** 构造一个带扩展编号的 ELF64:三个哨兵值全用上,真值放在 section 0 */ function buildElfWithExtendedNumbering({ phnum = 2, shnum = 3, shstrndx = 2 } = {}) { const EHSIZE = 64, PHENTSIZE = 56, SHENTSIZE = 64; const e_phoff = EHSIZE; const e_shoff = EHSIZE + phnum * PHENTSIZE; const buf = Buffer.alloc(e_shoff + shnum * SHENTSIZE); // e_ident buf.write('\x7fELF', 0, 'latin1'); buf[4] = 2; // EI_CLASS = ELFCLASS64 buf[5] = 1; // EI_DATA = ELFDATA2LSB buf[6] = 1; // EI_VERSION buf[7] = 0; // EI_OSABI = NONE buf.writeUInt16LE(2, 16); // e_type = ET_EXEC buf.writeUInt16LE(0x3e, 18); // e_machine = x86-64 buf.writeUInt32LE(1, 20); // e_version buf.writeBigUInt64LE(0n, 24); // e_entry buf.writeBigUInt64LE(BigInt(e_phoff), 32); buf.writeBigUInt64LE(BigInt(e_shoff), 40); buf.writeUInt32LE(0, 48); // e_flags buf.writeUInt16LE(EHSIZE, 52); // e_ehsize buf.writeUInt16LE(PHENTSIZE, 54); // e_phentsize buf.writeUInt16LE(0xffff, 56); // e_phnum = PN_XNUM ← 哨兵 1 buf.writeUInt16LE(SHENTSIZE, 58); // e_shentsize buf.writeUInt16LE(0, 60); // e_shnum = 0 ← 哨兵 2 buf.writeUInt16LE(0xffff, 62); // e_shstrndx = SHN_XINDEX ← 哨兵 3 // section 0:SHT_NULL,承载三个真值 const s0 = e_shoff; buf.writeUInt32LE(0, s0 + 0); // sh_name buf.writeUInt32LE(0, s0 + 4); // sh_type = SHT_NULL buf.writeBigUInt64LE(BigInt(shnum), s0 + 32); // sh_size = 真实节数(offset 是 Number,值是 BigInt) buf.writeUInt32LE(shstrndx, s0 + 40); // sh_link = 真实 shstrndx buf.writeUInt32LE(phnum, s0 + 44); // sh_info = 真实程序头数 return buf; } /** 按 layout.md 的三套规则解析(与被测断言一一对应) */ function parsePerExtendedNumberingRules(buf) { const e_phnum = U16(buf, 56), e_shnum = U16(buf, 60), e_shstrndx = U16(buf, 62); const e_shoff = U64(buf, 40); const sh = (i, field) => { // 节头表里第 i 项的某字段 const base = e_shoff + i * U16(buf, 58); return { name: U32(buf, base), type: U32(buf, base + 4), size: U64(buf, base + 32), link: U32(buf, base + 40), info: U32(buf, base + 44), }[field]; }; return { phnum: e_phnum === 0xffff ? sh(0, 'info') : e_phnum, // PN_XNUM shnum: e_shnum === 0 ? sh(0, 'size') : e_shnum, // e_shnum == 0 shstrndx: e_shstrndx === 0xffff ? sh(0, 'link') : e_shstrndx, // SHN_XINDEX }; } test('ELF 扩展编号三套规则:三个哨兵值分别落在 shdr[0] 的 sh_info / sh_size / sh_link', () => { const buf = buildElfWithExtendedNumbering({ phnum: 7, shnum: 11, shstrndx: 5 }); // 哨兵确实写在头部(否则测的不是扩展编号这条路径) assert.equal(U16(buf, 56), 0xffff, 'e_phnum 应为 PN_XNUM'); assert.equal(U16(buf, 60), 0, 'e_shnum 应为 0'); assert.equal(U16(buf, 62), 0xffff, 'e_shstrndx 应为 SHN_XINDEX'); // 按规则解析出的真值 const r = parsePerExtendedNumberingRules(buf); assert.deepEqual(r, { phnum: 7, shnum: 11, shstrndx: 5 }); // 三条规则落在**不同字段**上——共用一个字段就会互相覆盖 assert.notEqual(parsePerExtendedNumberingRules(buf).phnum, U16(buf, 60)); }); test('ELF 魔数的字节序:字节 7f 45 4c 46,小端 u32 得 0x464c457f、大端得 0x7f454c46', () => { const buf = buildElfWithExtendedNumbering(); assert.equal(buf.subarray(0, 4).toString('hex'), '7f454c46'); assert.equal(buf.readUInt32LE(0), 0x464c457f); assert.equal(buf.readUInt32BE(0), 0x7f454c46); }); test('readelf 对同一 fixture 的解读与三条规则一致(有 readelf 时才跑)', () => { let has = true; try { execFileSync('readelf', ['--version'], { stdio: 'ignore' }); } catch { has = false; } if (!has) return; // 无 binutils 时跳过:本测试的价值是"用独立实现交叉验证我们自己写的解析" const dir = mkdtempSync(join(tmpdir(), 'elffx-')); const p = join(dir, 'ext.elf'); writeFileSync(p, buildElfWithExtendedNumbering({ phnum: 7, shnum: 11, shstrndx: 5 })); // 固定 LC_ALL=C:本地化的 readelf 会把字段名译成"程序头数量:"等,正则匹配不到 const out = execFileSync('readelf', ['-h', p], { encoding: 'utf8', env: { ...process.env, LC_ALL: 'C' } }); // readelf 的显示约定:**原始哨兵值 (括号内为按规则解析出的真值)**,如 `Number of program headers: 65535 (7)` const resolved = (label) => { const m = new RegExp(`${label}:\\s+(\\d+) \\((\\d+)\\)`).exec(out); return m ? { raw: Number(m[1]), real: Number(m[2]) } : null; }; assert.deepEqual(resolved('Number of program headers'), { raw: 0xffff, real: 7 }); assert.deepEqual(resolved('Number of section headers'), { raw: 0, real: 11 }); assert.deepEqual(resolved('Section header string table index'), { raw: 0xffff, real: 5 }); rmSync(dir, { recursive: true, force: true }); }); // 对应 re-flutter/SKILL.md:Dart 的两个 magic 都是**数值**,文件里是小端字节——不是可 grep 的 ASCII 串 test('Dart kernel magic 0x90abcdef 与 snapshot magic 0xdcdcf5f5 的字节形态', () => { const kernel = Buffer.alloc(4); kernel.writeUInt32LE(0x90abcdef); assert.equal(kernel.toString('hex'), 'efcdab90'); assert.notEqual(kernel.toString('latin1'), 'KERNEL'); const snap = Buffer.alloc(4); snap.writeUInt32LE(0xdcdcf5f5); assert.equal(snap.toString('hex'), 'f5f5dcdc'); assert.ok(!snap.toString('latin1').includes('SNAPSHOT')); }); test('Dart snapshot 基础头为 20 字节:magic(4) + length(8) + kind(8)', () => { const head = Buffer.alloc(20); head.writeUInt32LE(0xdcdcf5f5, 0); head.writeBigInt64LE(0x1000n, 4); // length head.writeBigInt64LE(2n, 12); // kind = full-aot assert.equal(head.readUInt32LE(0), 0xdcdcf5f5); assert.equal(Number(head.readBigInt64LE(4)), 0x1000); assert.equal(Number(head.readBigInt64LE(12)), 2); assert.equal(head.length, 20); // 头部之后才是(版本相关的)子 blob 布局——本 fixture 只锁定基础头,不对其后的内部布局作承诺 }); // 对应 re-format-macho/references/layout.md:Mach-O 的基础常量与端序规则 // 取值对照 LLVM BinaryFormat/MachO.h(Apple loader.h / machine.h 的忠实移植) test('Mach-O cputype / cpusubtype:arm64e 靠 subtype 区分,不靠 cputype', () => { const CPU_ARCH_ABI64 = 0x01000000; const CPU_TYPE_X86 = 7, CPU_TYPE_ARM = 12; assert.equal(CPU_TYPE_X86 | CPU_ARCH_ABI64, 0x01000007); // x86_64 assert.equal(CPU_TYPE_ARM | CPU_ARCH_ABI64, 0x0100000c); // arm64 // 两个都是 arm64 的二进制,只靠 cpusubtype 分开 const ARM64_ALL = 0, ARM64_V8 = 1, ARM64E = 2; assert.deepEqual([ARM64_ALL, ARM64_V8, ARM64E], [0, 1, 2]); // x86_64 侧:3 是 ALL、8 才是 H;0x80000000 只是 capability 位,不改变基础 subtype assert.equal(3, 3); // CPU_SUBTYPE_X86_64_ALL assert.equal(8, 8); // CPU_SUBTYPE_X86_64_H // 注意 JS/C 共同的坑:按位或按有符号 32 位解释,0x80000000|3 会是负数——要 >>>0 才得 uint32 assert.equal((0x80000000 | 3) >>> 0, 0x80000003); // LIB64 capability 位 assert.ok(0x80000000 | 3 < 0); // 未修正时的真实取值 assert.notEqual((0x80000000 | 3) >>> 0, 8); // 它变不出 x86_64h }); test('Mach-O header flags 是位值,不是连续编号', () => { const MH = { NOUNDEFS: 0x1, INCRLINK: 0x2, DYLDLINK: 0x4, BINDATLOAD: 0x8, SPLIT_SEGS: 0x20, LAZY_INIT: 0x40, TWOLEVEL: 0x80, PIE: 0x200000, HAS_TLV_DESCRIPTORS: 0x800000 }; assert.equal(MH.LAZY_INIT, 0x40); assert.equal(MH.TWOLEVEL, 0x80); // 若按"连续编号"手抄,会得到 2=DYLDLINK、4=TWOLEVEL、0x800000=LAZY_INIT —— 全部错位 assert.notEqual(MH.DYLDLINK, 0x2); assert.notEqual(MH.TWOLEVEL, 0x4); assert.notEqual(MH.HAS_TLV_DESCRIPTORS, MH.LAZY_INIT); // 独立位可直接按位与判定 assert.equal(0x200000 & MH.PIE, MH.PIE); }); test('Mach-O n_type:基础类型与属性位分层读,0x0f 不是 undefined', () => { const N_TYPE = 0x0e, N_EXT = 0x01, N_PEXT = 0x10; assert.equal(0x0f & N_TYPE, 0x0e); // N_SECT assert.equal(0x0f & N_EXT, 0x01); // 且是 external // 0x0f 应解读为 N_SECT|N_EXT,而不是 N_UNDF assert.notEqual(0x0f & N_TYPE, 0x00); assert.equal(0xf0 & N_TYPE, 0x00); // N_UNDF 只可能是低 4 位为 0 的组合 assert.equal(0x01 & N_TYPE, 0); }); test('fat Mach-O:结构恒为大端,align 是 2 的幂', () => { const header = Buffer.alloc(8); header.writeUInt32BE(0xcafebabe, 0); // FAT_MAGIC,按磁盘约定写大端 header.writeUInt32BE(2, 4); // nfat_arch assert.equal(header.subarray(0, 4).toString('hex'), 'cafebabe'); // 文件开头就是 CA FE BA BE assert.equal(header.readUInt32BE(0), 0xcafebabe); // FAT_MAGIC assert.equal(header.readUInt32LE(0), 0xbebafeca); // 小端读得 FAT_CIGAM——同一份字节,不是"小端文件" // fat_arch.align 是 2 的幂:align=14 → 偏移需 2^14 对齐,而不是固定 4 字节 const align = 14; assert.equal(2 ** align, 16384); assert.equal(16384 % 4, 0); // 2^align 必然满足 4 字节,反之不成立 assert.notEqual(2 ** align, 4); }); // 对应 re-ai-model/SKILL.md:Safetensors 前 8 字节 = 小端 u64 头长度 test('Safetensors:前 8 字节是小端 u64 的 JSON 头长度', () => { const header = Buffer.from(JSON.stringify({ __metadata__: { format: 'pt' } }), 'utf8'); const len = Buffer.alloc(8); len.writeBigUInt64LE(BigInt(header.length)); const file = Buffer.concat([len, header]); const readLen = Number(file.readBigUInt64LE(0)); assert.equal(readLen, header.length); assert.deepEqual(JSON.parse(file.subarray(8, 8 + readLen).toString('utf8')), { __metadata__: { format: 'pt' } }); // 大端读法会得到完全不同的值——这正是"必须按小端读"这条断言的意义 assert.notEqual(file.readBigUInt64BE(0), BigInt(header.length)); });